DEV Community

Ömer Berat Sezer
Ömer Berat Sezer

Posted on

Docker Tutorial: Dockerfile, commands, container, images, volume, network, Docker Compose

In the previous post, we focused on the usage area and importance of Docker container in IT sector.

This post, we are diving to details. Let’s start.

How to Install Docker?

Docker Engine

There are mainly 3 components in the Docker Engine:

  • Server is the docker daemon named docker daemon. Creates and manages docker images, containers, networks, etc.
  • Rest API instructs docker daemon what to do.
  • Command Line Interface (CLI) is the client used to enter docker commands.

Docker Engine

Docker Commands

  • docker [ManagementCommand] [Command]
user@docker:~$ docker --help
Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Authenticate to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information

Management Commands:
  builder     Manage builds
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  plugin      Manage plugins
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes
Enter fullscreen mode Exit fullscreen mode
  • Management Command + Command + Parameter (optional):
user@docker:~$ docker container ls -a
user@docker:~$ docker image ls
user@docker:~$ docker volume ls
user@docker:~$ docker network ls
#docker container rm -f [containerName or containerID]
user@docker:~$ docker build -t ImageName .
Enter fullscreen mode Exit fullscreen mode
  • You can also get many helps after management command:
user@docker:~$ docker container --help
user@docker:~$ docker image --help
user@docker:~$ docker volume --help
user@docker:~$ docker network --help
Enter fullscreen mode Exit fullscreen mode

Dockerfile

Dockerfile is a text file with instructions to build a Docker image. It contains commands like FROM, RUN, COPY, and CMD to define the image’s environment, and dependencies.

Dockerfile Instructions

Sample Dockerfile (python base image):

FROM python:3.13.1-alpine3.21
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
CMD python ./index.py
Enter fullscreen mode Exit fullscreen mode

Sample Dockerfile (ubuntu base image):

FROM ubuntu:24.04
RUN apt-get update -y
RUN apt-get install default-jre -y
WORKDIR /myapp
COPY /myapp .
CMD ["java","hello"]
Enter fullscreen mode Exit fullscreen mode

Multi-stage Dockerfile (Creating temporary container:

  • In the example, JDK (Java Development Kit) based temporary image (~440MB) container is created for compilation.
  • Compiled files are copied into JRE (Java Runtime Environment) based image (~145MB). Finally, we have only JRE based image.
FROM mcr.microsoft.com/java/jdk:8-zulu-alpine AS compiler
COPY /myapp /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac hello.java

FROM mcr.microsoft.com/java/jre:8-zulu-alpine 
WORKDIR /myapp
COPY --from=compiler /usr/src/myapp .
CMD ["java", "hello"]
Enter fullscreen mode Exit fullscreen mode

Docker Image

  • Create Image using Dockerfile with build command.
user@docker:~$ docker image build -t hello . # (run this command where “Dockerfile” is)
user@docker:~$ docker image pull nginx:latest
user@docker:~$ docker image push alpine:latest
#docker image tag [imageOldName] [imageNewName]
# (PS: If you want to push DockerHub, [imageNewName]=[username]/[imageName]:[version])
user@docker:~$ docker save -o hello.tar test/hello
user@docker:~$ docker load -i <path to docker image tar file>
user@docker:~$ docker load -i .\hello.tar
Enter fullscreen mode Exit fullscreen mode

registry url, repo, tag

Docker Container

  • After creating, or pulling image from registry, we are creating docker container with “docker run”, or “docker container run”
user@docker:~$ docker container run --name mywebserver -d -p 80:80 nginx
user@docker:~$ docker container ls -a
user@docker:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
7481c4dca80e   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 3 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   mywebserver

user@docker:~$ docker exec -it mywebserver bash
root@7481c4dca80e:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@7481c4dca80e:/# exit
exit
Enter fullscreen mode Exit fullscreen mode
  • When we create the container from the image, in every container, there is an application that is set to run by default app. When this app runs, the container runs. When this default app finishes/stops, the container stops.

  • There could be more than one app in docker image (such as: sh, ls, basic commands)

  • When the Docker container is started, it is allowed that a single application is configured to run automatically.

dockerfile, container, image

Docker Container: Union file system:

  • Images are read only (R/O).
  • When containers are created, new read-write (R/W) thin layer is created.

union file system

Docker Volume

Why volumes are needed?

  • Containers do not save the changes/logs when erased if there is not any binding to volume/mount.
  • For persistence, volumes/mounts MUST be used. e.g. Creating a log file in the container. When the container is deleted, the log file also deleted with the container. So volumes/binding mounts MUST be used to provide persistence!
  • Docker volume is docker objects, with “-v” parameter, it can be connected to the container “VolumeName:ContainerFilePath”. When the files in the container path are stored, it is also synchronized with volume object.
user@docker:~$ docker volume create my_volume  # Creates a named volume called my_volume
user@docker:~$ docker volume ls   # Lists all the Docker volumes.
user@docker:~$ docker volume inspect my_volume  # Displays detailed information about the my_volume
user@docker:~$ docker volume rm my_volume  # Deletes the my_volume
user@docker:~$ docker volume prune # docker volume prune
# docker container run --name [containerName] -v [volumeName]:[pathInContainer] [imageName]
user@docker:~$ docker run -d -v my_volume:/app/data --name my_container nginx
Enter fullscreen mode Exit fullscreen mode

Docker Bind Mount:

  • Binding mount provide to connect host and container
# docker container run --name [containerName] -v [pathInHost]:[pathInContainer] [imageName]
user@docker:~$ docker container run --name c1 -v C:\test:/app alpine
Enter fullscreen mode Exit fullscreen mode

volume vs bind mount

Docker Network

  • Docker containers work like VMs.
  • Every Docker container has network connections
  • Docker Network Drivers: None, Bridge, Host, Macvlan, Overlay

Docker Network: Bridge:

  • Default Network Driver: Bridge ( — net bridge)
user@docker:~$ docker network create [networkName]
user@docker:~$ docker network create bridge1
#docker container run --name [containerName] --net [networkName] [imageName] 
user@docker:~$ docker container run --name c1 --net bridge1 alpine sh
user@docker:~$ docker network inspect bridge1
user@docker:~$ docker container run --name c2 --net bridge1 alpine sh
user@docker:~$ docker network connect bridge1 c2
user@docker:~$ docker network inspect bridge1
user@docker:~$ docker network disconnect bridge1 c2
Enter fullscreen mode Exit fullscreen mode
  • Creating a new network using customized network parameters:
user@docker:~$ docker network create --driver=bridge --subnet=10.10.0.0/16 --ip-range=10.10.10.0/24 --gateway=10.10.10.10 newbridge
Enter fullscreen mode Exit fullscreen mode

bridge network

Docker Network: Host

  • Containers directly reach host network interfaces ( — net host)
# docker container run --name [containerName] --net [networkName] [imageName] 
user@docker:~$ docker container run --name c1 --net host alpine sh
Enter fullscreen mode Exit fullscreen mode

host network

Docker Network: MacVlan

  • Each Container has its own MAC interface ( — net macvlan)

macvlan network

Docker Network: Overlay

  • Containers that work on different PCs/hosts can work as the same network ( — net overlay)

overlay network

Port Mapping/Publish:

  • Mapping Host PC’s port to container port:
## -p [hostPort]:[containerPort], --publish [hostPort]:[containerPort] e.g. -p 8080:80, -p 80:80
user@docker:~$  docker container run --name mywebserver -d -p 80:80 nginx
Enter fullscreen mode Exit fullscreen mode

Docker Compose File

  • Define and run multi-container applications with Docker.
  • Easy to create Docker components using one file: Docker-Compose file
  • It is a YAML file that defines components: Services, Volumes, Networks, Secrets

Sample “docker-compose.yml” file:

version: "3.8"
services:
  mydatabase:
    image: mysql:5.7
    restart: always
    volumes: 
      - mydata:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    networks:
      - mynet
  mywordpress:
    image: wordpress:latest
    depends_on: 
      - mydatabase
    restart: always
    ports:
      - "80:80"
      - "443:443"
    environment: 
      WORDPRESS_DB_HOST: mydatabase:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    networks:
      - mynet
volumes:
  mydata: {}
networks:
  mynet:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode
  • After saving the file as “docker-compose.yml”, run the following commands where the docker-compose file is, to create containers, volumes, networks:
user@docker:~$ docker-compose up -d    # run in detach mode with -d => background process
user@docker:~$ docker-compose down
Enter fullscreen mode Exit fullscreen mode

Docker Environment Variable (EV)

  • If you defined EV in dockerfile, it also possible to give input parameter while running command.
user@docker:~$ docker container run -it --env VAR1=test1 --env VAR2=test2 ubuntu bash
Enter fullscreen mode Exit fullscreen mode

Docker Stats/ Memory Limitations

  • You can see the running container stats using stat command.
user@docker:~$ docker container run --name mywebserver -d -p 80:80 nginx
user@docker:~$ docker stats
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O     PIDS
7481c4dca80e   mywebserver   0.00%     4.539MiB / 7.755GiB   0.06%     1.57kB / 0B   0B / 24.6kB   5
user@docker:~$ docker container rm -f mywebserver
user@docker:~$ docker container run --name mywebserver -d -p 80:80 --memory=100m nginx
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O     PIDS
c02a63d399e7   mywebserver   0.00%     4.473MiB / 100MiB   4.47%     1.05kB / 0B   0B / 20.5kB   5
Enter fullscreen mode Exit fullscreen mode

Docker Log

  • Docker Logs show /dev/stdout, /dev/stderror: docker logs --details [containerName]
user@docker:~$ docker logs mywebserver
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/01/12 12:18:50 [notice] 1#1: using the "epoll" event method
2025/01/12 12:18:50 [notice] 1#1: nginx/1.27.3
2025/01/12 12:18:50 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/01/12 12:18:50 [notice] 1#1: OS: Linux 6.8.0-48-generic
2025/01/12 12:18:50 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2025/01/12 12:18:50 [notice] 1#1: start worker processes
2025/01/12 12:18:50 [notice] 1#1: start worker process 29
2025/01/12 12:18:50 [notice] 1#1: start worker process 30
2025/01/12 12:18:50 [notice] 1#1: start worker process 31
2025/01/12 12:18:50 [notice] 1#1: start worker process 32
Enter fullscreen mode Exit fullscreen mode

Docker Commands Cheatsheet

Conclusion

This post focuses on the docker details (commands, dockerfile, volume, network, compose file, etc.). In the next post, we’ll make some hands-on-labs.

Follow for Tips, Tutorials, Hands-On Labs for AWS, Kubernetes, Docker, Linux, DevOps, Ansible, Machine Learning, Generative AI, SAAS.

Top comments (0)