Help us understand the problem. What is going on with this article?

nginx + Rails (unicorn) + MySQL 環境を Docker で構築する

こちらの記事をアップデートしたものを、筆者のブログの方で公開しています。こちらの記事は古くなってきているのでこちらを参照ください。

はじめに

まず,本記事では次の図のような構成で nginx + unicorn + MySQL な環境を構築します.リバースプロキシを異なるコンテナ間でやるのがはじめてだったので,とりあえず記事書いて覚え書きにでもしようかなと言うモチベーションです.

docker-compose.png

また,本記事におけるワークディレクトリの構成は以下のようになっています.ファイル名などはこちらを参考にしてください.いくつかのメインではない設定ファイルに関しては,記事が冗長になることを避けて掲載していませんので適宜 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 は以下のように書きます.

docker/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 は以下のように書きます.

docker/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 は空のままにしておきます.

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.0.0'

最後に,config/unicorn.rb として配置する unicorn.rb も用意しておきます.

docker/rails/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 のリポジトリから参照してください.)

docker/mysql/Dockerfile
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 を作ることでコンテナ同士を連携させていきます.

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/
config/database.yml
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 で詰まりました.まあ,何でもできてしまうと大したことではなく...
(不具合,指摘等ありましたら,コメント頂ければ幸いです.)

Why do not you register as a user and use Qiita more conveniently?
  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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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