Container - a way to package application will all the necessary dependencies and configuration
portable standardized artifact for efficient development and deployment
Devs & Ops work together to package the app in a container
No environment config needed on server (only Container Runtime)
layers of images
Linux base image
other layers
Application image
Container repositories
private
Docker - open source containerization platform
package applications into containers
there are other alternatives (but it made containers popular)
Docker image - the actual package file, artifact, consisting of layers
Docker container - started application, a running environment, virtual file system, port binding
Virtual machines - virtualize the OS Kernel and the Application layer - full copy of the OS, abstraction of physical hardware
Containers - multiple containers share the OS Kernel - abstraction of the app layer
Docker Engine acts as a client-server application with:
Server - dockerd, managing images & containers
Container Runtime
Volumes
Network
build images
API - interact with Docker Server
CLI - docker client
Libnetwork implements Container Network Model (CNM) which formalizes the steps required to provide networking for containers while providing an abstraction that can be used to support multiple network drivers.
docker network ls
NETWORK ID NAME DRIVER SCOPE
964fd24a27a1 bridge bridge local
446ad1bfc60e host host local
d1be7e105231 none null local
Docker Compose - define and run multiple docker containers applications
yaml file to configure application's services
easy maintenance and config
Dockerfile - text file with instructions to build Docker images
each instruction results in an image layer
used in CI/CD to build the docker image artifact, pushed to Docker (remote or local) repositories
each image is based on another base image (FROM <image>)
Dockerfile
FROM <image>
# Comment
INSTRUCTION arguments
# e.g.
ENV SOME_ENV=value
# run commands inside the container
RUN mkdir -p /home/app
RUN ...
# copy files from host to container
COPY . /home/app
# entrypoint command
CMD ["command","arguments"]
Public repositories
Public repositories (container registries)
Image naming in Docker - registryDomain/imageName:tag
# e.g. DockerHub
docker pull docker.io/library/ubuntu # default
# same as
docker pull ubuntu
# e.g. Push image to private my-repo
# Login to private my-repo
docker tag <my-repo/my-app:version>
docker push <my-repo/my-app:version>
Volumes - persist container generated and used data, by mounting a folder from the physical host file system into the Docker virtual file system
databases
stateful applications
data automatically replicated
Host, Anonymous, Named volumes
Host Path - /var/lib/docker/volumes
# Install Docker Engine via APT repository
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt update -y && sudo apt install -y ca-certificates curl gnupg
sudo sh -c '
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
sudo chmod a+r /usr/share/keyrings/docker.gpg
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
'
sudo systemctl enable docker --now
sudo gpasswd -a "${USER}" docker
# On Debian and Ubuntu, the Docker service starts on boot by default, if not run
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
# Reboot and Test
reboot
docker run hello-world
Commands
docker pull <image>
# e.g.
docker pull postgres
docker pull ubuntu
docker pull alpine
docker pull redis
# without tag, the latest version is downloaded
docker run <image>
# detached mode
docker run -d <image>
# use containers
docker start <container_id>
docker stop <container_id>
docker images
docker ps
# list running and exited containers
docker ps -a
# e.g. with image:tag
docker run redis:4.0
# Map a free port on HOST machine
docker run -p6000:6379 -d redis
docker run -p6001:6379 -d redis:4.0
# fetch logs
docker logs <container_id>
docker logs <container_id> -f
docker logs <container_name>
# name a container
docker run -p6000:6379 -d --name redis-latest redis
# new bash session in the container
docker exec -it <container_id> /bin/bash
docker exec -it <container_id> /bin/sh
docker network ls
# e.g.
docker network create test-network
docker compose -f docker-compose.yaml up
docker compose -f docker-compose.yaml down