LoginSignup
1
1

More than 5 years have passed since last update.

さくらVPS から AWS Elastic Beanstalk + RDS にWebサービスを移転したときにしたこと

Posted at

http://denkinovel.com/ をずっとさくらVPSで動かしていたが、たまになぜか異常にレスポンスが遅い、記憶力の減退からさくらVPSでのサーバーの管理ができなくなってきた、などの理由でAWSに移転した。

AWSをインターンシップでよく使うようになったので、勉強がてら AWS Elastic Beanstalk + RDS の構成にした。

構成

  • Rails v4.2.10
  • Puma v3.11.4
  • PostgreSQL RDS が用意してくれるやつ
  • Ruby 2.5.1-p57

DB dump => restore

VPSの旧サーバーの PostgreSQL に入っていたデータを pg_dump で取ってくる。

$ pg_dump -U myapp -Fc myapp_production > myapp_production_db.dump

で、ダンプしたデータを、 AWS RDS で読み込む。

$ pg_restore -h aaaaaa.bbbbbbbb.us-west-1.rds.amazonaws.com -p 5432 -d myapp_production -U myapp myapp_production_db.dump

このへんは公式ドキュメントを読んだらわかる。 https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Procedural.Importing.html

ただなぜかデータ移行とデプロイ後に (ActionView::Template::Error) "Unknown primary key for table collections in model xxx" のエラーが Rails で発生するようになった。

調べたところ、この人たちが似たような問題を抱えていた。 https://stackoverflow.com/questions/18056162/getting-unknown-primary-key-for-table-while-the-id-is-there

Rails ではデフォルトで primary_key は id のはずなのだが、なぜかそれが設定されていない?

user.rb
class User < ActiveRecord::Base
  self.primary_key = :id

考えるのが面倒になったので、こんな感じに、各 ActiveRecord::Base 継承クラスに self.primary_key = :id と明示的につけたところ、動いた。

デプロイ

Elastic Beanstalk はリポジトリのサイズ512MB までしか扱えない。 Denkinovel はサービスの性質上、大量の画像と音楽ファイルをリポジトリ内に持っていた。このままではデプロイできない!

そこで、 asset_sync を使って手元の開発機 MacBookPro で rake assets:precompile をしてしまうことで assets を S3 にアップロードしたうえで、本番環境のサーバにはアップロードしないようにした。本番環境では assets へのアクセスはすべて S3 (CloudFront を使うので実際はCloudFront)に向くので本番環境に assets がなくても問題ない。ただし、 public/assets/.sprockets-*-manifest.json だけは本番環境にアップロードしておかないといけない。もし public/assets/.sprockets-*-manifest.json がないと production 環境で Rails が asset_url などを変換する際に /assets/xx.jpg などではなく /images/xx.jpg に変換してしまい、ファイルが見つからくなってしまう。

具体的には以下のことをした。

.gitignore で public 内の public/assets/.sprockets-*-manifest.json 以外のファイルをすべて無視する。

public/assets/*
!public/assets/.sprockets-manifest-*.json

app/assets/audios/*
app/assets/images/*

asset_syncを使い、手元で precompile して S3 に assets はすべてアップロードする

$ RAILS_ENV=production bundle exec rake assets:precompile

これで public/assets に画像や音楽ファイルがプリコンパイルされて入るが、 git はそれを管理しない。ただし .sprockets-manifest-*.json だけは git が管理しているので、その差分は git commit する必要がある。

$ git add .
$ git commit

で、 git に .sprockets-manifest-*.json を記録させたあと

$ eb deploy

でデプロイするようにした。

思ったこと

もう Rails 使うのやだ。

1
1
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
1
1