My notes from the Udemy course: Docker Mastery.
Getting Docker
Go to the official documentation and add their APT repos to Ubuntu - this way you can get the latest stable releases.
- Docker
- Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
- Docker Machine is a tool that lets you install Docker Engine on virtual hosts, and manage the hosts with docker-machine commands.
Commands
docker version
: get the current Docker version.docker info
: displays the Docker information and its configurations.docker container run <Container>
: runs a container.--detach
or-d
: runs a container in the background.--name mycontainer
: gives the container an alias.--env
or-e MY_PASS=123456
: passes environment variables.--publish
or-p 8080:80
: exposes port to the outside world (format: HostPort:ContainerPort).--network <Network>
: bind it to a different network.
docker container ls
: lists all running containers.docker container ls -a
: lists all available containers.docker container stop <ContainerID>
: stops a containerdocker container logs <Container>
: shows logs for a specific container.docker container rm <ContainerID>
: removes a container. Use-f
to force removing a running container.
Images & containers
- An image is the app we want to run, and a container is an instance of that image running as a process.
- Registries are where you get publicly available images.
CLI Process Monitoring
docker container top <Container>
: shows processes being run on a container.docker container inspect <Container>
: shows metadata about the container (startup config, volumes, networking, etc).--format
can get specific configuration
docker container stats <Container [Optional]>
: shows container stats (memory, CPU, network IO, etc).
Docker commands
Containers will only run until the start command finishes.
docker container run -it <Command>
: start a new container iteratively.-it
pseudo TTY + iterative) and run a command.--rm
will remove the container after you exit the session.
docker container start -ai <Container>
: start an existing container iteratively.docker container exec <Command>
: run command on existing container.
Docker networks
Each container is connected to a private virtual network bridge, and they can talk to each other. You can create new virtual networks and attach containers to more than one virtual network (or none).
The bridge network is Docker’s default network.
docker network ls
: shows networksdocker network inspect <Network>
: inspects a networkdocker network create <Name>
: creates a new network.--driver <Driver>
: a different network driver can be used for different network types.
docker network connect <Network> <Container>
: connects a container to a network.docker network disconnect <Network> <Container>
: disconnects a container from a network.
DNS
Containers should not rely on IPs to communicate between each other, and because of that DNS is used in inter-container communication.
Container images
They are basically binnaries, dependencies and metadata about the image data and how to run it. It is not a complete OS - no kernel, or kernel modules, are included.
Docker Hub
Docker Hub (https://hub.docker.com) hosts public images. Official images will not have a account name, only the image name (e.g.: nginx), and they are maintaned by Docker Inc.
Versions: the most current is always latest.
Image layers
Every image change creates a new image layer, each one with its own SHA hash. It helps Docker to work more efficiently because a image layer cache exists.
My Image
- L3: nginx
- L2: APT
- L1: Ubuntu (base image
docker image inspect nginx
will return image metadata.
docker history nginx
will return the image layers.
Dockerfile
Dockerfile is unique to Docker. Remember that each command is a layer.
Structure of the Dockerfile
Always keep on top of the Dockerfile the things that change the least, and at the bottom the things that change more. This way you can always take advantage of Docker’s cache.
FROM sets the base image:
FROM debian:jessie
ENV sets environment variables:
ENV NGINX_VERSION 1.11.10-1-jessie
RUN executes shell commands inside the container:
RUN apt-get update && apt-get install nginx=${NGINX_VERSION}
Combining commands helps to save space.
Docker will handle error logging from /dev/stdout and /dev/stderr.
EXPOSE exposes the ports on the Docker internal network:
EXPOSE 80 443
CMD is a required parameter that will be run every time the container is started/restarted.
CMD ["nginx", "-g", "daemon off;"]
Running a Dockerfile
To run a Dockerfile in the directory:
docker image build -t <tag> .
Container lifetime & persistent data
Containers are usually immutable and ephemeral, the so-called “immutable infrastructure”.
There are two ways to persist data on Docker: Volumes and Bind Mounts.
Volumes
Example: on MySQL official Dockerfile, we find:
VOLUME /var/lib/mysql
This creates a volume when the image is created, and it can only be removed manually.
docker volume ls
lists the existing volumes.docker volume inspect <Hash>
inspects a volume.docker container run ... -v mysql-db:/var/lib/mysql
will create a named volume when the container is run.docker volume create
lets you create a volume without a container. You can select different drivers in this command.
Bind Mounts
Bind Mounting maps a host file or directory to a container file or directory. They cannot be used in Dockerfile, only at container run
. E.g.:
docker container run -d --name nginx -p 80:80 -v $(pwd):/usr/share/nginx/html nginx
Binds the current directory in the host (pwd
) to /usr/share/nginx/html on the container.
Docker Compose
Docker Compose helps us connecting containers together.
The YAML file
docker-compose.yml
can be used with docker-compose (on dev/test environments) and with docker
Swarm.
You always need to start with a version
property.
version: 3.1
services: # Containers
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./project:/var/www:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:
links:
- php
environment:
- URL=http://localhost
depends_on: php
php:
image: php:7.3-fpm
volumes:
- ./project:/var/www
volumes: # Optional
networks: # Optional
<volume>:ro
makes a volume read-only inside the container.
docker-compose CLI
docker-compose up
starts up the servicesdocker-compose down
shuts down the servicesdocker-compose top
will list the processes running inside the containers
Container Registries
- An image registry needs to be part of your container plan.
- Docker Hub is the most popular public image registry.
Tag/Push/Pull images
docker tag <image-name> my.private-registry.com/<image-name>
docker push my.private-registry.com/<image-name>
docker pull my.private-registry.com/<image-name>
Tips
What is the difference between ENTRYPOINT and CMD?
ENTRYPOINT
will/may run a custom script (or a command) you can call before the container is run via CMD.
Common ending for docker_entrypoint.sh
:
exec "$@"
-> $@
refers to all of a shell script’s command-line arguments.
Change the USER in Docker files
Do not run your app inside the container as root, unless strictly necessary. It will narrow the attack surface.
Create a user: RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
Change the user: USER postgres
You may need to chown
some directories or files to make it work.