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?
- Linux: https://docs.docker.com/engine/install/ubuntu/
- Windows: https://docs.docker.com/desktop/setup/install/windows-install/
- Mac: https://docs.docker.com/desktop/setup/install/mac-install/
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 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
- 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 .
- 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
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.
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
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"]
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"]
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
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
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.
Docker Container: Union file system:
- Images are read only (R/O).
- When containers are created, new read-write (R/W) thin layer is created.
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
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
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
- 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
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
Docker Network: MacVlan
- Each Container has its own MAC interface ( — net macvlan)
Docker Network: Overlay
- Containers that work on different PCs/hosts can work as the same network ( — net overlay)
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
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
- 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
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
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
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
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)