Docker Mastery

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.

  1. Docker
  2. 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.
  3. 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 container
  • docker 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 networks
  • docker network inspect <Network>: inspects a network
  • docker 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 services
  • docker-compose down shuts down the services
  • docker-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.