👌

Rails(Docker)にNginxを導入する (CI/CDまでの道④)

2022/01/17に公開

はじめに

前回に引き続き、今回はEC2にデプロイチャレンジをしようと思ったのですが、色々調べていたところnginxをつないでデプロイしている記事がかなり多かったため今回はDockerでnginx環境を作成していこうかと思います。

作成に利用するリポジトリはこちらになります。

CI/CDの道シリーズ

環境

  • WSL2 (Ubuntu20.04)
  • Docker 20.10.9
  • docker-compose 1.29.1
  • Git 2.25.1
  • VSCode

NginxのDocker環境の構築

Docker + Rails + Puma + Nginx + MySQL

こちらの記事を参考にします。

まずは、/containers/nginxディレクトリを作成し、Dockerfileを作成します。

/containers/nginx/Dockerfile

containers/nginx/Dockerfile
FROM nginx:alpine

# インクルード用のディレクトリ内を削除
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

次にcontainers/nginxnginx.confを作成します。

/containers/nginx/nginx.conf

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

server {
  listen 80;
  # ドメインもしくはIPを指定
  server_name localhost;

  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;
  }
}

次に/docker-compose.production.ymlを作成します。

docker-compose.production.yml
version: "3.9"
services:
  rails:
    build: .
    container_name: rails
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/myapp
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
      - log-data:/myapp/log
      - /myapp/node_modules
    env_file:
      - .env
    depends_on:
      - db
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker

  webpacker:
    build: .
    volumes:
      - .:/myapp
      - /myapp/node_modules
      - public-data:/myapp/public
    command: ./bin/webpack-dev-server
    environment:
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    ports:
      - "3035:3035"
    user: root

  db:
    image: mysql:8.0.27
    container_name: db
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - db:/var/lib/mysql
  
  web:
    build:
      context: containers/nginx
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80
    depends_on:
      - rails

volumes:
  db:
    driver: local
  bundle:
    driver: local
  public-data:
  tmp-data:
  log-data:

ここではdocker-compose updocker-compose.yml(開発用)を起動、docker-compose -f docker-compose.production.yml updocker-compose.production.yml(本番用)を起動できるようにします。

Nginxを利用するか選べるようにしてみます。(本当に使うかわからないので分けてみました)

webが追加されたのと、railsのマウントやコマンドが変更になっています。

次に/config/puma.rbを以下に変更します。

/config/puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

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

ここで以下のコマンドでコンテナを立ち上げます。(ちなみに失敗します)

$ docker-compose -f docker-compose.production.yml build
$ docker-compose -f docker-compose.production.yml up

起動してlocalhost/testが表示されれば成功です。

また、Nginxなしでも起動できることを確かめます。

$ docker-compose build
$ docker-compose up

localhost:3000/testにアクセスできれば成功です。

おわりに

作成したものはこちらのリポジトリに用意しています。

Nginxの導入は権限問題で困らされました。
あとはRedisを追加すれば必要なコンテナの準備は終わりそうです。

次回こそはEC2のデプロイにチャレンジしていきたいと思います。

参考

GitHubで編集を提案

Discussion