LoginSignup
23
12

More than 5 years have passed since last update.

AWSでMastodonサーバー立てました chitose.moe

Last updated at Posted at 2017-04-16

スポンサーが1社付いてるのですぐに消えたりはしないはず。
メール送信数制限の都合で1日のユーザー登録数には上限がある。
メールが届かない時は暫く待つか24時間後に再送信。
とはいえ5万なので上限になることはないか。

環境

  • AWS
  • EC2 Container Service
  • ecs-cli
  • RDS(PostgreSQL)
  • ElastiCache(Redis)
  • S3
  • CloudFront
  • ALB
  • SES

やれるだけやって分散した。
いくらでもサーバー増やせるけどたぶんそこまで必要にはならない。

最後SESのsandbox解除待ちで時間かかった…。

途中段階の役に立たないメモ

ローカルで動かすだけならVagrantのほうが早い。
最初から管理者アカウントも作られる。

docker-composeはproduction用。

git clone https://github.com/tootsuite/mastodon
cd mastodon
sudo curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-darwin-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
ecs-cli help
ecs-cli configure -p default --cluster mastodon
ecs-cli up ...
aws ecr get-login
docker login ...
aws ecr create-repository --repository-name mastodon
docker build -t mastodon .
docker tag mastodon:latest ...
docker push ...

docker-compose.ymlを編集
- buildの代わりにimage: mastodon
- DB永続化するためコメントを消す

ecs-cli compose service up

ここで上手く動かなくなった。
Elastic Beanstalkでやろうとしたけどこっちもだめ。
いろいろやってるうちにオリジナルのdocker-compose.ymlが事前に用意したDocker image使うようになってた。
ECS使う方法に戻る…。

assetsを削除して再生成してS3にアップ。
precompileを繰り返すとファイルが増える…?

rm -rf ./public/assets
docker-compose run --rm web rails assets:precompile

aws s3 cp ./public/assets s3://{S3バケット}/assets --recursive --acl public-read --cache-control "max-age=604800"

S3に置くと/public/assets以下がないのでprecompile済みファイルが使われない。
sprockets-manifestが必要。
S3に置くのはやめた。
image: gargron/mastodonは使わず自分でビルドする方法に戻る…。

.dockerignoreを変更してimageにassetsも含まれるように。

#public/assets

docker-compose.ymlをコピーしてaws.ymlを作りこっちを書き換えて行く。
docker-compose.ymlはローカル用に元のまま。
あ、当然gitのブランチは分けてる。

AWSのECSでは

  • buildが使えない
  • volumesで相対パスが使えない

という仕様なのでそれに合わせる。
volumesはよくわからないのでほぼ使わないように…。

ここからも色々苦労したけど細かすぎてもう忘れたのでメモ程度。
AWSのサービスで使えるものは使う。
db,redisはもちろん分離。
S3も当たり前に使う。
nginxは不要だった。nginx使おうとして無駄に混乱…。
ポートマッピングはELB。
httpsへのリダイレクトはCF。

LOCAL_HTTPS=falseでも問題なくhttpsで動くけどメール内のURLだけhttpになる。
リダイレクトされるので妥協。

ecs-cli compose serviceで--load-balancer-name付きで起動だけどうしてもできなかったので諦めた。

/api/v1/streamingはサブドメインにした。
STREAMING_API_BASE_URLで指定すればそれが使われる。
LOCAL_HTTPS=falseだとwebsocketでエラー出てたので無理矢理な対応。

S3_BUCKETS3_HOSTNAMEはS3のドメインそのまま使う用で
自分のサブドメイン使う場合はS3_CLOUDFRONT_HOSTも設定する。
CF使ってるかに関係なく静的ホスティングなら。

nginx使わなくても動いてるけど何か問題あれば後で修正していく。

docker-compose.ymlあるから簡単に動かせるかと思ったけどそんなことはなかった。
EC2上でdocker-compose upすれば簡単だけどそれじゃAWSの意味がない。

ALBの使用

その後調べて分かったので追記。
--load-balancer-nameはClassic Load Balancer用なので違う。
ALBは--target-group-arnを使う。
ただしサービスごとに一つしか設定できないのでサービスを複数作るしかない?

ecs-cli compose -f aws.yml --project-name mastodon-web service create --target-group-arn {web用のターゲットグループ} --container-name web --container-port 3000 --role ecsServiceRole

ecs-cli compose -f aws.yml --project-name mastodon-api service create --target-group-arn {streaming用のターゲットグループ} --container-name streaming --container-port 4000 --role ecsServiceRole

--project-nameの指定も必要になった。

ecs-cli compose -f aws.yml --project-name mastodon-web service up

AutoScalingでEC2インスタンス数を増減。
一つのEC2内で複数のタスクが動くし、タスクもAutoScalingできるようになった。

サービスを分けるならaws.ymlも分割したほうがメモリの無駄もない。

最終版

ごちゃごちゃしたのでまとめ。
最終的にはすっきり。

aws-web.yml

mem_limitは分からないので仮。
portsは動的ポートのために。
"3000"か"0:3000"の書き方。

version: '2'
services:
  web:
    image: {自分のimage}
    env_file: .env.production
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    mem_limit: 536870912
    ports:
      - "3000"

aws-api.yml

version: '2'
services:
  streaming:
    image: {自分のimage}
    env_file: .env.production
    command: npm run start
    mem_limit: 268435456
    ports:
      - "4000"

  sidekiq:
    image: {自分のimage}
    env_file: .env.production
    command: bundle exec sidekiq -q default -q mailers -q pull -q push
    mem_limit: 268435456
    volumes:
      - /var/app/system:/mastodon/public/system

sidekiqのvolumesはどこでもいいので指定しておく。
なにかファイルを書き込めないエラーが出ることがあった。

ALB

ターゲットグループ

  • port3000のweb用
  • port4000のstreaming用

を作る。

リスナーHTTPS 443
ヘルスチェックのポートをトラフィックポートにする。

  • HostがAPI用のサブドメインならstreaming
  • Pathが/ならweb

というルールを設定する。

CloudFrontはこのALBをOriginにする。
/assets以下はキャッシュ強く。他は短めというかなしでいいくらい。

Route53はCloudFrontを指定。
上手く行かないときはCFを外してみる。

今後のためのアップデート手順

masterブランチを最新にしてからマージ。

DB_HOSTはRDSを指定してるのでdb:migrateはローカルから直接行う。
これはどうなんだろうとは思うけど他の方法が分からなかった。

docker-compose build
docker-compose run --rm web rails db:migrate
docker-compose run --rm web rails assets:precompile

docker imageの更新はECRの手順通りに。

aws ecr get-login --region ap-northeast-1 | bash

docker build ...
docker tag ...
docker push ...

後はup。upはymlが変更されてないと以前のタスクのままなのでimageだけ更新した場合は更新されない。
CIで動かしてdocker tagを設定してymlの書き換えまで自動化かな。

ecs-cli compose -f aws-web.yml --project-name mastodon-web service up
ecs-cli compose -f aws-api.yml --project-name mastodon-api service up

動きさえすれば運用段階では楽になる。

23
12
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
23
12