はじめに
前回の記事
でEC2でのDockerの導入について解説しました。
今回はその続きで、EC2でDockerとdocker-composeを用いたEC2上でのDockerコンテナ起動とRailsアプリを手動デプロイしサーバーを起動するための方法やエラー解決などを解説していきます。
前提
① 開発環境でDockerおよびdocker-composeを導入していること
② EC2の初期設定(環境設定)でDockerとdocker-composeをインストールしていること
開発環境
Ruby 2.6.5
Bundler 2.1.4
Rails 6.0.0
MySQL 5.6.50
AWS EC2
EC2上でRailsアプリを起動する
前回まででEC2上でDocker内にDBを作成することができていますので、後は、それを起動してデプロイするだけです。
ただ、ここの起動で自分は結構手こずり8時間くらい起動できずに悶々としてました(笑)
unicornは必須か?
自分の場合EC2のデプロイではunicorn
が必須だと思っていたし、Dockerとunicornでサーバーを起動できている記事もちらほら見かけたので、それで行けると思っていました。
ただ、そこで沼にハマりました。
普通にDBができたのでターミナルで以下を実行。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
このコマンドでサーバーを起動しました。
すると以下の様なエラーが出ました。
ArgumentError: directory for
pid=/var/www/app/tmp/pids/unicorn.pid not writable
最初は権限の問題かなと思ったり、app/tmp/pid
のディレクトリが無いのかと思い以下記事を参考に試行錯誤しました。
以下の記事を参考に作業をしました。
① Unicornエラー(unicorn.pid not writable (ArgumentError))
② 【Capistrano,Unicorn】ArgumentError: directory for pid=/var/www/myapp/current/shared/tmp/pids/unicorn.pid not writableが書き込み権限の問題ではなかった
③ unicorn.pid not writable (ArgumentError)でUnicornが起動できない
が、どれもうまく行かず振り出しに...
だとしたら他に原因は...と考えていたら、「そもそもコンテナ起動するから、わざわざunicornでサーバー起動しなくても良いのでは?」と思い、コンテナを起動。
# コンテナ作成
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose build
# コンテナ内にDB作成
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:create RAILS_ENV=production
# コンテナ内でマイグレーションの実行
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:migrate RAILS_ENV=production
# コンテナを起動
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose up -d
# -dオプションを付けることでバックグラウンドで起動できる
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker ps -a
# statusがupになっているか確認
これでデプロイではず...とhttp://Elastic IP:3000/
にアクセスすると、database_development
がないと怒られました。
database_developmentの作成
自分の場合は特殊なのかどうかわかりませんが、RAILS_ENV=production
で本番環境のDBを作成したからOKと思いきや、開発環境の物も入るとエラーが出たので、以下を入力しました。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:create
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:migrate
エディタの方も記述を少し変えました。
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "4306:3306" #DockerコンテナとSequelpro接続の為に必要な設定
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# volumes の部分を変更
volumes:
- .:/アプリ名
ports:
- "3000:3000"
depends_on:
- db
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "4306:3306" #DockerコンテナとSequelpro接続の為に必要な設定
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# volumes をアプリ名から変更
volumes:
- ./mysql:/var/lib/mysql
ports:
- "3000:3000"
depends_on:
- db
これで保存、更新し、ブラウザ表示すると、今度はまた違ったエラーが出ました。
Webpacker::Manifest::MissingEntryError
「お、エラーが変わったな!」と思い、解決に取り組むが、これが中々難しかった。
どういうエラーかというと「ブラウザがJavaScriptなどを読み込めていない」というエラーです。
そのために、何をするのかというと、ブラウザが読み込めるようにすればアセットコンパイルを行えば良いのですが、ちょっとした確認などが必要でして、、、それにハマりました。
rails s
などででてきた場合は以下の記事を参考にしてみてください。
こちらの記事ではWebpacker周辺のエラー解決の方法を紹介しています。
ということで、アセットコンパイルを実行します
Dockerコンテナでアセットコンパイルの実行
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails assets:precompile RAILS_ENV=production
コンテナ内でもアセットコンパイルを行い、コンテナを起動します。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose up
**http://Elastic IP:3000/**にアクセスすることができたら
成功です。
参考文献
Docker + Rails5.2 + Unicorn + Nginx + capistranoで自動デプロイ