• Modern UX

    Edit and navigate faster in the terminal with Warp's IDE-like input editor.

  • Warp AI

    AI suggests what commands to run and learns from your documentation.

  • Agent Mode

    Delegate tasks to AI and use natural language on the command line.

  • Warp Drive

    Save and share interactive notebooks, workflows, and environment variables.

  • All Features

Learning Docker (The Easy Way) Using LazyDocker & Warp

Thumbnail for Jessica WangJessica Wang

Jessica Wang

Developer Advocate, Warp

Updated: 8/22/2024

About Terminus

Set up Docker

1. Download Docker.

‍ You can find instructions here for installing it for your device, depending on if you’re on Mac, Linux, or Windows. https://docs.docker.com/get-docker/

To check if you already have Docker installed, you can run this command:

 docker --version 
Run in Warp
2. Open up the Docker application on your device.

Set up LazyDocker and Warp

These steps are optional, but I personally think that downloading these two tools is the easiest way to learn Docker. Here is why:

  • LazyDocker is a terminal-based UI for Docker that provides an interface for managing Docker containers, images, volumes, and networks. It consumes far less CPU and memory compared to Docker Desktop’s GUI, and feels much simpler and less overwhelming. On top of that, it’s ideal for managing Docker on remote servers, where a graphical interface is usually unavailable.
Thumbnail for null
  • To download LazyDocker, run:
 brew install jesseduffield/lazydocker/lazydocker 
Run in Warp
  • Warp is a terminal application that looks and works great out-of-the-box, which just makes it a really pleasant tool to learn with. On top of that, it has an AI integration that makes it a lot quicker to set up things like Docker images and run containers (way better than doing it manually). I’ll be using Warp’s AI feature a lot throughout the tutorial.
Thumbnail for null
  • To install Warp, just run:
 brew install --cask warp 
Run in Warp

Basic Explanation of Docker Building Blocks

There are a few fundamental building blocks for understanding Docker.

  1. 1. Containers: standalone packages that include everything needed to run an application - code, runtime, libraries, and dependencies. Containers are isolated from each other to help ensure consistency across different environments.
  2. 2. Images: read-only templates used to create containers.
  3. 3. Dockerfile: A text file containing a set of instructions on how to build a Docker image. It typically includes commands to set up the environment, install dependencies, copy files, and the command to run the application.

Essentially, Dockerfiles are blueprints used to create Docker images, and Docker images are the blueprints used to create Docker containers. The reason why they do this is…

How the flow usually works is:

  1. 1. Build: You write a Dockerfile and use the docker build command to create an image.
  2. 2. Run: You use the docker run command to create and start a container from the image.
  3. 3. Manage: You can start, stop, and manage containers. For example, docker ps lists running containers, and docker stop stops a running container.

Set up a Dockerfile, Docker Image, Docker Container

Let’s apply these concepts. This is where LazyDocker and Warp will come in handy.

1. Open up your Warp terminal and press CMD-D to open up a split pane to the right. On the right pane, run the command:
 lazydocker 
Run in Warp

Which will open up the LazyDocker TUI in that pane. Your setup should look something like this:

Thumbnail for null
2. On the left, type in the following prompt into Warp:

‍ “Can you create a Dockerfile for me and explain what it does?”

The response you get may differ depending on what Warp’s AI (Agent Mode) feature outputs, but here is the Dockerfile it created for me:

# Use the official Ubuntu base image
FROM ubuntu:20.04

# Set the maintainer label
LABEL maintainer="your_email@example.com"

# Update the package repository and install some software packages
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip

# Set the working directory inside the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Make port 80 available to the world outside this container
EXPOSE 80

# Define the command to run the application
CMD ["python3", "app.py"]
Run in Warp

Here is the breakdown of the Dockerfile:

  • FROM ubuntu:20.04 This line specifies the base image to use for the Docker container, which in this case is Ubuntu 20.04.
  • LABEL maintainer="your_email@example.com" Sets a label to indicate the maintainer of the image.
  • RUN apt-get update && apt-get install -y python3 python3-pip Updates the package list and installs Python 3 and pip3 in the container.
  • WORKDIR /app Sets the working directory inside the container to /app.
  • COPY . /app Copies all the files from the current directory on the host machine into the /app directory in the container.
  • EXPOSE 80 Opens port 80 so this container can be accessible over HTTP.
  • CMD ["python3", "app.py"] Specifies the command to run the application, which in this case is "python3 app.py".
3. Next, I asked Warp’s Agent Mode:

‍**“Please build the Dockerfile you just created”**

I like typing my intent into Warp using natural language because I don’t have to worry about adding all the right flags/directory names correctly when running the base command. Even though I’ll eventually need to learn the meaning behind each parameter, I don’t want to get bogged down by this during my beginner learning stage. The command it generated for me was:

 docker build -t my-python-app 
Run in Warp

Once you create the image, you should see it show up in LazyDocker’s TUI:

Thumbnail for null
4. The next thing I will ask Warp’s Agent Mode is:

“Can you create a container from the Docker image you just created?”

And you can see in the screenshot below that it generates the command for me:

 docker run -d --name my-python-app-container my-python-app:v1 
Run in Warp
Thumbnail for null

Another thing I like about using Warp’s Agent Mode is that it can easily help me debug and fix errors without much context switching. When I tried to run this command at first, I ran into an error because my Docker image was trying to run the command python3 app.py but app.py did not exist:

Thumbnail for null

As you can see in the screenshot above, Warp generated this command:

# Create a simple placeholder app.py file
echo 'print("Hello, Docker!")' > app.py

# Rebuild the Docker image
docker build -t my-python-app:v1 

# Run the container with the new image
docker run -d --name my-python-app-container my-python-app:v1
Run in Warp

Which creates a simple app.py file in my directory that prints “Hello Docker!”, and then (my favorite part) regenerates the Docker image and Docker container without me having to prompt it to rebuild everything. After running these commands, you’ll see that my LazyDocker TUI now shows a running container:

Thumbnail for null
5. The last thing you can do with containers is manage them. LazyDocker makes this really easy. Press “x” to see the menu, and do things like “pause” or “remove” a container.
Thumbnail for null

Why Docker is great for containerization & microservices

Now that we understand the basic flow of how to use Docker, let’s dive into why the concept of Docker containers are important to developer productivity. To do this, we’re going to set up multiple services running in different containers, demonstrating how Docker can easily help you set up a simple microservices architecture with minimal hassle.

In fact, I’m going to let Warp walk you through this demo. I’m going to type the following prompt into Warp’s Agent Mode:

‍ Can you create 3 different containers each running different types of services to demonstrate how Docker can easily create a microservices architecture?

Thumbnail for null

First, it prompts you to run:

 docker network create microserves_demo 
Run in Warp

Which creates a new user-defined network in Docker named “microservices_demo” and allows multiple Docker containers to communicate with each other. Then, it asks to create three different Docker containers running different types of services:

Thumbnail for null

Here’s the specific command:

docker run -d --name web_service --network microservices_demo nginx && \
docker run -d --name db_service --network microservices_demo -e MYSQL_ROOT_PASSWORD=root mysql && \
docker run -d --name cache_service --ne
Run in Warp

In this case, I was able to create these containers without first creating a Dockerfile or Docker image because these commands use existing official Docker images from the Docker Hub, which is a cloud-based repository that holds Docker images. These images are pre-built and maintained by their respective communities.

Once I run this command, I can see that my three new services (cache_service, db_service, and web_service) are all running in their own Docker containers in LazyDocker.

Thumbnail for null

Here are two important takeaways from this demonstration.

  1. 1.

    All three of these Docker containers (cache_service, db_service, and web_service) run in isolated environments.

    For example, suppose that the web_service container creates a file at /app/logs/error.log. This file is only visible within that container and does not affect the db_service container.

    Another example is that the web_service container can run processes like nginx which is independent of the MySQL processes running in the db_service container. I can even run a command like ps aux inside the web_service container and see processes only related to that container (and not db_service).

  2. 2.

    These three services are able to communicate with each other over the microservices_demo network.

    For example, let’s say web_service needs to store user profile data in the database managed by db_service. Or maybe web_service wants to use cache_service to cache user session data or frequently accessed query results to avoid hitting the database repeatedly. Docker would automatically set up a DNS service within the network that maps the container names to their IP address.

This only scratches the surface of what Docker can do, but with Warp and LazyDocker, there’s a lot of exploration you can do with the tool on your own to learn more. Good luck!

Written by

Thumbnail for Jessica WangJessica Wang

Jessica Wang

Developer Advocate, Warp

Filed Under

Related Articles

Override the Container Entrypoint With docker run

Learn how to override and customize the entrypoint of a Docker container using the docker run command.

Docker

The Dockerfile ARG Instruction

Learn how to define and set build-time variables for Docker images using the ARG instruction and the --build-arg flag.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Start a Docker Container

Learn how to start a new Docker container from an image in both the foreground and the background using the docker-run command.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Stop All Docker Containers

How to gracefully shutdown running containers and forcefully kill unresponsive containers with signals in Docker using the docker-stop and docker-kill commands.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Use An .env File In Docker

Learn how to write and use .env files in Docker to populate the environment of containers on startup.

Docker

Run SSH In Docker

Learn how to launch and connect to a containerized SSH server in Docker using password-based authentication and SSH keys.

Docker
Thumbnail for Gabriel ManricksGabriel Manricks

Launch MySQL Using Docker Compose

Learn how to launch a MySQL container in Docker Compose.

DockerSQL

Execute in a Docker Container

Learn how to execute one or multiple commands in a Docker container using the docker exec command.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Expose Docker Container Ports

Learn how to publish and expose Docker container ports using the docker run command and Dockerfiles.

Docker

Restart Containers In Docker Compose

Learn how to restart and rebuild one or more containers in Docker Compose.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Output Logs in Docker Compose

Learn how to output, monitor, customize and filter the logs of the containers related to one or more services in Docker Compose

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Rename A Docker Image

Learn how to rename Docker images locally and remotely using the docker tag command.

Docker

Trusted by hundreds of thousands of professional developers

Download Warp to get started

Download for Mac
Request demo
Thumbnail for null