Docker と Docker Compose 備忘録


Posted on 2024年 3月 20日 (水)
Tags docker, container, docker-compose
docker, container, docker-compose

Docker について備忘録をまとめる

docker コマンドについて

イメージ、コンテナへの操作

docker tag で名前を変更する

build などしてイメージが hash になっているケースで名前をわかりやすくつけたい場面がある。tag を使うしかなさそう?

Docker イメージの働き - Qiita

1docker build .
2docker tag 09134185310 myapp:latest

docker file からファイルをコピーしてくる

1docker create --name temp-image some-image
2docker cp temp-image:/some/dir/file.tmp file.tmp
3docker rm temp-image

コンテナ実行

docker run = docker create & docker start

run はコンテナを作成して、起動する。このとき、 -d の dettach を行うとそのままプロセスがバックグラウンドで走り続ける。 -i はコンテナから exit したらコンテナを落とす。

Docker Documentation

privileged を付けるとで何でもできる特権 container になる

1docker run --it alpine:latest --privileged

docker exec は実行中の docker process でコマンド実行

docker exec -it <コンテナ名> で docker で現在実行中のプロセス(ただし、PATH に shell がある)に入ることができる。

docker ps -a で停止しているプロセスも含めてすべて閲覧

1sudo docker ps -a
2
3CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
471e0cf6a50a6        101779243274        "/bin/bash"         5 weeks ago         Exited (137) 2 weeks ago                       angry_fermat
5d5577c8aca3f        bbe77145eb18        "/bin/bash"         5 weeks ago         Exited (137) 2 weeks ago                       eager_carson
6b8c0b1a734a6        101779243274        "bash"              6 weeks ago         Up 8 days                                      interesting_shtern
73ce1af5ce44c        bbe77145eb18        "/bin/bash"         8 weeks ago         Exited (137) 2 weeks ago                       hardcore_torvalds
80456af55e878        bbe77145eb18        "/bin/bash"         2 months ago        Exited (137) 2 weeks ago                       lucid_swanson

イメージ、コンテナのクリーンアップ

TAG が none の image 削除

1docker image prune

docker 1.25 から利用ができるようだ。それまでは下記のように複数のコマンドを使う必要があった。

1docker rmi $(docker images -f "dangling=true" -q)

docker でイメージ削除を for で実施する

1arr=("image_id1" "image_id2" "image_id3"); for i in "${arr[@]}" ; do sudo docker rmi -f $i ; done

docker で exit して止まっているコンテナの削除を行う

1docker rm $(docker ps -aq)

で止まっているコンテナの削除ができる。

$(docker ps -aq) は running のものも対象になっているが、 docker rm は running のコンテナは削除しない。

docker run を抜け出したら、コンテナを落とすようにする

1docker run --rm -it --name="default" alpine /bin/sh

--rm をつけることで、コマンドから抜け出したらコンテナは落ちるようにできる。 これで、色々と試行錯誤して、docker commit や save を行えば、DockerImageができるので、あとは消すだけで良い。

ヘルプで出てくる中のよく使うコマンド

 1# 個人的に普段あまりつかわないサブコマンドをコメントアウトする
 2$ docker -h
 3
 4Common Commands:
 5  run         Create and run a new container from an image
 6  exec        Execute a command in a running container
 7  ps          List containers
 8  build       Build an image from a Dockerfile
 9  pull        Download an image from a registry
10# push        Upload an image to a registry
11  images      List images
12# login       Log in to a registry
13# logout      Log out from a registry
14# search      Search Docker Hub for images
15  version     Show the Docker version information
16  info        Display system-wide information
17
18Management Commands:
19# builder     Manage builds
20  container   Manage containers
21# context     Manage contexts
22  image       Manage images
23# manifest    Manage Docker image manifests and manifest lists
24  network     Manage networks
25# plugin      Manage plugins
26  system      Manage Docker
27# trust       Manage trust on Docker images
28  volume      Manage volumes
29
30Commands:
31  attach      Attach local standard input, output, and error streams to a running container
32# commit      Create a new image from a container's changes
33  cp          Copy files/folders between a container and the local filesystem
34# create      Create a new container
35# diff        Inspect changes to files or directories on a container's filesystem
36# events      Get real time events from the server
37# export      Export a container's filesystem as a tar archive
38# history     Show the history of an image
39  import      Import the contents from a tarball to create a filesystem image
40# inspect     Return low-level information on Docker objects
41  kill        Kill one or more running containers
42  load        Load an image from a tar archive or STDIN
43  logs        Fetch the logs of a container
44# pause       Pause all processes within one or more containers
45  port        List port mappings or a specific mapping for the container
46  rename      Rename a container
47  restart     Restart one or more containers
48  rm          Remove one or more containers
49  rmi         Remove one or more images
50  save        Save one or more images to a tar archive (streamed to STDOUT by default)
51# start       Start one or more stopped containers
52# stats       Display a live stream of container(s) resource usage statistics
53# stop        Stop one or more running containers
54  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
55  top         Display the running processes of a container
56# unpause     Unpause all processes within one or more containers
57# update      Update configuration of one or more containers
58# wait        Block until one or more containers stop, then print their exit codes

docker compose

docker compose コマンドについて

1# 起動
2docker compose up
3
4# volume を使うと、自動的には削除されない。下記のコマンドを使うと、running ではないコンテナと volume も削除できる
5docker system prune --volumes
6
7# docker compose で起動したコンテナを停止、あわせて不要な volume も削除する
8docker compose down -v

docker-compose.yml

restart

Container がクラッシュしたときの振る舞い。 restart だと必ず再度立ち上げようとする。

user

Compose file version 3 reference | Docker Documentation にあるとおり、これは docker run の USER に値する。 そして、これは User の UID や username を指定できる。

depends_on

起動順序の定義が行える。終了時は逆順となる。 特に web が db に依存する場合は、depends_on: [ db ] のようになることが多い。

ちなみに、web から db へアクセスしたいとき、db:5432 のように指定することで名前解決ができる。

 1services:
 2  db:
 3    image: postgres:15
 4    environment:
 5      POSTGRES_DB: dev
 6      POSTGRES_USER: postgres
 7      POSTGRES_PASSWORD: postgres
 8    ports:
 9      - 5432:5432
10
11  django:
12    build: .
13    command: python manage.py runserver 0.0.0.0:8000
14    environment:
15      # host名は docker で起動された db となる
16      DATABASE_URL: "postgres://postgres:postgres@db:5432/dev"
17      SECRET_KEY: "sample_secret_key"
18    volumes:
19      - .:/djangoapp
20    ports:
21      - "8000:8000"
22    depends_on:
23      - db

docker の仕組み

docker のネットワーク

Docker のネットワークはよくハマる。

Docker compose ではアプリケーション1つに対して、ネットワークを作成する。 各コンテナ上のサービスはデフォルトネットワークに参加したら、同一ネットワーク上の他のコンテナから接続できるようになります。また、ホスト名とコンテナ名でも発見可能になります。

network driver

Driver には、bridge か overlay が指定できる。デフォルトでは bridge。

bridge ネットワークとは

「docker0 に値する」とあるが、どのような意味だ…

Use bridge networks | Docker Documentation

1A bridge network is a Link Layer device which forwards traffic between network segments. A bridge can be a hardware device or a software device running within a host machine’s kernel.

ネットワークセグメント間で通信を転送する Link layer device とある。 Docker は software bridge を使っていて、定義された bridge network 内につながっているコンテナはお互いに通信が行える。

bridge モードのときは、同じ docker daemon を利用しているコンテナは同じ bridge network になる

異なる daemon 間で通信したい場合は、OS などの設定でルーティングさせるか、overlay ネットワークを使うらしい。

ブリッジ接続 (bridge connection)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

Use bridge networks | Docker Documentation

1The default bridge network is considered a legacy detail of Docker and is not recommended for production use. Configuring it is a manual operation, and it has technical shortcomings.

デフォルトの bridge network はレガシーとある。

daemon.json で docker daemon が利用する bridge network の設定が記載されている。

 1To configure the default bridge network, you specify options in daemon.json. Here is an example daemon.json with several options specified. Only specify the settings you need to customize.
 2
 3{
 4  "bip": "192.168.1.5/24",
 5  "fixed-cidr": "192.168.1.5/25",
 6  "fixed-cidr-v6": "2001:db8::/64",
 7  "mtu": 1500,
 8  "default-gateway": "10.20.1.1",
 9  "default-gateway-v6": "2001:db8:abcd::89",
10  "dns": ["10.20.1.2","10.20.1.3"]
11}

192.168.1.0 - 192.168.1.255 のレンジを利用しているようだ。

user define bridge で通信

1Containers connected to the same user-defined bridge network automatically expose all ports to each other, and no ports to the outside world. This allows containerized applications to communicate with each other easily, without accidentally opening access to the outside world.

同じ bridge network では全てのポートがお互いに通信できるが、外の世界からはポートが空いていないように見える。

Dockerfile の書き方

作り方の参考資料

ADD はレイヤーが増えるが、 COPY はレイヤーを増やさない

docker image のファイルサイズを小さくする

go の src に vendor があるのでサイズは大きくなる。でも /go/bin が使われるだけなので、/go/src はまとめて不要 (- 300MB)

1[root@7a4baa5582f7 /]# du -sh /go/bin/* | sort -h
23.7M    /go/bin/yaml-patch
313M     /go/bin/om
428M     /go/bin/bosh-cli
5[root@7a4baa5582f7 /]# du -sh /go/src/* | sort -h
62.2M    /go/src/gopkg.in
731M     /go/src/golang.org
8299M    /go/src/github.com

/usr/local/go は go 言語をインストールしたため存在する。 しかし、image build 後は go を実行しないので不要となる(go の binary は作られているため) (- 300 MB)

1[root@7a4baa5582f7 /]# du -sh /usr/local/go/* | sort -h
26.5M    /usr/local/go/api
312M     /usr/local/go/test
431M     /usr/local/go/bin
575M     /usr/local/go/src
6214M    /usr/local/go/pkg

/usr/lib 内は Python, jvm でそもそもの動作に必要なので、削除できない。

15.7M    /usr/lib/udev
29.1M    /usr/lib/systemd
3155M    /usr/lib/python2.7
4166M    /usr/lib/jvm

yum の cache も不要 (- 80MB)

1[root@7a4baa5582f7 /]# du -sh /var/cache/* | sort -h
216K     /var/cache/ldconfig
381M     /var/cache/yum

multi stage build でどこからでも確実にビルドできるようにする

multi stage を利用するととても便利。dockerfile を build するだけで必要なものを揃えることができる。

  1. make build 方式 <- バイナリのダウンロードなど高速化できるが、make を実行する環境依存
  2. multi stage build <- 環境を整えるのが冗長だが、docker build するだけで済む

multi stage build で ARG を利用する時

1ARG JDK_VERSION="15"
2ARG PLANTUML_VERSION="1.2020.2"
3FROM openjdk:${JDK_VERSION}-jdk-alpine
4
5RUN apk add --update-cache graphviz wget && \
6    wget "http://downloads.sourceforge.net/project/plantuml/$PLANTUML_VERSION/plantuml.$PLANTUML_VERSION.jar" 

このコードは動かなくて、ARG は最初の FROM で認識されるにとどまる。正しくは下記のようにする。

1ARG JDK_VERSION="15"
2FROM openjdk:${JDK_VERSION}-jdk-alpine
3
4ARG PLANTUML_VERSION="1.2020.2"
5RUN apk add --update-cache graphviz wget && \
6    wget "http://downloads.sourceforge.net/project/plantuml/$PLANTUML_VERSION/plantuml.$PLANTUML_VERSION.jar" 

.dockerignore を定義することで、docker image に入れるファイルを制限できる

1.git
2**/secret.yaml

と書くことで、どこのフォルダでも除くことができる。.gitignore とやや書式が異なるので注意

この場合、.git フォルダを除かないと git reset でシークレットが復元できたりしてしまうので注意(そもそもなんで secret 入ってんねんって話だが)

Share


See also