本番環境用のdocker-compose
従来、コンテナの作成は開発環境でのみ行われることが多かったが、これを本番環境でも利用することで、開発環境と同一の環境での運用を可能とし、サービスの冗長性を高め、環境の違いによる不具合を軽減する事例が増えているそうだ。
コンテナを構築するための情報が記載されているファイルがdocker-compose.ymlである。そしてこのファイルは、本番環境と開発環境で使い分けが可能である。
今回実施する内容は、使い分けというよりは、本番環境用にファイルの内容を上書きするという言い方が正しいかも知れない。具体的にはdocker-compose.ymlとは別に、docker-compose-prod.ymlという名称のファイルを作成し、コンテナの構築時に以下のように-fオプションで参照するdocker-composeファイルを指定する方法である。
docker-compose -f docker-compose-prod.yml up
ここでは、以下の記事に書かれているコードを元に、環境ごとにdocker-composeを分けていく。尚、プロキシとしてNginxを使っているので、それも踏まえたうえで行っていきたい。
ディレクトリ構成は、アプリケーションのディレクトリ(ここではapp_nameとしている)の配下に以下のファイル、およびフォルダを作成する。
Dockerfile
docker-compose.yml
docker-compose-prod.yml
config
└ puma.rb
nginx_docker_prod
├ Dockerfile
└ nginx.conf
nginx_docker_dev
├ Dockerfile
└ nginx.conf
Dockerfile
Dockerfileについては、今回は二つ作成する必要はなく、以下のものを開発環境と本番環境で共通して使用する。
FROM ruby:3.0.0
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
&& curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs \
&& apt-get update -qq \
&& apt-get -y install \
yarn \
nodejs \
imagemagick \
default-mysql-server \
default-mysql-client
WORKDIR /app_name
COPY Gemfile /app_name/Gemfile
COPY Gemfile.lock /app_name/Gemfile.lock
RUN gem install bundler
RUN bundle install
RUN mkdir -p tmp/sockets
docker-compose.yml
開発時に使うdocker-compose.ymlは以下の通り設定する。本番環境との違いについてはコメントアウトで記載している。
version: '3'
services:
app:
build:
context: .
command: bundle exec puma -C config/puma.rb
volumes:
- .:/app_name
- public-data:/app_name/public
- tmp-data:/app_name/tmp
- log-data:/app_name/log
networks:
- app_name-network
depends_on:
- db
# ↓ mysqlでDBコンテナを立てるための情報
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_DATABASE: app_name_development
volumes:
- db-data:/var/lib/mysql
networks:
- app_name-network
web:
build:
context: ./nginx_docker_dev
# ↑ 開発環境用に作ったディレクトリでnginxによるコンテナを構築する。
volumes:
- public-data:/app_name/public
- tmp-data:/app_name/tmp
ports:
- 80:80
depends_on:
- app
networks:
- app_name-network
volumes:
public-data:
tmp-data:
log-data:
db-data:
networks:
app_name-network:
external: true
docker-compose-prod.yml
本番環境用のdocker-compose-prod.ymlが以下の通り。開発環境との違いについてはコメントアウトで記載している。
version: '3'
services:
app:
build:
context: .
command: bundle exec puma -C config/puma.rb -e production
# ↑ pumaの起動時に本番環境を指定している。
volumes:
- .:/app_name
- public-data:/app_name/public
- tmp-data:/app_name/tmp
- log-data:/app_name/log
networks:
- app_name-network
# 今回、本番環境について、EC2へのデプロイとRDSの使用を前提としているため、
# 本番環境用ではDBコンテナの記述は無し。
web:
build:
context: ./nginx_docker_prod
# ↑ 本番環境用に作ったディレクトリでnginxによるコンテナを構築する。
volumes:
- public-data:/app_name/public
- tmp-data:/app_name/tmp
ports:
- 80:80
depends_on:
- app
networks:
- app_name-network
volumes:
public-data:
tmp-data:
log-data:
db-data:
networks:
riskbuster-network:
external: true
nginx_docker_dev ディレクトリ
開発用のnginxの構築のためにnginx_docker_devディレクトリを作成する。
このディレクトリには、Dockerfileとnginx.confの二つのファイルを用意する。
内容はそれぞれ以下の通りとする。
- Dockerfile
FROM nginx:1.15.8
RUN rm -f /etc/nginx/conf.d/*
ADD nginx.conf /etc/nginx/conf.d/app_name.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
- nginx.conf
upstream app_name {
server unix:///app_name/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name localhost;
# ↑ nginxの既定のポート番号である80番ポートを指定して、
# server_nameをlocalhostとしている。
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /app_name/public;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @app_name;
keepalive_timeout 5;
location @app_name {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://app_name;
}
}
nginx_docker_prod ディレクトリ
また同様に、本番用のnginxコンテナを構築するためにnginx_docker_prodディレクトリを作成する。このディレクトリにも、Dockerfileとnginx.confの二つのファイルを用意する。
-
Dockerfile
上記のDockerfileの内容と同様。 -
nginx.conf
upstream app_name {
server unix:///app_name/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name ××.×××.×××.×××;
# ↑ EC2の固定IPを指定
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /app_name/public;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @app_name;
keepalive_timeout 5;
location @app_name {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://app_name;
}
}
コンテナの立ち上げ
環境に応じて以下のコマンドを使い分けて実行し、コンテナの構築を行う。
- 開発環境
$ docker-compose build
$ docker-compose up -d
- 本番環境
$ docker-compose -f docker-compose-prod.yml build
$ docker-compose -f docker-compose-prod.yml up -d
以上。
参考