・Rails5.2(Puma)+NginxでのRailsアプリケーション動作方法
・Docker環境設定方法紹介
RailsアプリケーションをNginxで動かす方法の紹介となります。
EC2環境下で同じことやっているため基本的にはEC2環境でやったことと同じことをやるのですが、Dockerが挟まるということを変なふうに捉えてしまいDockerfileのところで詰まってしまいました。
備忘として作成した次第です。
EC2環境下での構築は下記を参照ください。
環境情報
各種バージョンは下記となります。
Ruby:2.6.3
Rails:5.2.1
Puma:3.11(Gemfile記載)
Nginx:1.21.1
Railsアプリケーションはrails newコマンドで作成されたプロジェクトを使っています。
作成したRailsアプリケーションは「/var/www/」直下に配置しています。
ディレクトリ構成
rails_hello
├─docker-compose.yml
├─.devcontainer
│ └─devcontainer.json
├─docker
│ ├─app_rails
│ │ └─Dockerfile
│ └─web_nginx
│ └─Dockerfile
├─nginx
│ default.conf
│ nginx.conf
└─workspace
└─hello
├─config
│ └─puma.rb
└─tmp
└─sockets
└──puma.sock
ディレクトリ構成は上記とおりです。
workspaceディレクトリの中にRailsアプリケーションがあります。
今回Railsアプリケーションは必要なもののみ記載しています。
.devcontainerディレクトリはVSCode Remote Developmentプラグインに必要です。
詳しい使い方は今回省略しますが、別記事でKotlin環境構築を紹介していますので参照ください。
Rails設定
Dockerfile
FROM ruby:2.6.3
RUN apt-get update && apt-get install -y build-essential libpq-dev postgresql-client nodejs
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
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 && \
apt-get update && apt-get install -y yarn
# Node.jsをインストール
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
RUN gem install rails -v 5.2.1
Puma.rb設定
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
# port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
Dockerfileは単純なRubyとRailsとNode.jsのインストールです。
Puma.rbは3行目のPORT部分をコメントアウトしました。
また6行目を追加しました。puma.sockはプロジェクト作成時には無いですが「rails s」コマンドでPumaが立ち上がったときに作られます。
Nginx設定
Dockerfile
FROM nginx:latest
# インクルード用のディレクトリ内を削除
RUN rm -f /etc/nginx/conf.d/*
# ビルド完了後にNginxを起動
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
default.conf設定
# プロキシ先の指定
# Nginxが受け取ったリクエストをバックエンドのpumaに送信
upstream web {
# ソケット通信したいのでpuma.sockを指定
server unix:///var/www/hello/tmp/sockets/puma.sock;
}
server {
listen 80;
# ドメインもしくはIPを指定
server_name localhost:8000;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# ドキュメントルートの指定
root /var/www/hello/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 @hello;
keepalive_timeout 5;
# リバースプロキシ関連の設定
location @hello {
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://web;
}
}
nginx.conf設定
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
DockerfileはRailsのときと同じくNginxのインストールと実行です。
confファイルの削除は後述するconfファイルを毎回コンテナに配置したいので削除しています。
default.conf はPumaとの連携およびドメイン指定が必要です。
Railsアプリケーションのプロジェクトを指定する2箇所はパスに合わせて修正してください。
30行目のproxy_passは3行目のupstreamで指定した名前を設定してください。
nginx.conf は1行目にrootユーザーで参照するよう追加しました。
それ以外の箇所はデフォルト状態のままです。
docker-compose.yml設定
version: "3"
services:
app:
build: ./docker/app_rails
ports:
- "3000:3000"
environment:
- "DATABASE_HOST=db"
- "DATABASE_PORT=5432"
- "DATABASE_USER=postgres"
- "DATABASE_PASSWORD=mysecretpassword1234"
depends_on:
- db
- web
stdin_open: true
tty: true
volumes:
- ./workspace:/var/www
db:
image: postgres:10.1
ports:
- "5432:5432"
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=mysecretpassword1234"
web:
build: ./docker/web_nginx
ports:
- 8080:80
volumes:
- ./workspace:/var/www
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
docker-compose.yml は先程作成したDockerfile2つとデータベースを追加した3つのコンテナを定義しています。
注意すべき点としては、RailsとNginxのVolumesです。
NginxにてRailsのpuma.sockを参照するため、Nginxのコンテナでも見れるようにする必要があるため同じパスを設定しています。
これが無いと502 Bad Gateway が表示され、Nginxのログに「puma.sock failed (2: No such file or directory)」が出力されます。
Dockerコンテナ起動後設定
以上で各種環境の設定は完了です。
docker-compose.ymlファイルのある場所に対して「docker-compose up」コマンドを実行してコンテナを起動してください。
エラー無く、3つのコンテナが起動したらRailsアプリケーションに「bundle install」コマンドを行い、「rails s」コマンドでPumaが立ち上がります。
Nginxと連携されている場合は下記のような値が出力されます。
* Listening on unix:///var/www/hello/tmp/sockets/puma.sock
Pumaも立ち上がった後、default.confファイルの11行目(server_name)で設定したドメインをブラウザに打ち込みRails画面が表示されていることを確認してください。
Rails側に修正がある場合は、都度「rails s」コマンドの切断や接続を行えば反映されます。
最後に
以上でRailsアプリケーションをNginxで動作する方法の紹介となります。
1つ1つは難しく無いですが、やはり組み合わせとなると難易度が跳ね上がりますね。
学習用だとPuma単体で問題無いですがCD/CIを実現するとなるとNginxを使って、良い感じにしたいですね。