70
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

docker-compose.ymlでcommandの引数が長いのでエスケープして改行したい

Dockerフレンドリーなコマンドは設定ファイルなしでも引数でいろいろ挙動が指定できて便利なんだけど、
コマンドの引数の指定が長くなりがちである。

例えばoauth2_proxyはシングルバイナリで、設定ファイルもあるけど、すべての設定が引数で指定できる。

何も考えずに素朴に並べるとこんなかんじで、起動コマンドがクッソ長くなる。

docker-compose.yml
version: '2'
services:
  oauth2_proxy:
    image: oauth2_proxy
    command: /bin/oauth2_proxy -provider="github" -github-org="${OAUTH2_PROXY_GITHUB_ORG}" -github-team="${OAUTH2_PROXY_GITHUB_TEAM}" -http-address="0.0.0.0:4180" -redirect-url="https://upstream/oauth2/callback" -upstream="http://upstream:4440/" -email-domain="*" -cookie-refresh="1h"

圧倒的に読みづらい。

ymlで改行をエスケープするにはどうすればよいのか?
ymlではシェルでおなじみの \ ではなくて > 記号でできる。

docker-compose.yml
version: '2'
services:
  oauth2_proxy:
    image: oauth2_proxy
    command: >
      /bin/oauth2_proxy
      -provider="github"
      -github-org="${OAUTH2_PROXY_GITHUB_ORG}"
      -github-team="${OAUTH2_PROXY_GITHUB_TEAM}"
      -http-address="0.0.0.0:4180"
      -redirect-url="https://upstream/oauth2/callback"
      -upstream="http://upstream:4440/"
      -email-domain="*"
      -cookie-refresh="1h"

圧倒的に見やすい。

ちなみにymlの改行記号には2種類あって、 > だと複数行を空白文字で連結したものとして評価されるんだけど、| 記号だと改行文字で連結したものとして評価されるよう。

ところで Dockerで環境変数を設定ファイルに埋め込むのに便利な envsubst でnginxの設定に環境変数を埋め込もうとすると、必然的にダブルクオートの中が長くなる。

ダブルクオートの中で改行したい場合は、 > で複数行にして空白文字で連結されるから、ダブルクオートの中は \ にすると改行できる。難しい。 (2017/02/05訂正: 改行記号が入るのはダブルクオートではなくインデントが原因でした。難しい)

ダブルクオートの中でも特にインデントしなければ、そのまま単純に並べればよい。

docker-compose.yml
version: '2'
services:
  nginx:
    image: nginx:alpine
    command: >
      /bin/sh -c
      "envsubst '
      $$NGINX_SERVER_NAME
      $$NGINX_UPSTREAM_HOST
      $$NGINX_UPSTREAM_PORT
      '< /etc/nginx/nginx.conf.template
      > /etc/nginx/nginx.conf
      && nginx -g 'daemon off;'"
    volumes:
      - ./nginx.conf.template:/etc/nginx/nginx.conf.template
    ports:
      - 8080:80
    environment:
      NGINX_SERVER_NAME: "test.example.com"
      NGINX_UPSTREAM_HOST: "hoge"
      NGINX_UPSTREAM_PORT: "80"

>の中でインデントすると改行記号が入るよう。インデントしたい場合は、 > で複数行にして空白文字で連結されるから、インデントした場合は \ でエスケープすれば改行できる。難しい。

docker-compose.yml
version: '2'
services:
  nginx:
    image: nginx:alpine
    command: >
      /bin/sh -c
        "envsubst ' \
        $$NGINX_SERVER_NAME \
        $$NGINX_UPSTREAM_HOST \
        $$NGINX_UPSTREAM_PORT \
        '< /etc/nginx/nginx.conf.template \
        > /etc/nginx/nginx.conf \
        && nginx -g 'daemon off;'"
    volumes:
      - ./nginx.conf.template:/etc/nginx/nginx.conf.template
    ports:
      - 8080:80
    environment:
      NGINX_SERVER_NAME: "test.example.com"
      NGINX_UPSTREAM_HOST: "hoge"
      NGINX_UPSTREAM_PORT: "80"

これをデバッグしてて、 docker-compose config という設定ファイルをparseだけしていくれるコマンドがあることに気づいた。エスケープがおかしいときとか、シンタックスエラーとか出る場合に使うとよいのでわないかと。参考までに上記のインデントありのやつをパースするとこんなかんじ。

$ docker-compose config
networks: {}
services:
  nginx:
    command: "/bin/sh -c\n  \"envsubst ' \\\n  $NGINX_SERVER_NAME \\\n  $NGINX_UPSTREAM_HOST\
      \ \\\n  $NGINX_UPSTREAM_PORT \\\n  '< /etc/nginx/nginx.conf.template \\\n  >\
      \ /etc/nginx/nginx.conf \\\n  && nginx -g 'daemon off;'\"\n"
    environment:
      NGINX_SERVER_NAME: test.example.com
      NGINX_UPSTREAM_HOST: hoge
      NGINX_UPSTREAM_PORT: '80'
    image: nginx:alpine
    ports:
    - 8080:80
    volumes:
    - /Users/m-morita/work/tmp/20170204/nginx.conf.template:/etc/nginx/nginx.conf.template:rw
version: '2.0'
volumes: {}

というわけで、docker-compose.ymlも適切に改行して見やすくしましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
70
Help us understand the problem. What are the problem?