ざっくりdocker-compose

ヨメレバCSS
オリジナルCSS

docker-composeを使って色々やるとき割とよく使うことのまとめみたいなものです。

スポンサーリンク
GoogleAdSence レクタングル(大)

基本形

カレントディレクトリにdocker-compose.ymlを作成します。

version: "3"
services:
  app:

networks:
  default:

「app」が(このdocker-compose内での)サービス名になります。ここの設定を元に、イメージやコンテナが作られ動きます。

タブに注意

インデントはタブではなくスペースで入れる必要があります。

エディタで書いてるとついタブが入ってしまうことがありますが、それだとエラーになります。

ERROR: yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any token
  in ".\docker-compose.yml", line 2, column 1

ってなります。

docker-composeの一部を変更する

チームで共有しているdocker-composeの一部だけを変更したい場合など、一部を変更する場合にはdocker-compose.override.ymlを作成します。

このファイルに書いてある内容が、もとのdocker-comopse.ymlに上書きされます。

サービスの拡張と Compose ファイル

設定の一部を引き継ぐ

他のコンテナ設定をコピーする、引き継いで作成する場合はYAMLのアンカーとエイリアスが使えます。

「&」で目印を付けて「*」で展開する感じです。

services:
  app1: &app
    image: centos:7

  app2: *app

こうするとapp1の内容をapp2に展開できます。

YAMLのエイリアスでAnsibleファイルの重複を減らす

イメージを作る

既存のイメージを使う

services:
  app: 
    image: centos:7

のように指定します。

イメージはDockerHubにあるものを使用できます。公式だけでなく、個人で公開されているものもあるみたいです。

Docker公式が配布しているイメージには「Docker Officeal Images」とあります。

例えばcentos。

Guidelines for Official Images on Docker Hub

Dockerfileを使う

Dockerfileを指定する場合はbuild.dockerfileを指定します。

services:
  app: 
    build:
      dockerfile: ./Dockerfile

コンテナ内のカレントディレクトリを指定する

working_dirで指定します。

services:
  app: 
    working_dir: /var/log
$ docker-compose run app
[root@52d5c6f944b4 log]# pwd
/var/log

ファイルをマウントする

ファイルをマウントするにはvolumensに定義を書きます。

カレントディレクトリからの相対パスもできます。

services:
  app: 
    image: centos:7
    volumes:
      - ./test:/test

volumesのマウントは、コンテナ内に同名のファイルやディレクトリがあっても優先されます。(逆にもともとコンテナにあったファイルおよびディレクトリは隠れてしまいます。単純にコンテナ内のファイルを共有するわけではありません)

また指定したパスまでのディレクトリがコンテナ内に無い場合でも、問題なくそのパスでマウントされます。

なので/var/log/nginxをマウントしてログを出力させたりとか、/etc/nginx/nginx.confをマウントして設定変えたりとかします。

up/runで実行するコマンドを指定する

コンテナを起動したときの動作を指定します。

※commandとentrypointは似て異なるものになりますがざっくりなのでまとめています。使用する際にはそれぞれの意味をご確認下さい。

DockerfileのCMDとENTRYPOINT

DockerfileのCMDとENTRYPOINTはそのまま動作します。

commandとentrypoint

commandとentrypointでDockerfileのそれを上書きできます。

services:
  app: 
    command:
      ls

または

services:
  app: 
    entrypoint:
      ls

lsだけして終わります。

複数のコマンドを指定する

複数のコマンドを指定するときはシェル引数で連結したりできます。

services:
  app: 
    image: centos:7
    command: |
      sh -c ' \
      ls && \
      touch sample.file && \
      echo "touch sample file" && \
      ls '

これを実行してみるとsample.fileが作成されています。

$ docker-compose run app
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr
touch sample file
anaconda-post.log  dev  home  lib64  mnt  proc  run          sbin  sys  usr
bin                etc  lib   media  opt  root  sample.file  srv   tmp  var

run時の引数に指定

docker-compose run時のコンテナ名以下の引数はそのまま実行されます。

$ docker-compose run app ls -a
.           anaconda-post.log  etc   lib64  opt   run   sys   usr
..          bin                home  media  proc  sbin  test  var
.dockerenv  dev                lib   mnt    root  srv   tmp

または

$ docker-compose run  --entrypoint="ls -a" app
.           anaconda-post.log  etc   lib64  opt   run   sys   usr
..          bin                home  media  proc  sbin  test  var
.dockerenv  dev                lib   mnt    root  srv   tmp

run/upでコンテナを起動しっぱなしにする

基本的にコンテナはコマンドを実行し終えたら終了してしまいますが、nginxのようにサービスとして起動していて欲しいときもあります。

ttyをtrueにする

services:
  app: 
    tty: true

おそらくターミナルの待ち受けになり、結果起動しっぱなしになるのかなと思います。

commandなどで終了しないようにする

何らかの方法でコマンドを終了しないようにすれば、起動しっぱなしになります。

例えばnginxはデーモン起動しないことでコンテナを起動させ続けていたりするようです。

Docerfileより

CMD ["nginx", "-g", "daemon off;"]

次のように/dev/nullをtailし続けるとか。

services:
  app: 
    command: tail -f /dev/null

こうなります。

$ docker-compose up app
Recreating sample_app_1 ... done
Attaching to sample_app_1

ここはそれぞれの環境にあわせて、どう実行させるかを決めて下さい。

コンテナ内部から他のサービスを参照する

docker-comopse.ymlにあるコンテナ群は閉じたネットワーク内のマシンとして認識されており、他のサービスのコンテナに(普通のネットワーク越しみたいな感じで)接続することも出来ます。

サービス名をホスト名として指定する

services:
  app: 
    image: centos:7

  nginx: 
    image: nginx

nginxに対してpingしてみます。

$ docker-compose up -d nginx
Creating sample_nginx_1 ... done

$ docker-compose run app ping nginx
PING nginx (172.20.0.2) 56(84) bytes of data.
64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=3 ttl=64 time=0.072 ms
^C
--- nginx ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2056ms
rtt min/avg/max/mdev = 0.072/0.089/0.108/0.014 ms

エイリアス名を設定する

nginxでVirtualHostを設定するときなど、他の名前解決をしたいときがあります。

その場合はaliasを使います。このときにはデフォルトでいいので、networkの指定も必要です。

services:
  app: 
    image: centos:7

  nginx: 
    image: nginx
    networks:
      default:
        aliases:
          - host1
          - host2

pingしてみます。


$ docker-compose run app ping host1 PING host1 (172.20.0.2) 56(84) bytes of data. 64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=1 ttl=64 time=0.161 ms 64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=2 ttl=64 time=0.088 ms ^C --- host1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1037ms rtt min/avg/max/mdev = 0.088/0.124/0.161/0.038 ms $ docker-compose run app ping host2 PING host2 (172.20.0.2) 56(84) bytes of data. 64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=1 ttl=64 time=0.091 ms 64 bytes from sample_nginx_1.sample_default (172.20.0.2): icmp_seq=2 ttl=64 time=0.085 ms ^C --- host2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.085/0.088/0.091/0.003 ms

ポートを開ける

コンテナのportをポートフォワードしたいときはportを指定します。

services:
  nginx: 
    image: nginx
    ports: 
      - 8000:80

左にホストOSのポート、右にコンテナ(この場合はnginxコンテナ)のポートを指定します。

これでhttp://localhost:8000/ としてアクセスできます。

変数を使う

変数には二種類あります。docker-compose.yml内で使用するものと、コンテナを起動したときに環境変数として設定されるものです。

このあたりのファイルにホスト名などの変更されやすい情報や、リポジトリに含めない設定ファイルにパスワードなどの重要な情報を設定してしたりしておくと便利です。重要情報はリポジトリに含めない設定ファイルにです。大事なことなので二回言いました。

docker-compose.ymlで使うための変数

カレントディレクトリに.envファイルを作ります。

HOGE=centos:7

それでdocker-compose.ymlではこう。

services:
  app: 
    image: ${HOGE}

コンテナ内に設定する環境変数

environmentとenv_fileを使います。

environment

docker-compose.ymlに直接書きます。

services:
  app: 
    environment:
      ENV_SAMPLE: hoge

コンテナ内で確認。

$ docker-compose run app
[root@31bc6a655b81 /]# echo $ENV_SAMPLE
hoge

env_file

数が多いときはファイルにまとめます。

local_envファイルを作成して、次のように書いておきます。

ENV_LOCAL=hoge2

docker-composeのenv_fileでファイルを指定します。複数指定も可能です。(その場合、下に書いたファイルが優先されます)

services:
  app: 
    env_file:
      - local_env

コンテナ内で確認。

$ docker-compose run app
[root@7ccdfccb3d3c /]# echo $ENV_LOCAL
hoge2
[root@7ccdfccb3d3c /]#

environemntとenv_fileで同じ環境変数を指定した場合

environmentのほうが優先されます。docker-compose.ymlに直書きされているものが強いということですね。

.envの変数はenv_fileのファイルでは使えない

先ほど.envで指定したHOGEは、environmentでは使えますがenv_fileで指定したファイル内では使えません。

docker-comopse.yml

services:
  app: 
    environment:
      ENV_HOGE: ${HOGE}
    env_file:
      - local_env

local_env

ENV_HOGE_LOCAL=${HOGE}

コンテナ実行

$ docker-compose run app
[root@f0fd70a2f2f8 /]# echo $ENV_HOGE
centos:7
[root@f0fd70a2f2f8 /]# echo $ENV_HOGE_LOCAL
${HOGE}
[root@f0fd70a2f2f8 /]#

.envをそのままenv_fileに指定する

形式は同じなので.envをそのまま環境変数に設定できたりもします。

services:
  app: 
    env_file:
      - .env

コンテナでの確認

$ docker-compose run app
[root@2e4b9ac6253a /]# echo $HOGE
centos:7

自動起動しないようにする

デフォルトの状態だと、docker-compose upしたコンテナはDockerデーモンが再起動すると自動起動するようになっています。

その設定はrestartで変更できます。

services:
  app: 
    image: centos:7
    restart: no

restartに設定できるパラメータはDocker runの--restartオプションと一緒です。

参考

ざっくりなのでそれぞれの機能とか、深いところは必要に応じて調べていってもらえればと思います。

  • 公式ドキュメント
Introduction and Overview of Compose

細かいオプションなんかはリファレンスを見て下さい。

Compose file reference
  • 日本語ドキュメント

日本語ドキュメントはところどころ古いですが、そこまで大きな違いはないため参考になります。(あれっと思ったら本家公式のほうを当たることもあります)

  • Dockerfileのベストプラクティス
スポンサーリンク
GoogleAdSence レクタングル(大)

シェアする

スポンサーリンク
GoogleAdSence レクタングル(大)