docker-compose の ${VAR:-default} 記法と .env で開発&本番環境を設計する
April 14, 2020
docker-compose.yml で、シェルでよくある ${VAR:-default}
記法が使えるのがあまり知られていないようだったので書きます。
[https://www.debuntu.org/how-to-bash-parameter-expansion-and-default-values/:embed:cite]
サンプルプロジェクトはこちらです [https://github.com/tamakiii-sandbox/docker-compose-variable:embed:cite]
PHP が動く Dockerfile と
# Dockerfile
FROM docker.io/php:7.2.29-cli
それを使う docker-compose.yml を用意します。今回はサービスは1つです。
# docker-compose.yml
version: "3.7"
services:
php:
build:
context: .
working_dir: /app
volumes:
- .:/app
動かすプログラム src/main.php
は環境変数 $MESSAGE
を出力するだけです。
<?php
echo $_ENV["MESSAGE"] . PHP_EOL;
Dockerfile で ENV MESSAGE "hello"
として
FROM docker.io/php:7.2.29-cli
ENV MESSAGE "hello"
これを実行すると、ENV
した hello が出力されます。
$ docker-compose run --rm php php src/main.php
hello
これは環境変数なので当然シェルも同様です
$ docker-compose run --rm php sh -c 'echo $MESSAGE'
hello
docker-compose.yml で environment
に表題の MESSAGE: ${MESSAGE:-holla}
とすると
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,6 +3,8 @@ services:
php:
build:
context: .
+ environment:
+ MESSAGE: ${MESSAGE:-holla}
working_dir: /app
volumes:
- .:/app
デフォルト値の holla が出力されます
$ docker-compose run --rm php php src/main.php
holla
-e
を指定するとこちらが優先されます
$ docker-compose run --help | grep -- "-e KEY=VAL"
run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...]
-e KEY=VAL Set an environment variable (can be used multiple times)
$ docker-compose run --rm -e MESSAGE=ciao php php src/main.php
ciao
.env
を docker-compose が勝手に読むので、状態を .env
に保持しておけます
$ echo "MESSAGE=haisai" > .env
$ docker-compose run --rm php php src/main.php
haisai
さて、ここで開発用にgitやvimを入れたくなった気持ちになってみます。
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,3 +1,10 @@
FROM docker.io/php:7.2.29-cli
+RUN apt-get update && \
+ apt-get install -y \
+ vim \
+ git \
+ && \
+ apt-get clean
+
ENV MESSAGE "hello"
本番稼働時は要らないですよね
$ docker-compose build
Building php
Step 1/4 : FROM docker.io/php:7.2.29-cli
---> e7d2518687da
Step 2/4 : ENV MESSAGE "hello"
---> Using cache
---> 51c63dafa792
Step 3/4 : FROM production-pseudo AS development
---> 51c63dafa792
Step 4/4 : RUN apt-get update && apt-get install -y vim git && apt-get clean
---> Using cache
---> 964a4048e6ab
そんなときは target build stages の出番です。
production-pseudo
はまだ本番稼働していない疑似本番環境を表す語として使っています。
FROM docker.io/php:7.2.29-cli AS production-pseudo
RUN # ここに本番で要るものだけインストールする
# --
FROM production-pseudo AS development
RUN apt-get update && \
apt-get install -y \
vim \
git \
&& \
apt-get clean
これで TARGET=production-pseudo
時はvimやgitをインストールしなくなりました
$ docker-compose build
Building php
Step 1/2 : FROM docker.io/php:7.2.29-cli AS production-pseudo
---> e7d2518687da
Step 2/2 : ENV MESSAGE "hello"
---> Using cache
---> 51c63dafa792
Successfully built 51c63dafa792
Successfully tagged docker-compose-variable_php:latest
TARGET=development
時はインストールされます
$ echo "TARGET=development" > .env
$ docker-compose build
Building php
Step 1/4 : FROM docker.io/php:7.2.29-cli AS production-pseudo
---> e7d2518687da
Step 2/4 : ENV MESSAGE "hello"
---> Using cache
---> 51c63dafa792
Step 3/4 : FROM production-pseudo AS development
---> 51c63dafa792
Step 4/4 : RUN apt-get update && apt-get install -y vim git && apt-get clean
---> Running in 36bcf0f189fe
$ docker-compose run --rm php which git
/usr/bin/git
これに VSCode の Remote Containers 拡張用を合わせて使うと相性が良いです。
FROM development AS debug
として XDebug をインストールする、といった使い方もできます(それなりに重いので)。
が、話が長くなるのでこれについてはまた次回書きます。
ちなみに今回、 .env
を作ったりする docker.mk
はこの様になりました
.PHONY: install install-dev development clean
TARGET := production-pseudo
install: \
.env \
build
install-dev: \
development \
install
development:
$(eval TARGET := development)
.env:
touch $@
echo "TARGET=$(TARGET)" >> $@
build:
docker-compose build
clean:
rm -rf .env