Learning Docker (The Easy Way) Using LazyDocker & Warp
Jessica Wang
Developer Advocate, Warp
Updated: 8/22/2024
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.
- 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.
- 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. 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. Images: read-only templates used to create containers.
- 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. Build: You write a Dockerfile and use the docker build command to create an image.
- 2. Run: You use the docker run command to create and start a container from the image.
- 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:
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:
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
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:
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:
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.
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?
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:
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.
Here are two important takeaways from this demonstration.
- 1.
All three of these Docker containers (
cache_service
,db_service
, andweb_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 thedb_service
container.Another example is that the
web_service
container can run processes like nginx which is independent of the MySQL processes running in thedb_service
container. I can even run a command likeps aux
inside theweb_service
container and see processes only related to that container (and notdb_service
). - 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 bydb_service
. Or maybeweb_service
wants to usecache_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
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.
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.
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.
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.
Use An .env File In Docker
Learn how to write and use .env files in Docker to populate the environment of containers on startup.
Run SSH In Docker
Learn how to launch and connect to a containerized SSH server in Docker using password-based authentication and SSH keys.
Launch MySQL Using Docker Compose
Learn how to launch a MySQL container in Docker Compose.
Execute in a Docker Container
Learn how to execute one or multiple commands in a Docker container using the docker exec command.
Expose Docker Container Ports
Learn how to publish and expose Docker container ports using the docker run command and Dockerfiles.
Restart Containers In Docker Compose
Learn how to restart and rebuild one or more containers in Docker Compose.
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
Rename A Docker Image
Learn how to rename Docker images locally and remotely using the docker tag command.