Skip to content

Docker

Docker

run container

docker container run --interactive --tty diamol/base    

--interactive , -it: connect to container with interact mode

--tty : connect to terminal

--detach : run container in background

--publish 8088:80 : use physical port 8088 for container port 80

check all container information

docker container ls # check alived container 
docker container ls --all # check all container

check container process

docker container top <CONTAINER ID>

check container log

docker container logs <CONTAINER ID>

check container detail info

docker container inspect <CONTAINER ID>

check container resources

docker container stats <CONTAINER ID>

execute command in docker container

docker container exec <CONTAINER ID> <COMMAND>

copy files from host to container

docker container cp <source> <CONTAINER ID>:<target>

change environment variable

docker container run -e VAR1=var1 -e VAR2=var2 <CONTAINER ID>

remove container

docker container rm <CONTAINER ID>
docker container rm --force $(docker container ls --all --quiet) 

--force : force to remove even when still running

create a virtual network

docker network create nat

delete all container

docker rm -f $(docker ps -aq)

Build

Docker file

FROM diamol/node

ENV TARGET="blog.sixeyed.com"
ENV METHOD="HEAD"
ENV INTERVAL="3000"

WORKDIR /web-ping
COPY app.js .

EXPOSE 80

CMD ["node", "/web-ping/app.js"]

build docker image base on docker file

docker image build --tag web-ping .
  • --tag : image name
  • . : target directory to build

the build image will locate in cache, use docker image ls to check result

$ docker image ls w*
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
web-ping     latest    4d95a21e3e1c   2 minutes ago   75.3MB

check metadata of build image

docker image history web-ping

file system

use docker volume to save file change in container file system

create

docker volume create todo-list

use in container run: -v

docker container run -d -p 8011:80 -v todo-list:/data --name todo-v1 diamol/ch06-todo-list

from docker file

notice that VOLUME in docker file is different with -v command, if run command didn’t specify a volume, it will use the file one, else overwrite it

# app image
FROM diamol/dotnet-aspnet
WORKDIR /app
ENTRYPOINT ["dotnet", "ToDoList.dll"]

# set in the base image - `/data` for Linux, `C:\data` for Windows
VOLUME /data

COPY --from=builder /out/ .

volume can be shared between each container, use --volumes-from

$ docker container run -d --name t3 --volumes-from todol diamol/ch06-todo-list
4a51c9e44995b6876165de59568cc2d4d28af0d569a674759489195bd40019e7
$ docker container exec t3 ls /data/
todo-list.db

container remove will not affect volume.

access host file from container: use bind host

$source="$(pwd)/database" && target='/data'
$mkdir ./database
$docker container run --mount type=bind,source=$source,target=$target -d -p 8012:80 diamol/ch06-todo-list
$curl http://localhost:8012
$ls ./databases

since docker container usually runs with lowest user privilege, if we want to read/write host files, we need to change docker container privilege.

we can set file as read only in host, that way we don’t need change docker image, and achieve changing config…etc

mount will overwrite the container one if same directory

windows cannot mount a file

# following command will fail on windows system
$ docker container run --mount type=bind,source="$(pwd)/new/123.txt",target="/init/123.txt" diamol/ch06-bind-mount

Docker compose

a tool to manage docker container

example: execute todo-list container using docker compose

version: '3.7'

services:

    todo-web:
        image: diamol/ch06-todo-list
        ports:
            - "8020:80"
        networks:
            - "app-net"

networks:
    app-net:
        external:
            name: nat
  • version: docker compose version
  • services: element to form a compose, a service might have multiple container
  • network: docker virtual network can be join by service

docker-compose command will find a file docker-compose.yml in current working directory

example: multi-container in a composer

version: '3.7'

services:

  accesslog:
    image: diamol/ch04-access-log
    networks:
      - app-net

  iotd:
    image: diamol/ch04-image-of-the-day
    ports:
      - "80"
    networks:
      - app-net

  image-gallery:
    image: diamol/ch04-image-gallery
    ports:
      - "8010:80" 
    depends_on:
      - accesslog
      - iotd
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat
  • depends on : service will wail on other until they’re up
  • environment: create a environment variable for service

run the docker-compose

$docker-compose up --detach 
  • --detach: run compose in detach mode

run multiple container in one compose

$ docker-compose up -d --scale iotd=3

check compose log

$ docker-compose logs iotd
  • --tail=1 : show last log message in each iotd service

check process of running service

stop compose

$ docker-compose stop

will keep service as last open history

remove compose

$ docker-compose down

will remove service open history

labeling

when trying to launch multiple same compose at same directory, docker compose will not launch duplicate one

we can change compose name to prevent this issue

$ docker-compose -f ./todo-list/docker-compose.yml -p todo-test up -d
  • -p: project name of compose

over-write

when a compose file need to be configured in different use case (such as open multiple same compose with different port), we can use overwrite property to provide different set-up for the same docker-compose file

  • original compose file
service:
  todo-web:
      image: diamol/ch06-todo-list
      ports:
          - 80
      environment:
          - Database:Provider=Sqlite
      networks:
          - app-net
  • the overwrite one
services:
  todo-web:
      image: diamol/ch06-todo-list:v2
  • execute in terminal
$ docker-compose -f ./todo-list/docker-compose.yml -f ./todo-list/docker-compose-v2.yml ...

{51DF9444-9B40-47DA-9565-03C1EF14251F}


health check

check if process in container exited un-exceptly or not

DOCKERFILE : HEALTHCHECK syntax

FROM diamol/dotnet-aspnet

ENTRYPOINT ["dotnet", "/app/Numbers.Api.dll"]
HEALTHCHECK CMD curl --fail https://localhost/health

WORKDIR /app
COPY --from=builder /out/ .

container will be marked as unhealthy when CMD returns non zero

docker cannot take action about unhealthy container (rm or restart), since it might lost data

dependency check

when launching multiple container, it might not follow the execute order.

dependency check can prevent program runs before any dependency

FROM diamol/dotnet-aspnet
ENV RngApi:Url=http://numbers-api/rng
CMD curl --fail http://numbers-api/rng && dotnet Numbers.Web.dll
WORKDIR /app
COPY --from=builder /out/ .

if curl command success, then open the server, else exit docker container

lastly, write test ourself and intergrade into dockerfile

FROM diamol/dotnet-aspnet

ENTRYPOINT ["dotnet", "Numbers.Api.dll"]
HEALTHCHECK CMD ["dotnet", "Utilities.HttpCheck.dll", "-u", "https://localhost/health"]

WORKDIR /app
COPY --from=http-check-builder /out/ . COPY --from=builder /out/ .

health in docker composer

numbers-api:
    image: diamol/ch08-numbers-api:v3
    ports:
        - "8087:80"
    restart: on-failure
    healthcheck:
        test: ["CMD", "dotnet", "Utilities.HttpCheck.dll", "-t", "150"]
        interval: 5s
        timeout: 1s
        retries: 2
        start_period: 5s
    networks:
        - app-net

monitor

use Prometheus to fetch all data using /metric node from all container

add Prometheus metric into language:

* go: use `gorutine`
* java: memory use in `JVM`

Grafana:

a more powerful visualize tool using same protocol as Prometheus


Docker Swarm

connect multiple machine running docker (like a swarm), which will allocate and maintain containers

a computer in a swarm is being called as node

for workers to add into manager, they need tokens to add into it

$ docker swarm init
Swarm initialized: current node (mnp3pr7vpxgn4cwt0ezd0wuw7) is now a manager.

To add a worker to this swarm, run the following command:
doc
    docker swarm join --token SWMTKN-1-586z8vco6elux4gjnvghdp31v9erf8r7bjx5o7mnpapha24m41-2a7dvsccirbpx63d7r6of8jzf 192.168.1.112:2377

$ docker swarm join --token SWMTKN-1-586z8vco6elux4gjnvghdp31v9erf8r7bjx5o7mnpapha24m41-2a7dvsccirbpx63d7r6of8jzf 192.168.1.112:2377

$ docker node ls
ID                            HOSTNAME                            STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
mnp3pr7vpxgn4cwt0ezd0wuw7 *   mint-HP-Pavilion-Laptop-15-cs2xxx   Ready     Active         Leader           28.0.0

use docker service to manage container under swarm