備忘録兼ねての記事です。
OS: amazon-linux2
前提
EC2インスタンスを作成していて、ターミナル上でssh接続している
(インスタンスやRDSデータベースの作成はこの記事では割愛しますが、たくさんの記事で書かれているのでそこまで難しくないと思います)
ローカル環境のRailsアプリをDockerコンテナ化
webサーバーとしてnginxを配置します。
appサーバーはpumaを設置します。
docker-compose.yml
Dockerfile
nginx_docker
├── Dockerfile
└── nginx.conf
config
└── puma.rb
FROM ruby:3.1.0
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
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get update -qq && apt-get install -y curl build-essential libpq-dev nodejs imagemagick chromium-driver
ENV APP_PATH /myapp
RUN mkdir $APP_PATH
WORKDIR $APP_PATH
COPY Gemfile $APP_PATH/Gemfile
COPY Gemfile.lock $APP_PATH/Gemfile.lock
RUN bundle install
COPY . $APP_PATH
RUN yarn install
EXPOSE 3000
USER root
VOLUME /myapp/public
VOLUME /myapp/tmp
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
CMD /bin/bash -c "rm -f tmp/pids/server.pid && bundle exec rails s"
# nginx:1.22.1 イメージをdocker hubからインストールします。
FROM nginx:1.22.1
# インクルード用のディレクトリ内を削除
RUN rm -f /etc/nginx/conf.d/*
# Nginxの設定ファイルをコンテナにコピー
ADD nginx.conf /etc/nginx/conf.d/movie-review.conf
# ビルド完了後にNginxを起動
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
次はpumaの設定ファイルです。
bind "unix://#{app_root}/tmp/sockets/puma.sock"
の部分は、nginx.conf
のserver
と一致するようにしなければなりません。
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
environment ENV.fetch("RAILS_ENV") { "development" }
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
plugin :tmp_restart
app_root = File.expand_path("..", __dir__)
# nginx.confのserverと一致させる。
bind "unix://#{app_root}/tmp/sockets/puma.sock"
stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
DockerコンテナをAWSにアップロードします。
作成したAWSインスタンスにローカルdockerコンテナをアップロードしていきます。
ngixやpuma、RDSなど接続しなくてはいけないものが多々あります。
EC2にdockerをインストールする
今回はamazon-linux2を使っています。amazon-linux2023だと下記のコマンドで動かないので、別のコマンドにする必要があります。(一応過去の自分の記事でも書いています)
下記はsudoが必要です。
$ amazon-linux-extras install docker -y
systemctl enable docker.service
systemctl start docker.service
curl -SL "https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-$(uname -s|tr [A-Z] [a-z])-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
ついでにgitも入れます
$ sudo yum install git
他にもインストールするものがある場合は、$ sudo yum install ○○
で入れられます。
database.ymlの修正
usernameやpasswordをベタ打ちは良くないので、環境変数を使っています。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV['DB_USER'] %>
password: <%= ENV['MYSQL_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
development:
<<: *default
database: happylunch_development
test:
<<: *default
database: happylunch_test
production:
<<: *default
database: happylunch_production
username: root
password: <%= ENV['happylunch__DATABASE_PASSWORD'] %>
nginx.confの修正
upstream myapp {
server unix:///myapp/tmp/sockets/puma.sock;
}
server {
listen 80;
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.ymlの修正
version: "3"
services:
db:
image: mysql:8.0.31
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql-data:/var/lib/mysql
ports:
- 3306:3306
platform: linux/x86_64/v8
rails:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/myapp
- public-data:/myapp/public
- tmp-data:/myapp/tmp
environment:
TZ: Asia/Tokyo
RAILS_ENV: development
DB_HOST: db
DB_USER: root
MYSQL_PASSWORD: password
ports:
- "3000:3000"
stdin_open: true
tty:
true
depends_on:
- db
web:
build:
context: nginx_docker
volumes:
- public-data:/myapp/public
- tmp-data:/myapp/tmp
ports:
- 80:80
depends_on:
- rails
volumes:
public-data:
mysql-data:
tmp-data:
環境変数を定義する
次に環境変数の値をリモートのdatabase.ymlに書き込みます。
$ cd /movie-review/config
$ vi database.yml
マスターユーザー名とマスターパスワードはRDSの設定
、エンドポイントは接続とセキュリティ
に書かれています(パスワードは伏せ字ですが、忘れてしまった場合はパスワードを変更できます)
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: ******(マスターユーザー名)
password: ******(マスターパスワード)
host: ********ap-northeast-1.rds.amazonaws.com(エンドポイント)
書き換えられたらesc→:wqで保存します。
次にDockerコマンドです。権限がない場合はsudoをつけます。(例:sudo docker-compose build
)
$ cd /movie-review
$ docker-compose build
//コンテナを作成します。
$ docker-compose up
//コンテナを起動します。
下記のように表示されていれば問題なく起動しています。
movie-review-rails-1 | * Listening on unix:///myapp/tmp/sockets/puma.sock
movie-review-rails-1 | Use Ctrl-C to stop
別のターミナルを開きます。
$ cd /movie-review
$ docker-compose exec rails bash
//コンテナの中に入ります。
# bin/rails assets:precompile
//プリコンパイルを実施
# bin/rails db:create
//データベースを作成
# bin/rails db:migrate
//マイグレーションを実行
# bin/rails db:seed
//(必要であれば)
以上で、http://固定IP(パブリックIP)
にアクセスした場合、正しく表示されるはずです。(EC2インスタンスのパブリック IPv4 アドレスをコピーしてブラウザの検索で貼り付ければできます)
参考: