Post

Docker

Docker

Containers

Basics

  1. Run container (e.g. nginx)
    • docker run nginx
  2. Run container with specific version (tag)
    • docker run redis:4.0
    • docker run <container_name>:<tag>
  3. List containers
    • Running
      • docker ps
    • All
      • docker ps -a
  4. Stop container
    • docker stop <container_id/name>
  5. Remove container
    • docker rm <container_id/name>
  6. Map Ports
    • Map Docker Host port to Docker Container port
      • docker run -p <host_port>:<container_port> <container_id/name>
    • E.g. Map port 80 of Docker Host to port 5000 of Docker Container
      • docker run -p 80:5000 my_container
  7. Map Volumes
    • Map Docker Host Volume to Docker Container Volume
      • docker run -v /opt/datadir:/var/lib/mysql mysql
      • docker run -v <host_path>:<container_path> <container_id/name>
  8. Get more detailed info of container
    • docker inspect <container_id/name>
  9. Show Container logs
    • docker logs <container_id/name>
  10. Set Environmental Variables
    • docker run --env JAVA_VERSION=11 my_container
    • docker run --env <variable>=<value> <container_id/name>
    • --env ~ -e
  11. Display Environmental Variables
    • Use docker inspect command

Images

  1. Build docker image
    • docker build .
    • docker build <path_of_Dockerfile>
  2. Tag docker image you are building
    • docker build . -t <repository>/<image_name>
  3. Don’t use cache
    • --no-cache
  4. Show full log output (don’t trim build log)
    • --progress=plain
  5. Tag docker image you have built
    • docker tag <image> <repository>/<image_name>:<tag>
  6. Download image
    • docker pull <image_name>
  7. Show downloaded images
    • docker images
  8. Download image into computer
    • docker image save <image> > image.tar
  9. Show image history (some commands and sizes)
    • docker history <image>
  10. Remove image
    • docker rmi <image_name>

Commands

  1. Run container with command
    • docker run ubuntu sleep 5
    • docker run ubuntu <command>
  2. Run command on a running container
    • docker exec cat /etc/hosts
    • docker exec -it mydb mysql --user=root --password=$MYSQL_ROOT_PASSWORD --version
    • docker exec <container_id/name> <command>
  3. Run container in detached mode
    • docker run -d <container_id/name>
    • --detach ~ -d
  4. Attach to running container
    • docker attach <container_id/name>
  5. Enable interactive mode to make container receive input
    • docker run --interactive <container_id/name>
    • --interactive ~ -i
  6. Attach to terminal (to see its output)
    • docker run --tty <container_id/name>
    • --tty ~ -t
  7. Run container in combined mode to have both terminal input and output
    • docker run -it <container_id/name>
  8. Add name to container
    • docker run --name <name> <image>
  9. Publish image on DockerHub
    • docker push komidawi/my-image
  10. Remove container (and its anonymous volumes) after exit
    • --rm
  11. See container logs
    • docker logs <container_id/name>
  12. See container processes
    • docker top <container_id/name>

COMMANDs and ENTRYPOINTs

  1. Specifying Commands in Dockerfile
    • Shell form
      • CMD <command> <param>
    • JSON Array form
      • CMD ["<command>", "param"]
  2. CMD vs ENTRYPOINT
    • CMD allows to override Dockerfile command and arguments
      • docker run my_container <command> <arguments>
    • ENTRYPOINT only appends arguments into Dockerfile
      • docker run my_container <arguments>
  3. Set default arguments
    • It must be JSON Array form
    • You provide both ENTRYPOINT and CMD
      • 1
        2
        
        ENTRYPOINT ["sleep"]
        CMD ["5"]
        
  4. Override ENTRYPOINT
    • docker run --entrypoint sleep2 ubuntu-sleeper 10
    • docker run --entrypoint <command> <image> <args>

Networking

  1. What is EXPOSE
    • EXPOSE documents which ports application uses

Network: Bridge

  • Default network
  • Network within Docker Host, allows communication between all containers
  • You need to map Ports to access containers
  • By default, one Bridge Network is created
    • If you need more, you have to specify this explicitly

Network: Host

  • Ports are shared with the “real” network
  • You don’t have Network isolation in this case (so beware of port collision with “real” network)
  • Also, you can’t run multiple containers on the same container ports, as they are now published
  • --network=host

Network: None

  • No network - totally isolated
  • --network=none

Commands

  1. Create new Network
    • docker network create --driver bridge --subnet 182.18.0.0/16 my_network
    • docker network create --driver <driver> --subnet <a.b.c.d/n> <network_name>
  2. Embedded DNS
    • All Docker containers are accessible by their names
    • This DNS runs at 127.0.0.11
  3. Show Network info of container
    • Use docker inspect

Volumes

  1. Create volume
    • docker volume create <volume_name>
    • creates /var/lib/docker/volumes/volume_name
  2. Assign volume on run (mount volume)
    • docker run -v data_volume:/var/lib/mysql mysql
    • docker run --volume <volume_name>:<container_path> <image>
  3. Bind Mount
    • File or directory on the host machine is mounted directly into a container
    • Bind mount means that any changes to the local file system are immediately reflected in running container
  4. Assign local volume (bind mount)
    • docker run -v /data/mysql:/var/lib/mysql mysql
  5. Bind mount volume on run
    • docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql

docker compose

docker-compose.yml

Reference file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
services:
    my-app:
        image: my-app:2.1.1-SNAPSHOT
        environment:
            - SPRING_PROFILES_ACTIVE=docker-mysql
        ports:
            - '8080:8080'
            - '5555:5555'
        networks:
            - backend-network
        depends_on:
            db:
                condition: service_healthy
        healthcheck:
            test: curl --fail --silent localhost:5555/actuator/health | grep UP || exit 1
            interval: 3s
            retries: 5
            start_period: 30s
    db:
        image: mysql:5.7.44
        command: [
            # For some reason UTF-8 is not default encoding..
            "--character-set-server=utf8",
            "--collation-server=utf8_unicode_ci",
            "--init-connect='SET NAMES UTF8;'",
            "--innodb-flush-log-at-trx-commit=0" ]
        environment:
            - MYSQL_DATABASE=sds_docker
            - MYSQL_ROOT_PASSWORD=password
        ports:
            - '3336:3306'
        volumes:
            - app-database
        networks:
            - backend-network
        healthcheck:
            test: [ "CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent" ]
            interval: 3s
            retries: 5
            start_period: 30s
volumes:
    app-database: { }
networks:
    backend-network: { }

CLI

  1. Run only certain service
    • docker compose up mysql
    • docker compose up <service>

Dockerfile

Practices

For apt-get add --no-install-recommends to reduce image build time and size

  • https://ubuntu.com/blog/we-reduced-our-docker-images-by-60-with-no-install-recommends

Example command*

1
2
3
4
RUN apt-get update && \
    apt-get --yes --no-install-recommends upgrade && \
    apt-get clean && \
    rm --recursive --force /var/lib/apt/lists/*

Add and use non-root user.

Example command*

1
2
3
4
RUN mkdir --parents "$APP_DIR" && \
    groupadd --system appgroup && \
    useradd --system --gid appgroup appuser && \
    chown --recursive appuser:appgroup "$APP_DIR"

*Command generated by AI - validate it before using.