LoginSignup
0
0

More than 1 year has passed since last update.

Dockerを使用したRailsアプリをAWS(EC2, RDS)からHerokuに移行する

Last updated at Posted at 2022-01-23

AWSの無料枠が使える期限が差し迫っていること、今後は別アプリに力を入れたいのでAWSにアップしているRailsアプリを停止することにしてHerokuに移行することにしました。

AWSからHerokuに移行している参考になりそうな以下の記事があったのですぐできるかと思ったのですが、数日費やすことになってしまったので備忘録としてのこします(全体の流れとしてはとてもわかりやすいです)。
【Rails + MySQL】AWS→herokuの移行 – blog.aiandrox
HerokuにMySQL+NginxのRailsアプリを移管した - kumamotone’s blog

Dockerを使用しない場合でも同じような手順で使える部分があるとは思いますが参考程度に留めていただきますようお願いいたします。

動作環境

  • MacOS
  • Rails(6.0.4.1、gem dotenv-railsを使用して環境変数管理)
  • Ruby(2.7.3)
  • MySQL(5.7系)
  • Docker(20.10.12)
  • docker-compose(2.2.3)

移行に際して関連してくるAWSサービス

  • EC2
  • RDS
  • S3

前提

  • AWS環境にRailsアプリがあること
  • RDSにデータを格納していること(MySQL)
  • Herokuの登録、ログインができていること
  • EC2へSSH接続できること

今回しないこと

  • Heroku, AWSの詳細な説明
  • HerokuにNginxをデプロイ
  • 独自ドメインを使用
  • S3からcloudinaryへの画像の移行

以下のリンクに移行方法が書いてありますが今回は触れません(登録してあるデータ量が少なかったので手作業でやりました)。
Railsで運用しているサービスの画像配信をAWSスタックからCloudinaryに移行した話 | スペースマーケットブログ

手順

1. RDSのデータのバックアップファイルを作成

AWSで動作していた生データをHerokuに移行するためにバックアップファイルを作成します。

1-1. EC2でSSHログイン

RDSに接続するためにEC2にログインします。

Localから
ssh -i "鍵ファイル(aaa.pem)" ec2-user@www.xxx.yyy.zzz

以下を参考にしています
[初心者向け] 初めてのEC2ログイン:Linux編 | DevelopersIO

1-2. RDSデータのバックアップファイルを作成する

EC2上で以下のコマンドを実行します。

EC2上で
mysqldump -u ユーザー名 -h ホスト名 -p データベース名 > dump.sql

dump.sqlのファイル名はお好きな名前で大丈夫です。
ファイルが作成されたこと、どこにファイルがあるかを確認します()。

2. バックアップファイルをlocal(Mac)にコピー

AWSのEC2上からlocalにdump.sqlファイルをコピーするために以下のコマンドを実行します

Localから
scp -i "鍵ファイル(aaa.pem)" ec2-user@www.xxx.yyy.zzz:EC2上のdump.sqlまでのファイルパス localの保存したい場所のパス
#=> 例) scp -i "aws-key.pem" username@1.1.1.1:/var/www/hashlog/dump.sql ~/Desktop 

scpコマンドに関しては以下のリンクがわかりやすいです。
scpコマンドでサーバー上のファイルorディレクトリをローカルに落としてくる - Qiita
sshでファイル転送の手順 - Qiita

以下は実際にEC2からmysqlのバックアップデータを作成、コピーしている記事です。
RDSのdumpファイルを取得してlocalのMySQLに反映させる | すな.dev

3. Herokuにアップロードするための前準備

3-1. Herokuにterminalでログイン、アプリを作成する

以下のリンクを参考にします。
【Rails7】DockerでRuby on Railsアプリを構築してHerokuにデプロイするまで

冒頭の記事を参考にMySQLデータベースはHeroku上ではJawsDBを使用しました。
【Rails + MySQL】AWS→herokuの移行 – blog.aiandrox

local
# heroku-cliのインストール
brew tap heroku/brew && brew install heroku
# herokuのコンテナレジストリにログイン
heroku container:login
# herokuアプリを作成 (アプリ名を引数につければ指定したアプリ名で作成できる)
heroku create

3-2. MySQL用のアドオンを追加

terminal(local)
# MySQL5.7用のアドオンを追加
heroku addons:create jawsdb:kitefin --version=5.7

以下コマンドでアドオンが追加されているか確認できます。

terminal(local)
heroku addons
#=> Add-on                           Plan     Price  State  
#=> ───────────────────────────────  ───────  ─────  ───────
#=> jawsdb (jawsdb-amorphous-40408)  kitefin  free   created
#=>  └─ as JAWSDB

3-3. 必要な環境変数を JAWSDB_URL の値にしたがってHerokuにセットする

3-2でHerokuでMySQL(JawsDB)用のアドオンを追加できたので、Heroku上の環境変数の値を以下のコマンドで確認します。

terminal(local)
heroku config
# 現状だと以下のような感じで表示されるはず(他に値は表示されないはず)
# JawsDBのアドオンが追加できていなければ表示されない
# => JAWSDB_URL=mysql://NEWUSER:NEWPASS@NEWHOST:3306/NEWDATABASE

RailsでMySQLを使用している場合は上記のJAWSDB_URLの値を一部だけ変えなければいけません。
具体的にはmysqlmysql2に変更します。
以下のコマンドでJAWSDB_URLの値を変更できます。
config:setconfig:addでも良いかもしれません。

ちなみに間違えて設定した環境変数の値は、terminalheroku config:unset 環境変数名で削除できます

terminal(local)
heroku config:set JAWSDB_URL=mysql2://NEWUSER:NEWPASS@NEWHOST:3306/NEWDATABASE
terminal(local)
# JAWSDB_URL=mysql://NEWUSER:NEWPASS@NEWHOST:3306/NEWDATABASE を参考にすると
heroku config:set DATABASE_NAME="*************" # NEWDATABASE の値を代入
heroku config:set DATABASE_PASSWORD="****************" # NEWPASS の値を代入
heroku config:set DATABASE_USERNAME="***************" # NEWUSER の値を代入

人によっては以下の値を設定する場合もある感じです。自分の環境に合わせて設定をします。
heroku configファイルの確認が参考になりそうです。

  • LANG
  • RACK_ENV
  • RAILS_ENV
  • RAILS_LOG_TO_STDOUT
  • RAILS_SERVE_STATIC_FILES
  • SECRET_KEY_BASE

3-4. Herokuで使用した環境変数の値をRails側で参照できるようにする

config/database.ymlの各値はHerokuが発行するデータベース用のURLから分割して割り当て、変更する必要があります。

【Rails7】DockerでRuby on Railsアプリを構築してHerokuにデプロイするまで

3-3 まででHerokuの環境変数に値は設定できているのであとはRails側に設定を反映させます。
設定するファイルはconfig/database.ymlです。

config/database.yml
# Heroku configで表示される JAWSDB_URL の値との対応ができているか確認しながら設定
production:
  <<: *default
  database: <%= ENV['DATABASE_NAME'] %>
  username: <%= ENV['DATABASE_USERNAME'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  url: <%= ENV['JAWSDB_URL'] %>

【JAWSDB設定】HerokuでMysqlを使う - Qiita

4. Herokuにアップロード

全然知らなかったのですが、Dockerで作成したRailsアプリをHerokuにデプロイするには以下の2通りのやり方があるようです
どちらもlocalのterminalで何回かコマンドを打ち込む必要があります。

1つ目のデプロイに関しては以下が参考になりそうです。
DockerでRailsの環境構築してHerokuへデプロイする - Qiita

私の場合は2個目のやり方に従いheroku.ymlを作成してデプロイしました。

heroku.yml(使用するDockerfileと同じ階層に配置)
build:
  docker:
    web: Dockerfile.production # 本番用のDockerfile
run:
  web: bundle exec puma -C config/puma.rb

terminalで以下のコマンドを実行してデプロイ

local
# Herokuデプロイ用のブランチを作成
git checkout -b 'heroku_main'
# 変更をcommitする
git add .
git commit -m "Add heroku.yml"
# Herokuのコンテナにスタックをセット
heroku stack:set container
# Herokuにpush
git push heroku heroku_main:main
# DBをdb:migrate
heroku run rails db:migrate
# ブラウザで動作確認
heroku open

5. エラー解決

ただ私の場合、Herokuにアップロードしたあとheroku openコマンドを実行してアプリして動作確認しましたが、以下のエラーが発生してherokuのエラー画面が表示されました。
Webpacker::Manifest::MissingEntryError

以下にかなりいろいろな対処法が記載されていましたが、私の場合は解決に至りませんでした。
herokuへデプロイする際のWebpaker::Manifest::MissingEntryErrorというエラーの対処法まとめ - Qiita

最終的にはlocalでdocker-composeコマンドを使用して以下のコマンドを実行し、

  • rails webpacker:compile
  • rails assets:precompile`

.gitignoreの以下のフォルダの記述を削除してコンパイルされているファイルをgit add, commitして再度4 のやりかたでHerokuへアップすることでアプリが動作するようになりました。

  • /public/assetsフォルダ
  • /public/packsフォルダ

6. バックアップファイルのデータをDB(JawsDB)にインポートする

最後です。
以下のコマンドをlocalのterminalで実行してlocalのバックアップファイルからJawsDBにデータをインポートします。
JawsDB MySQL | Heroku Dev Center

local
mysql -h NEWHOST -u NEWUSER -pNEWPASS NEWDATABASE < dump.sql

注意点ですが、-p の後にスペースは入れずにコマンドを実行してください。エラー扱いになってしまいます(ややこしい)。
Unable To Migrate .SQL File to JawsDb (MySQL) - Stack Overflow

実行完了までしばらく時間がかかります。Warning: Using a password on the command line interface can be insecureが表示されたら正常にコマンドが実行できているはずです。そのまま完了するまで待ちましょう。

7. 完了

heroku openなどで該当アプリにアクセスして期待通りの表示がされていればOKです。
お疲れ様でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0