はじめに
Railsアプリとnginxを、docker-composeで管理する方法を紹介します。
イメージは軽量なalpineを使用してしまいます。
この方法では事前にRailsアプリを作り、後からDockerに移す必要があります。
Railsバージョン
- 2.5.2
使用イメージ
- ruby:2.6.2-alpine3.9
- nginx:1.15.8-alpine
ディレクトリ構成
<Railsアプリ>
|- .env
|- Dockerfile
|- docker-compose.yml
|- nginx.conf
|- (Railsアプリの各フォルダー、各ファイル)
各ファイルの中身
envファイル
- データベースの設定や、ポートを環境変数で指定しています。
- Railsアプリ内の設定は環境変数を使用するようにして、envファイルで管理するようにすると良いです。
.env
# Rails
RAILS_ENV=development
RAILS_MASTER_KEY=<マスターキー>
# Database
DATABASE_NAME=hogehoge
DATABASE_HOST=example.com
DATABASE_PORT=5432
DATABASE_USERNAME=user
DATABASE_PASSWORD=password
# nginx
HTTP_PORT=80
データベースの設定
- 環境変数から設定しています。
config/database.yml
# PostgreSQL. Versions 9.1 and up are supported.
#
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
database: <%= ENV['DATABASE_NAME'] %>
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
development:
<<: *default
database: hogehoge_development
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
test:
<<: *default
database: hogehoge_test
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
production:
<<: *default
database: <%= ENV['DATABASE_NAME'] %>
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
Rubyのイメージ
- ホストのユーザのidによっては、railsユーザに権限がない状態になるのでidには注意してください。
Dockerfile
FROM ruby:2.6.2-alpine3.9
ENV TZ=Asia/Tokyo \
RAILS_ENV=development \
RAILS_MASTER_KEY="" \
RAILS_SERVE_STATIC_FILES=false
RUN apk add --no-cache build-base libxml2-dev libxslt-dev tzdata postgresql-dev yarn ca-certificates
RUN mkdir -p /data
WORKDIR data
RUN adduser -D -u 1000 rails
USER rails
CMD tail -f /dev/null
docker-composeの中身
docker-compose.yml
ersion: '3'
services:
rails:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/data/
env_file: .env
entrypoint: sh -c 'bundle install --path vendor/bundle && yarn install && bin/rails s -b 0.0.0.0'
restart: always
nginx:
image: nginx:1.15.8-alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- .:/data/
ports:
- $HTTP_PORT:80
depends_on:
- rails
links:
- rails:puma
restart: always
nginxの設定
- ログはlog/nginx-access.logとlog/nginx-error.logとして出力しています。
- アクセスログのフォーマットはltsv形式にしています。
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format ltsv 'time:$time_iso8601\t'
'remote_addr:$remote_addr\t'
'request_method:$request_method\t'
'request_length:$request_length\t'
'request_uri:$request_uri\t'
'https:$https\t'
'uri:$uri\t'
'query_string:$query_string\t'
'status:$status\t'
'bytes_sent:$bytes_sent\t'
'body_bytes_sent:$body_bytes_sent\t'
'referer:$http_referer\t'
'useragent:$http_user_agent\t'
'forwardedfor:$http_x_forwarded_for\t'
'request_time:$request_time\t'
'upstream_response_time:$upstream_response_time';
access_log /var/log/nginx/access.log ltsv;
sendfile on;
tcp_nopush on;
server_tokens off;
keepalive_timeout 65;
#gzip on;
upstream puma {
server puma:3000;
}
server {
listen 80;
charset utf-8;
access_log /data/log/nginx-access.log ltsv;
error_log /data/log/nginx-error.log;
root /data/public;
try_files $uri/index.html $uri @puma;
# puma
location @puma {
proxy_pass http://puma;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
使い方
起動
$ docker-compose up -d
停止
$ docker-compose down
コンテナに入る
# railsコンテナ
$ docker-compose exec rails sh
# nginxコンテナ
$ docker-compose exec nginx sh
最後に
Railsアプリとalpineをそれぞれalpineベースのイメージで動かし、docker-composeで管理する方法でした。