こちらの記事をアップデートしたものを、Zennで公開しています。こちらの記事は古くなってきているのでこちらを参照ください。
はじめに
まず,本記事では次の図のような構成で nginx + unicorn + MySQL な環境を構築します.リバースプロキシを異なるコンテナ間でやるのがはじめてだったので,とりあえず記事書いて覚え書きにでもしようかなと言うモチベーションです.
また,本記事におけるワークディレクトリの構成は以下のようになっています.ファイル名などはこちらを参考にしてください.いくつかのメインではない設定ファイルに関しては,記事が冗長になることを避けて掲載していませんので適宜 Github のリポジトリを参照してください.
.
├── Gemfile
├── Gemfile.lock
├── docker
│ ├── gitignore
│ ├── mysql
│ │ ├── Dockerfile
│ │ ├── charset.cnf
│ │ └── password.yml
│ ├── nginx
│ │ ├── Dockerfile
│ │ ├── nginx.conf
│ │ └── rails.conf
│ └── rails
│ ├── Dockerfile
│ └── unicorn.rb
└── docker-compose.yml
Github リポジトリは,こちら になっております.
nginx コンテナ
nginx コンテナの Dockerfile は以下のように書きます.
FROM nginx:1.11
RUN apt-get update && \
apt-get install -y apt-utils \
locales && \
sed -i -e 's/# ja_JP.UTF-8/ja_JP.UTF-8/g' /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_TIME C
ADD ./docker/nginx/nginx.conf /etc/nginx/nginx.conf
ADD ./docker/nginx/rails.conf /etc/nginx/conf.d/default.conf
Rails コンテナ
Rails コンテナの Dockerfile は以下のように書きます.
FROM ruby:2.3.0
RUN apt-get update -qq && \
apt-get install -y apt-utils \
build-essential \
libpq-dev \
nodejs \
mysql-client
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install -j4
ADD . /app
EXPOSE 3000
また,Gemfile は以下のように書いておき,Gemfile.lock は空のままにしておきます.
source 'https://rubygems.org'
gem 'rails', '5.0.0'
最後に,config/unicorn.rb として配置する unicorn.rb も用意しておきます.
worker_processes 8
pid "/var/run/unicorn.pid"
listen "/share/unicorn.sock"
stdout_path "./log/unicorn.stdout.log"
stderr_path "./log/unicorn.stderr.log"
MySQL コンテナ
MySQL コンテナの Dockerfile は以下のように書きます.(charset.cnf
の内容は,Github のリポジトリから参照してください.)
FROM mysql:5.7
RUN apt-get update && \
apt-get install -y apt-utils \
locales && \
rm -rf /var/lib/apt/lists/* && \
echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
ADD ./docker/mysql/charset.cnf /etc/mysql/conf.d/charset.cnf
Docker Compose
3 つの主要コンテナの Dockerfile が出揃ったので,docker-compose.yml を作ることでコンテナ同士を連携させていきます.
version: '2'
services:
datastore:
image: busybox
volumes:
- /share
- ./docker/mysql/volumes:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
server:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- '80:80'
volumes_from:
- datastore
depends_on:
- datastore
web:
build:
context: .
dockerfile: ./docker/rails/Dockerfile
command: bundle exec unicorn -p 3000 -c /app/config/unicorn.rb
ports:
- '3000:3000'
volumes:
- .:/app
- /etc/localtime:/etc/localtime:ro
volumes_from:
- datastore
depends_on:
- db
links:
- db
- db:database
- db:mysql
extends:
file: ./docker/mysql/password.yml
service: password
db:
build:
context: .
dockerfile: ./docker/mysql/Dockerfile
ports:
- '3306:3306'
volumes_from:
- datastore
depends_on:
- datastore
extends:
file: ./docker/mysql/password.yml
service: password
ここで,docker/mysql/password.yml
を以下のように書いて作っておきます.
version: '2'
services:
password:
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: hoge
MYSQL_PASSWORD: hogepassword
TZ: "Asia/Tokyo"
各パスワードやユーザ名は,ご自身のものを記入ください.この password.yml にこれらパスワード類を隔離することで docker-compose.yml に直書きしなくて済みます.
ビルドと Rails アプリケーションの作成
docker-compose.yml が用意できたら,docker-compose build
でビルドします.Successfully built ...
と最後に出力されたらビルド成功です.
次に,docker-compose
コマンド経由で rails new
してアプリケーションを作成します.
docker-compose run web rails new . --force --database=mysql --skip-bundle
これによってアプリケーションディレクトリが作られたかと思います.このとき,Gemfile が更新されているので gem 'unicorn'
という行を追加して再度 docker-compose build
します.ただ単に,docker-compose run web bundle install
してもコンテナが終了すると状態は保存されないからです.
次に,事前に作っておいた unicorn.rb
をコピーするのと,config/database.yml
の該当箇所を忘れずに変更します.
cp docker/rails/unicorn.rb config/
default: &default
adapter: mysql2
encoding: utf8
pool: 5
username: root
password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
host: db
socket: /tmp/mysql.sock
最後に,MySQL 上に rake db:create
してデータベースを作れば完了です.
おわりに
ネットワーク関連には疎いので,nginx で詰まりました.まあ,何でもできてしまうと大したことではなく...
(不具合,指摘等ありましたら,コメント頂ければ幸いです.)