Skip to content

CreateInstanceOnHeroku

zunda edited this page Apr 15, 2019 · 69 revisions

Herokuにクレジットカードを登録してあるアカウントを持っている場合の手順をまとめてみます。

Heroku CLIとgitコマンドを使ってデプロイする

Herokuアプリの準備

Herokuアプリを作成しassets:precompileに必要なconfig varを設定します。

export HEROKU_APP=<アプリ名>しておくことで、Heroku CLIに-aオプションを渡す必要がなくなります。

export HEROKU_APP=<希望のアプリ名>
heroku create $HEROKU_APP
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-apt
heroku buildpacks:add heroku/nodejs
heroku buildpacks:add heroku/ruby
heroku addons:create heroku-postgresql
heroku addons:create heroku-redis
heroku config:set OTP_SECRET=`ruby -r securerandom -e 'puts SecureRandom.hex(64)'`

アプリケーションログの保存にPapertrailかLogentriesなどのadd-onも付けておくとよいでしょう。

デプロイ

コードをHerokuにデプロイします。

例えばv2.8.0タグを使い、ワーキングコピーではheroku-branchブランチで管理するなら、

VERSION=v2.8.0
git clone https://github.com/tootsuite/mastodon.git
cd mastodon
heroku git:remote
git checkout -b heroku-branch refs/tags/$VERSION
git push heroku heroku-branch:master

git pushコマンドでHerokuへのコードのデプロイとHerokuでのアプリケーションのビルドが行われます。数分かかるのでしばらく待ちます。うまくいかなかった場合には端末にエラーメッセージが表示されているかもしれません。

データベースの初期設定をします。

heroku run rails db:migrate

アプリケーションの設定をします。

LOCAL_DOMAINには、カスタムドメインを利用する場合にはそれを設定します。

heroku config:set \
  HEROKU=true \
  LOCAL_DOMAIN=$HEROKU_APP.herokuapp.com \
  SMTP_FROM_ADDRESS=notifications@localhost \
  SECRET_KEY_BASE=`ruby -r securerandom -e 'puts SecureRandom.hex(64)'` \
  `heroku run rake mastodon:webpush:generate_vapid_key`

ユーザー登録

最初のユーザーをadminとして登録します。初期パスワードは端末に表示されます。

heroku run tootctl accounts create \
  <表示名> \
  --email <メールアドレス> \
  --confirmed \
  --role admin

Dynoをスケールする

heroku ps:scale web=1 worker=1

ここまででMastodonを使ってみることができるはずです。

heroku open

でMastodonを開き、Log inのリンクからログインしてみてください。アップロードされたファイルはDynoの再起動で消えちゃうので注意してください。

うまくいかない時は

アプリケーションのログを見ながらアクセスしてみるとエラーを確認できるかもしれません。

heroku logs -t -a $APP_NAME

追加の設定

ファイルストアの設定

Mastodonはデフォルトではdynoのファイルシステムにアイコンやメディアなどのファイルを格納します。これらのファイルは1日に1度のdynoの再起動の際に消えてしまいます。

Amazon S3のバケットを作成し、そこにファイルを格納するようにします。著者はAWSについて詳しくないので下記の記述には誤りや危険な設定が含まれる可能性があります。気づいたことがあればお知らせください。

バケットの作成

https://aws.amazon.com/ からログインし、AWS Management Consoleに進み、AWS servicesからS3を検索し、クリックして、

  • Create bucketをクリック、
  • bucket nameを設定 (ファイルのダウンロード元のホスト名の一部として使われます)、
  • regionを設定、
  • versioning、logging、tagsを適宜設定、
  • permissionはデフォルト (Ownerのみ読み書き)、

して作成する。

IAMユーザーの作成

まずIAMユーザーに付与する権限を定義します。

https://aws.amazon.com/ からログインし、AWS Management Consoleに進み、AWS servicesからIAMを検索し、クリックして、

  • Policiesをクリック、
  • Create policyをクリック、
  • Create Your Own Policyをクリック、
  • Policy NameとDescriptionを適宜設定、Policy Documentに下記をペースト、
  • Create Policyをクリック
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ]
        }
    ]
}

次にIAMユーザーを作成します。

https://aws.amazon.com/ からログインし、AWS Management Consoleに進み、AWS servicesからIAMを検索し、クリックして、

  • Usersをクリック、
  • Add userをクリック、
  • User nameを設定、
  • Programmatic accessを選択、
  • Attach existing policies directlyを選択、
  • 上記で作成したポリシーを検索して選択、
  • Reviewをクリック、
  • Create userをクリック

Access key IDとSecret access keyが表示されている状態で次に進みます。

アプリケーションの設定

Config varを設定します。S3_HOSTNAMEはリージョンによって異なるかもしれません。下記の例はus-east-1のものです。

$ heroku config:set S3_ENABLED=true
$ heroku config:set S3_BUCKET=<バケット名>
$ heroku config:set AWS_ACCESS_KEY_ID=<作成したIAMユーザーのものをペースト>
$ heroku config:set AWS_SECRET_ACCESS_KEY=<作成したIAMユーザーのものをペースト>
$ heroku config:set S3_REGION=<us-east-1などのリージョン名>
$ heroku config:set S3_PROTOCOL=https
$ heroku config:set S3_HOSTNAME=s3.amazonaws.com

ここまででアイコンやメディアファイルがS3に保存されるようになったはずです。Mastodonから何かアップロードし、AWSのS3のコンソールから確認してみてください。

Pipelinesを使う場合には、slugをビルドするアプリケーションではS3_ENABLEDfalseにしておくと、precompileされたassetはアプリケーションから、稼働中にアップロードされたファイルはS3から利用するようになります。

Bucketterアドオンが利用できるかもしれません。$5/月から。

ソースコードへのリンク

MastodonはAGPLでライセンスされているので、利用者の求めがあればソースコードを提供する必要があります。コードにインスタンス独自の改修をしている場合には、公開レポジトリへのリンクを公開しておくと良いかもしれません。下記のようなイニシャライザを例えばconfig/initializer/source.rbとして追加しておくことで、/about/about/moreで閲覧できるページ下部の「ソースコード」へのリンクが指定したものになります。

# frozen_string_literal: true
module Mastodon
  module Version
    module_function
    def source_base_url
      'https://github.com/<ユーザー名>/mastodon'
    end
  end
end

デプロイ時のコミットハッシュも記録しておく場合には、下記のようなrakeタスクを例えばlib/tasks/version.rakeとして置いておくことで、デプロイ中にイニシャライザを追加できます。

namespace :source do
  desc 'Record source version'
  task :version do
    hash = ENV['SOURCE_VERSION']  # available on Heroku while build
    if hash.blank?
      begin
        hash = `git show --pretty=%H 2>/dev/null`.strip
        # ignore the error: fatal: Not a git repository
      rescue Errno::ENOENT  # git command is not available
      end
    end
    unless hash.blank?
      hash_abb = hash[0..7]
      mastodon_version_to_s = Mastodon::Version.to_s
      File.open('config/initializers/version.rb', 'w') do |f|
        f.write <<~_TEMPLATE
          # frozen_string_literal: true
          module Mastodon
            module Version
              module_function

              def to_s
                "#{mastodon_version_to_s} at #{hash_abb}"
              end
              def source_base_url
                'https://github.com/ユーザー名/mastodon'
              end
              def source_tag
                "#{hash}"
              end
            end
          end
        _TEMPLATE
      end
    end
  end
end

task 'assets:precompile' => ['source:version']

メールの設定

ここではMailgunを使ってみます。

heroku addons:create mailgun
heroku addons:open mailgun

電話番号を入力してアカウントを認証してもらい、一番下のAuthorized RecipientsにMastodonのユーザー登録に利用するメールアドレスを追加し、ベリファイしておく。

Config varを設定する

$ heroku config:set SMTP_FROM_ADDRESS=<メールアドレス> 
$ for v in SMTP_SERVER SMTP_PORT SMTP_LOGIN SMTP_PASSWORD; do
  heroku config:set $v=`heroku config:get MAILGUN_$v`
done

カスタムドメインでの運用

下記のコマンドで、カスタムドメインを使ってアプリケーションにアクセスできるようになります。

heroku domains:add <インスタンスのFQDN>

DNSの設定

インスタンスのFQDNが、CNAMEで、上記のコマンドで表示されたターゲット<インスタンスのFQDN>.herokudns.comを指すように設定する。 トップレベルドメインを使う場合には、ANAMEあるいはALIASレコードにしてください (業者によっては利用できません)。

HTTPSの利用

Automated Certificate Managementを利用する場合には、Hobby以上のdynoを利用する必要があります (dynoの稼働時間に比例した料金がかかります)

heroku ps:type hobby
heroku certs:auto:enable

しばらくして、下記のコマンドがOKを表示するようになれば、HTTPSでのアクセスが可能です。

heroku certs:auto

下記でMastodonがHTTP経由のアクセスをHTTPSにリダイレクトします。自ドメインの設定も直しておく。

heroku config:set LOCAL_HTTPS=true
heroku config:set LOCAL_DOMAIN=<インスタンスのFQDN>

Streaming APIの有効化

Mastodonではブラウザのリアルタイムに近い更新にNode.jsによって実装されているstreaming APIを利用します。上記で作成したアプリケーションではリクエストはRailsが処理しますので、streaming APIが利用できません。下記のように2つめのアプリケーションを作成してリクエストをそちらに送ることで対応できます。(ActionCableを使うようにコードを書き換えられればいいのかな?)

APP_NAME=<上記で作成したアプリ名>
STREAMING_APP_NAME=<上記とは違う、希望のアプリ名>
heroku create $STREAMING_APP_NAME
heroku buildpacks:add heroku/nodejs -a $STREAMING_APP_NAME
heroku addons:attach $APP_NAME::DATABASE --as DATABASE -a $STREAMING_APP_NAME
heroku addons:attach $APP_NAME::REDIS --as REDIS -a $STREAMING_APP_NAME

streaming/index.jsで検出されたCPU数に基づくデフォルトの並列度 7ではFree dynoの512 MBのメモリでは若干足りないようです。ここでは5まで減らしてみます:

heroku config:set STREAMING_CLUSTER_NUM=5 -a $STREAMING_APP_NAME

Mastodonのコードのうち、Procfileを下記のように書き換えて、

web: npm start

レポジトリに登録する。

git add Procfile
git commit -m 'Start streaming service'

このレポジトリを新しく作ったアプリケーションにデプロイする。手元では、ブランチを作成してそこにpushし、GitHub syncでそのブランチからコードをデプロイしています。

Streaming APIに新しく作ったアプリケーションを使うように設定する。

heroku config:set STREAMING_API_BASE_URL=wss://$STREAMING_APP_NAME.herokuapp.com -a $APP_NAME

参考文献

You can’t perform that action at this time.