導入
Docker Composeを利用して、複数のdocker containerを使った環境の設定例を紹介します。なお、Docker ComposeはWindowsでは使えません。Max OSX or 64bit Linuxのみ対象となっています。
準備
Docker Toolboxをインストールできれば環境はすべて整います。
https://www.docker.com/products/docker-toolbox
docker, docker-machine, docker-composeといったツールとVirtualBoxがインストールされるはずです。
次にmachineの準備
https://docs.docker.com/machine/get-started/
$ docker-machine create --driver virtualbox default
$ docker-machine env default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/user/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
# Run this command to configure your shell:
# eval $(docker-machine env default)
$ eval $(docker-machine env default)
これでdefault machineを使ってdocker containerを起動することができるようになりました。
docker-machine ls
で確認できます
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v1.10.1
prod - google Running tcp://104.155.xxx.xxx:2376 v1.9.1
prod2 - google Running tcp://104.199.xxx.xxx:2376 v1.10.1
Version
今回利用したdockerツール類のversionを記載しておきます。
$ docker-machine -v
docker-machine version 0.6.0, build e27fb87
$ docker-compose -v
docker-compose version 1.6.0, build d99cad6
$ docker -v
Docker version 1.10.1, build 9e83765
Docker Compose 1.6からの書式変更
docker-composeは1.6からconfigurationの書式が変更になっているのでご注意ください。
以下のように構造が変わっています。
1.5系まで(version 1)
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
1.6以降
以下のようにversionを明示し, 各serviceの設定を束ねるservicesが追加されました。
version: '2'
services:
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
1.6でもversion1の書式を受け付けてくれますが、サポートは1.6系までのため新規のものはversion 2で設定してください。
Docker Compose 設定例
rails new myapp
で作成し、myappは以下の構成となっていることを前提とします。
$ ls -1F
Dockerfile
Dockerfile.prod
Gemfile
Gemfile.lock
README.rdoc
Rakefile
app/
bin/
config/
config.ru
db/
doc/
docker-compose.prod.yml
docker-compose.yml
lib/
log/
nginx/
public/
script/
test/
tmp/
vendor/
- docker-compose.ymlがcurrent dirにあると
docker-compose up -d
のみでbuildからcontainer起動まですみます。 - docker-compose.prod.ymlのようにdefault以外の名前をつけた場合、-fオプションで指定する必要があります
- 例:
docker-compose -f docker-compose.prod.yml up -d
- 例:
以下のページを参考に設定してきます。
https://docs.docker.com/compose/compose-file/
development(docker-compose.yml)
version: '2'
services:
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: $MYAPP_DATABASE_PASSWORD
volumes:
- db-data:/var/lib/mysql
redis:
image: redis:3.0.5
app:
build: .
environment:
MYAPP_DATABASE_USERNAME: root
MYAPP_DATABASE_PASSWORD: $MYAPP_DATABASE_PASSWORD
MYAPP_DATABASE_HOST: db
MYAPP_SLACK_API_TOKEN: $MYAPP_SLACK_API_TOKEN
web:
extends:
service: app
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
- redis
worker:
extends:
service: app
command: bundle exec sidekiq -q notification
volumes:
- .:/myapp
links:
- db
- redis
volumes:
db-data:
driver: local
image
image: mysql
はimage: mysql:latest
省略であり、2016/02/17現在はimage: mysql:5.7.11
を意味します
buildのたびにバージョンがばらけてしまうことになるので、image: mysql:5.7
やimage: mysql:5.7.11
というようにversion指定したほうがよいです。
基本的なものは https://hub.docker.com/ から探すことができます。
environment
containerに渡す環境変数の設定ですが、password類をyamlに書いてrepositoryに突っ込むわけにもいかないので、以下のようにshellの環境変数を渡します。
environment:
MYSQL_ROOT_PASSWORD: $MYAPP_DATABASE_PASSWORD
volumes
databaseのように永続的なストレージが欲しい場合に必要な設定です。
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
driver: local
extends
今回の例のようにwebとworker containerがあり、設定が共通している場合にはextendsを利用して共通化することができます。
app:
build: .
web:
extends:
service: app
command: bundle exec rails s -p 3000 -b '0.0.0.0'
worker:
extends:
service: app
command: bundle exec sidekiq -q notification
設定ファイルを分けて管理することもできます。
https://docs.docker.com/compose/compose-file/#extends
links
linksを設定すると、container内で名前が引けるようになります。今回の例ではwebがdbとredisに接続するため、設定しています。
links:
- db
- redis
production(docker-compose.prod.yml)
version: '2'
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
environment:
RAILS_SERVE_STATIC_FILES: 'true'
MYAPP_SECRET_KEY_BASE: $MYAPP_SECRET_KEY_BASE
MYAPP_DATABASE_USERNAME: app
MYAPP_DATABASE_PASSWORD: $MYAPP_DATABASE_PASSWORD
MYAPP_DATABASE_HOST: db
MYAPP_SLACK_API_TOKEN: $MYAPP_SLACK_API_TOKEN
logging:
driver: syslog
options:
syslog-address: "udp://logs3.papertrailapp.com:xxx"
web:
extends:
service: app
command: bundle exec puma -C config/puma.rb
links:
- db
- redis
worker:
extends:
service: app
command: bundle exec sidekiq -q notification
links:
- db
- redis
nginx:
build: ./nginx
ports:
- '80:80'
- '443:443'
volumes:
- /etc/letsencrypt:/etc/letsencrypt
links:
- web
logging:
driver: syslog
options:
syslog-address: "udp://logs3.papertrailapp.com:xxx"
db:
image: mysql
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: $MYAPP_DATABASE_PASSWORD
MYSQL_DATABASE: myapp_production
MYSQL_USER: driver
MYSQL_PASSWORD: $MYAPP_DATABASE_PASSWORD
logging:
driver: syslog
options:
syslog-address: "udp://logs3.papertrailapp.com:xxx"
redis:
image: redis:3.0.5
logging:
driver: syslog
options:
syslog-address: "udp://logs3.papertrailapp.com:xxx"
volumes:
db-data:
driver: local
build
build: .
であれば./Dockerfileを使ってbuildしますが、別のdirectoryやfileの場合にはcontext,dockerfileで指定してください。
app:
build:
context: .
dockerfile: Dockerfile.prod
以下のように書くと、./nginx/Dockerfileを使ってbuildします。
nginx:
build: ./nginx
logging
特に設定しない場合はdriver: json-file
となり、docker machine上の/var/lib/docker/containers/*/*-json.log
にログが出力されています。
ログを何処かに集約したい場合は、fluentd containerを用意してあれこれしたり、以下の様なlogging設定をする方法などが考えられます。
logging:
driver: syslog
options:
syslog-address: "udp://logs3.papertrailapp.com:xxx"
https://papertrailapp.com/ に転送する例です。実際にはxxxに指定されたport番号を書いておく必要があります。
Docker本体に関わることですが、log周りは以下が片付くとまたかわってくると思います。
補足
Dockerfile
$ cat Dockerfile
FROM ruby:2.2.4
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile Gemfile.lock /myapp/
RUN bundle install
ADD . /myapp
Dockerfile.prod
FROM ruby:2.2.4
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile Gemfile.lock /myapp/
RUN bundle install --jobs 20 --retry 5 --without development test
ENV RAILS_ENV production
ADD . /myapp
RUN bundle exec rake tmp:create
RUN bundle exec rake assets:precompile
.dockerignore
.dockerignoreファイルを用意することで余計なものをcontainerに載せずにすみます。
https://docs.docker.com/engine/reference/builder/#dockerignore-file
.git
log
tmp