DEV Community

Cover image for Introduction to Docker, part I
Mohammad-Ali A'RÂBI for Docker

Posted on

Introduction to Docker, part I

This is the blueprint content for the Docker Workshop I plan to conduct on December 12th, 2024. I wrote this article here for later reference.

Agenda (aka ToC)

  1. Welcome and Setup (10 minutes)
  2. What is Docker? (10 minutes)
  3. Key Docker Concepts (15 minutes)
  4. Hands-On: Your First Docker Container (30 minutes)
  5. Quick Introduction to Dockerfile (15 minutes)
  6. Wrap-Up and Q&A (10 minutes)

Welcome and Setup

Welcome to the Docker Workshop!

My name is Mohammad-Ali A'râbi, a software engineer and Docker Captain. It means I am a Docker expert and have been recognized by Docker for my contributions to the community. I have regular meetings with Docker engineers and get early access to new features and updates.

Read more:

What is Docker?

Docker was introduced by Solomon Hykes in 2013. He did a 5-minute lightning talk at PyCon and introduced Docker as a tool to solve the problem of "it works on my machine." The world was never the same again.

He did another talk almost 10 years later at KubeCon 2024 in Paris, reflecting on 10 years of Docker.

And here is a photo of me with Solomon Hykes there:

Solomon Hykes and Mohammad-Ali A'râbi


It works on my machine!

— Every developer ever

Docker is a tool that allows you to run applications in containers. Containers are like lightweight virtual machines that run on your computer. They are isolated from each other and from the host system. This means you can run multiple containers on the same machine without them interfering with each other.

The dependencies of your application are packaged with the application itself. This makes it easy to run the application on different machines without worrying about the environment.

Let's ship your machine!
— Docker

Note: Docker is not the only containerization tool. There are others like Podman, LXC, and rkt. However, Docker is the most popular one.

Note. Docker, Inc. created Docker runtime and Docker CLI. The Docker runtime, which is now called containerd, was donated to the CNCF in 2017. The Docker CLI is still maintained by Docker, Inc.

Docker uses a Linux kernel feature called namespaces to isolate processes. So, Docker runs on Linux natively. Other solutions like Docker Desktop for Mac and Windows use a Linux VM to run Docker.

Key Docker Concepts

Let's try to review some of the Docker concepts:

  • Image: A read-only template with instructions for creating a Docker container. It contains the application code, runtime, libraries, environment variables, and configuration files.
  • Container: An instance of an image that runs as a process on the host machine. It is isolated from other containers and has its own filesystem, network, and process space.
  • Dockerfile: A text file that contains a set of instructions for building a Docker image. It is used to automate the process of creating an image.
  • Docker Hub: A cloud-based registry service that allows you to share Docker images publicly or privately. It is like GitHub for Docker images.

Hands-On: Your First Docker Container

Let's start with the example that Solomon Hykes used in his talk:

docker run -it busybox echo hello
Enter fullscreen mode Exit fullscreen mode

This command runs a container from the busybox image and runs the echo hello command inside it. The -it flag attaches the terminal to the container so you can see the output.

By running this command, the image for busybox is downloaded from Docker Hub, a container is created from it, the echo hello command is run inside the container, and the container exits.

After the image is pulled, you should be able to see it in the list of images:

docker images
Enter fullscreen mode Exit fullscreen mode

There is also a list of containers that have been run:

docker ps -a
Enter fullscreen mode Exit fullscreen mode

If you omit the -a flag, you will only see the running containers.

docker ps
Enter fullscreen mode Exit fullscreen mode

The hello container is not visible, because it exited after running the command. Now let's create a container that runs indefinitely:

docker run -d busybox sh -c 'while true; do echo hello; sleep 10; done'
Enter fullscreen mode Exit fullscreen mode

To see the output, you can use the docker logs command, but to get the container ID, you need to use the docker ps command:

docker ps
Enter fullscreen mode Exit fullscreen mode

Then you can use the container ID to get the logs:

docker logs <container_id>
Enter fullscreen mode Exit fullscreen mode

If you want to see the logs in real time, you can use the -f flag:

docker logs -f <container_id>
Enter fullscreen mode Exit fullscreen mode

To stop the container, you can use the docker stop command:

docker stop <container_id>
Enter fullscreen mode Exit fullscreen mode

Let's run the same container again, but this time we'll give it a name:

docker run -d --name hello busybox sh -c 'while true; do echo hello; sleep 10; done'
Enter fullscreen mode Exit fullscreen mode

Now if you do a docker ps, you should see the container with the name hello. And we can use this name for checking the logs or attaching to the container:

docker exec -it hello bash
Enter fullscreen mode Exit fullscreen mode

It will error out because the bash command is not available in the busybox image. You can use sh instead:

docker exec -it hello sh
Enter fullscreen mode Exit fullscreen mode

Note. You can use docker debug to attach a debugger container to the running container. This way you can use the tools that are not on the running container. Docker Debug is a paid feature of Docker Desktop.

Now that you are inside the container, you can run commands like ls, pwd, and ps. You can also exit the container by typing exit.

Note. If you change the state of the container, like installing new software or creating new files, these changes are not saved. When you exit the container, the changes are lost. To save the changes, you need to create a new image.

Quick Introduction to Dockerfile

A Dockerfile is a text file that contains a set of instructions for building a Docker image. It is used to automate the process of creating an image. Here is an example of a Dockerfile:

FROM busybox

RUN echo "hello world" > /hello.txt

CMD cat /hello.txt
Enter fullscreen mode Exit fullscreen mode

This Dockerfile does the following:

  1. It starts with the busybox image.
  2. It runs the echo "hello world" > /hello.txt command to create a file called hello.txt with the content hello world.
  3. It sets the default command to cat /hello.txt.

To build an image from this Dockerfile, you can use the docker build command:

docker build -t hello .
Enter fullscreen mode Exit fullscreen mode

The -t flag tags the image with the name hello. The . at the end of the command specifies the build context, which is the current directory.

Note. Here, the image name is hello, which is not the same thing as the container name. The container name is used to identify a running container, while the image name is used to identify an image.

After the image is built, you can run a container from it:

docker run hello
Enter fullscreen mode Exit fullscreen mode

As expected, the container runs the cat /hello.txt command and prints hello world, and exits. Let's change the command to see if the changes are saved:

docker run hello ls /
Enter fullscreen mode Exit fullscreen mode

You should see the hello.txt file in the root directory. This means the changes are saved in the image.

Real-World Example

Let's take a real-world example of a Dockerfile. Here is a Dockerfile for a simple web server:

This

FROM nginx:alpine

COPY index.html /usr/share/nginx/html/index.html
Enter fullscreen mode Exit fullscreen mode

This Dockerfile does the following:

  1. It starts with the nginx:alpine image.
  2. It copies the index.html file from the build context to the /usr/share/nginx/html/ directory in the image.

To build an image from this Dockerfile, you can use the docker build command:

echo "<h1>Hello, World!</h1>" > index.html
docker build -t hello-server .
Enter fullscreen mode Exit fullscreen mode

The -t flag tags the image with the name hello-server. The . at the end of the command specifies the build context, which is the current directory. The index.html file should be in the same directory as the Dockerfile.

After the image is built, you can run a container from it:

docker run -d -p 8080:80 hello-server
Enter fullscreen mode Exit fullscreen mode

If you open a browser and go to http://localhost:8080, you should see the message Hello, World!.

Exercises

  1. Create a Dockerfile that installs curl and runs curl google.com.
  2. Create a Dockerfile that starts a web server on port 8080 and serves a static HTML file with the message Hello, Docker!.
  3. Write a simple web server in Python that get's a name from the query string and returns Hello, <name>!. Create a Dockerfile that runs this web server on port 8080. For this exercise, you can use the python:latest image.
  4. After creating the Python web server, check the image for vulnerabilities using the docker scout cves <image> command. How many vulnerabilities are there? How can you fix them?
  5. Write a Python script that reads a file called data.txt and prints its content. Create a Dockerfile that copies the data.txt file to the image and runs the Python script. For this exercise, you can use the python:latest image.
  6. Change the data.txt file from the previous exercise and rebuild the image. Does the Python script print the new content?
  7. Change the data.txt file from the previous exercise and run the image again without rebuilding it. Does the Python script print the new content?
  8. Run the Docker image from the previous exercise with a volume mounted to the /data directory. Change the data.txt file on the host machine and see if the Python script prints the new content.

Last Words

I hope you enjoyed the article. If you have any questions or feedback, feel free to reach out to me on:

To learn more about Docker, take a look at articles published on Docker's blog:

Thank you for reading! 🚀

Top comments (0)