Nginxの導入方法
dockerを使用したrails(apiモード)とnuxt.jsの超簡易的なアプリに、Nginxを導入できたので備忘録と勉強になったポイントのメモです。
誤りのある箇所が多々あるかもしれません。ご了承いただけますと幸いです。
作業ディレクトリ
nginxディレクトリを作成しその中にDockerfile、nginx.confを作成。
(rails用Dockerfileとは別にnginx用Dockerfileを新しく作成する。1コンテナ1プロセスの原則)
Dockerfile
FROM nginx:alpine
# デフォルトで用意されている個別設定ファイルを削除
RUN rm -f /etc/nginx/conf.d/*
# Nginxの設定ファイルをコンテナにコピー
COPY nginx.conf /etc/nginx/nginx.conf
# Nginxをforeground起動
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
EXPOSE 80
メモ
・ベースイメージは軽量化のためalpineを使用。
・COPYコマンド:COPY ホスト内のコピー元 コンテナ内のコピー先
コピー元はDockerfileと同じディレクトリ内に存在しないといけない。
nginx.conf
user nginx;
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
upstream app {
server unix:/app/tmp/sockets/puma.sock; #←コンテナ内のパス
}
server {
listen 80;
server_name localhost;
root /app/public;
client_max_body_size 100m;
location / {
try_files $uri $uri/index.html @app;
}
location @app {
# クライアントのリクエスト情報をpumaに伝える
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# upstream ブロックで定義したサーバーグループを指定
proxy_pass http://app;
}
error_page 404 /404.html;
error_page 505 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location = /404.html {
return 404 "404 NOT FOUND ERROR";
}
location = /v1/healthcheck {
return 200;
break;
}
}
}
puma.rb
max_threads_count = Integer(ENV.fetch("RAILS_MAX_THREADS") { 5 })
min_threads_count = Integer(ENV.fetch("RAILS_MIN_THREADS") { max_threads_count })
threads min_threads_count, max_threads_count
# port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
# nginx ソケット通信設定追加
app_root = File.expand_path('..', __dir__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"
stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
plugin :tmp_restart
メモ
・nginxにより3000ポートを使用しなくなるため、port ENV.fetch("PORT") { 3000 }はコメントアウト。
・ソケット通信のための設定を追加。
・app_root = File.expand_path('..', dir)
→app_rootに現在のファイルのディレクトリの親ディレクトリを代入。
・bind "unix://#{app_root}/tmp/sockets/puma.sock"
→ソケットファイルをbindしてソケット通信する。
(bind "unix://#{Rails.root}/tmp/sockets/puma.sock"と記載してもOKのよう。)
・stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
→標準出力ログ、エラーログの出力先を指定。trueでログを追記、falseで上書き。
docker-compose.yml
version: "3.8"
services:
db:(割愛省略)
api:
build:
context: ./api
args:
WORKDIR: $WORKDIR
environment:
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
API_DOMAIN: "localhost:$FRONT_PORT"
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec puma -C config/puma.rb"
volumes:
- "./api:/$WORKDIR"
- public:/app/public #追加
- tmp:/app/tmp #追加
depends_on:
- db
front:
build:
context: ./front
args:
WORKDIR: $WORKDIR
API_URL: "http://localhost"
command: yarn run dev
volumes:
- "./front:/$WORKDIR"
ports:
- "$FRONT_PORT:3000"
depends_on:
- api
nginx: #追加
build:
context: ./api/nginx
dockerfile: Dockerfile
volumes:
- ./api/nginx/nginx.conf:/etc/nginx/nginx.conf
- public:/app/public
- tmp:/app/tmp
ports:
- "80:80"
depends_on:
- api
volumes: #追加
tmp:
public:
メモ
・nginxの記載を追加。
・apiのポート3000の記載を削除。
・apiのAPI_DOMAINでリクエスト送信元を、frontのAPI_URLでリクエスト送信先を設定しAPI通信を行う。
・apiとnginxのvolumesに以下を追加。また、最下部でtmp、publicを指定。これによりapiとnginx間でファイルを共有できる。
- public:/app/public
- tmp:/app/tmp
Nginx導入にあたり、これまで意味をしっかりと理解できていなかったDockerfile内のCOPYなどのコマンドや、ポート、volumesの理解が深まりました。
大変参考にさせていただいた記事
Discussion