Dockerを用いたローカル環境にWebサーバー(nginx)を設置

内容

前回既存のRailsアプリにDockerを導入したが、Webサーバーも設置することにしたのでまとめる

現状

ここにwebコンテナ(nginx)を設置する(ちなみにappサーバーはpumaを設置)

手順1 必要なファイルを作成

既存アプリケーションのルートディレクトリにnginx_dockerフォルダを作成し、その配下にDockerfileとnginx.confファイルを作成

手順2 Dockerfileの編集

app用とnginx用のDockerfileを編集(app用は前回のそのまま)
※ここからアプリ名をmyappとして記述している
Dockerfile

FROM ruby:2.6.5
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
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    yarn
WORKDIR /myapp
COPY Gemfile ./Gemfile
COPY Gemfile.lock ./Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /myapp
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]

nginx_docker/Dockerfile

FROM nginx:1.21.3

# インクルード用のディレクトリ内を削除
RUN rm -f /etc/nginx/conf.d/*

# Nginxの設定ファイルをコンテナにコピー
ADD nginx.conf /etc/nginx/conf.d/myapp.conf

# ビルド完了後にNginxを起動
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

手順3 nginxの設定ファイル

nginx.conf

# プロキシ先の指定
# Nginxが受け取ったリクエストをバックエンドのpumaに送信
upstream myapp {
  # ソケット通信したいのでpuma.sockを指定
  server unix:///myapp/tmp/sockets/puma.sock;
}

server {
  listen 80;
  # ドメインもしくはIPを指定
  server_name localhost [or example.com or 192.168.xx.xx];

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;

  # ドキュメントルートの指定
  root /myapp/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 @myapp;
  keepalive_timeout 5;

  # リバースプロキシ関連の設定
  location @myapp {
    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://myapp;
  }
}

手順4 docker-compose.ymlの編集

前回railsコンテナをwebと定義していたがそれをappに変更し、nginxコンテナをwebと定義する
docker-compose.yml

version: '3'
services:
  # Nginxコンテナ定義
  web:
    build:
      context: ./nginx_docker
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80
    depends_on:
      - app
  # Railsコンテナ定義
  app:
    build: .
    command: bundle exec puma -C config/puma.rb
    environment:
      - MYSQL_HOST=${MYSQL_HOST}
      - MYSQL_USERNAME=${MYSQL_USERNAME}
      - MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD}
    volumes:
      - .:/myapp
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
      - log-data:/myapp/log
    depends_on:
      - db
    tty: true
    stdin_open: true
  # MySQLコンテナ定義
  db:
    image: mysql:5.6.51
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
    ports:
      - "4306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  public-data:
  tmp-data:
  log-data:
  mysql-data:

手順5 puma.rbの編集

puma.rbの最下部に以下の記述を追加
bind "unix://#{app_root}/tmp/sockets/puma.sock"の部分は、nginx.confのserverと一致するようにする
config/puma.rb

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

手順6 database.ymlの編集

Railsはデフォルトで、localhost上でDBが動作するようになっているので、hostを先ほど作成したdbに変更
また、ここにおける「MYSQL_USER」と「MYSQL_PASSWORD」はDBファイルで定義した環境変数名を設定
database.yml

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch('MYSQL_USER') { 'root' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

手順7 イメージを作成

docker-compose.ymlで、web・app・dbのbuildに指定されているDockerfileを元にイメージを作成
ターミナル

% docker-compose build

手順8 コンテナを起動

以下のコマンドでコンテナを立ち上げ、コンテナが起動しているのかを確認
ターミナル

% docker-compose up -d
% docker-compose ps

手順9 データベースの作成、マイグレーションファイルの読み込み

最後に以下のコマンドでデータベースの作成とマイグレーションファイルの読み込みをする
ターミナル

% docker-compose exec app rails db:create db:migrate

コンテナの停止・削除をしたい時

以下のコマンドを実行
ターミナル

# 停止したい時
% docker-compose stop

# 停止・削除したい時
% docker-compose down

# volumeも一緒に削除したい時(MySQLのデータもすべて消えるので注意!)
% docker-compose down -v