strapiでブログを作る⑤(デプロイ編)
herokuとcloudflareを使ってブログを公開するための設定方法を紹介します。
構成
バックエンドの構成
■サーバー
heroku - dynos (Basic plan)
費用 (上限 $7/月) (Heroku の価格)
■データベース
heroku - postgres
費用 約$0.007/時間(上限 $5/月) (Heroku の価格)
最大$12なので今の$1が155.78 円なので1869.42円となると結構高い。たかが個人ブログにこの金額は結構高い。年間だと22433円もしてしまう。以前herokuは無料だったから、有料になったとはいえ良心的な価格設定に抑えてくれていると思っていたのに...
しかも日本のリージョンを使いたい場合はHeroku Enterpriseにならなくてはならず、そうでない場合はアメリカ(US)かヨーロッパ(EU)しか選ばべなかったです。
それでもなぜHerokuを選んだかというとstrapiのドキュメントの[strapi - Hosting Provider Guides] (https://docs.strapi.io/dev-docs/deployment/hosting-guides)に
- AWS
- Azure
- DigitalOcean
- Heroku
- Strapi Cloud
のホスティングの方法が記載されていたので、これらのプロバイダーが推奨されているのでこちらから選ぼうと思った次第でした。 この中ではHerokuが一番安そうで、使ったこともあったのでHerokuを選択しました。
フロントエンドの構成
■ドメイン Cloudflare Registrar
protagram.comというドメインを取得し
管理画面用の
オブジェクトストレージ用の
というサブドメインも作っています。
費用は年間で**$9.77**でした。
■サーバー
ここにnuxt3で作ったフロント側のコードをデプロイします。
■オブジェクトストレージ
r2はS3互換のオブジェクトストレージなのでawsのS3でも良かったのですが、S3よりも安く、一定の容量までは永年無料な点でこちらを選びました。
また極力少ないプロバイダーで完結したいのでr2があって助かりました。
デプロイ環境構築
今回はherokuとcloudflareという2つのプロバイダを使いデプロイを行います。
バックエンドのデプロイ設定
Herokuへのデプロイ設定
https://docs.strapi.io/dev-docs/deployment/heroku
ドキュメントの通りにやれば大体はできます。
backend編でnpx @strapi-community/dockerize
を実行していれば ./config/env/production/database.ts
のファイルは生成されていると思いますが以下のように書き換えます。
import { parse } from 'pg-connection-string';
const config = parse(process.env.DATABASE_URL);
export default ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: config.host,
port: config.port,
database: config.database,
user: config.user,
password: config.password,
ssl: {
rejectUnauthorized: false
},
},
debug: false,
},
});
後/config/env/production/server.ts
のファイルを作成して以下をコピー
export default ({ env }) => ({
proxy: true,
url: env('MY_HEROKU_URL'), // Sets the public URL of the application.
app: {
keys: env.array('APP_KEYS')
},
});
pgとpg-connection-stringをインストール
npm install pg && npm install pg-connection-string
./.gitignore
に以下の記述を追加
package-lock.json
Herokuの設定
HerokuはCLIがるので、コマンドラインから操作することが可能です。
ただ管理画面からの方が実際どのようになったのかが分かるので個人的には管理画面から操作した方が良い気がしています。
ただどっちにしてもherokuへのデプロイのときに使うのでheroku cliをインストールはしておいた方がいい
■アカウントを作成
まずはHerokuのアカウントを作りログインします。
https://signup.heroku.com/login
※クレジットカードの登録も必要となります。
※Google Authenticatorなどの認証アプリも必要となります。
■heroku cliのインストール
brew tap heroku/brew && brew install heroku
cliでログインする
heroku login
■projectを作成
まずは左上のNEWのボタンからcreate appを選択します。
この時app-nameとregionを選ぶのですが、regionにはUnited StatesとEuropeしかないです涙
cliを使う場合は以下
heroku create
■database作成
管理画面から追加する方法
管理画面のResourceからFind more add-onsのボタンをクリック
Heroku Postgresを追加する。
追加されたHeroku PostgresのリンクをクリックするとDBの使用状況を見ることが出来る。
Heroku PostgresのSettingsのCredentialsのView Credentials…のボタンをクリックすることでDBの情報を見ることが出来る。
cliから追加する方法
cliのコマンドは以下
heroku addons:create heroku-postgresql:<PLAN_NAME>
ここのPLAN_NAMEは適切なPlanを入力する。
今回私は最安のminiをにした。
昔は無料のhobbyというプランがあったのになくなってしまっていた。
https://devcenter.heroku.com/articles/heroku-postgres-plans
heroku config
こちらを実行するとDATABASE_URLをみることが出来る。
ここにDBのusernameとpasswordも含まれているので、それを使えばdbeaverなどを使ってDBを見ることも出来る。
envにDB情報を追加
とりあえずこれを元にenvのDBの以下の情報を適切に書き換えてください。
DATABASE_HOST=ec2-*****.compute-1.amazonaws.com
DATABASE_PORT=5432
DATABASE_NAME=
DATABASE_USERNAME=
DATABASE_PASSWORD=
■envの設定
Config Varsには以下のkeyと値が必要になります。
ADMIN_JWT_SECRET
API_TOKEN_SALT
APP_KEYS
CF_ACCESS_KEY_ID
CF_ACCESS_SECRET
CF_BUCKET
CF_ENDPOINT
CF_PUBLIC_ACCESS_URL
DATABASE_URL
JWT_SECRET
MY_HEROKU_URL
NODE_ENV
これらをCLIで追加する場合は.env.productionにenvの値が書いてある前提で以下のコマンドを実行すると追加される。
heroku config:set APP_KEYS=$(cat .env.production | grep APP_KEYS | cut -d= -f2-)
heroku config:set API_TOKEN_SALT=$(cat .env.production | grep API_TOKEN_SALT | cut -d= -f2)
ここで追加された内容は管理画面のSettingsのConfig VarsのReveal Config Varsというボタンをクリックすると表示されます。
■Buildpacksの設定
settingsのBuildpackのadd buildpackからnodejsを選択
■Domainsの設定
SettingsのDomainsからCloudflareで取得したadmin.protagram.comのサブドメインを設定することで、管理画面のURLをherokuが自動で割り振ってくれたURLからサブドメインに変更することができます。
手順はちょっと忘れたのですが、適当にやっても出来るはずです。
Herokuへデプロイ
heroku cliを使う場合以下のコマンドで自動でHerokuにデプロイされる。
git push heroku HEAD:main
しかし、これで以下のエラーが出た。
Installing binaries
remote: engines.node (package.json): >=18.0.0 <=20.x.x
remote: engines.npm (package.json): >=6.0.0
remote:
remote: Resolving node version >=18.0.0 <=20.x.x...
remote: Downloading and installing node 19.9.0...
remote: Bootstrapping npm >=6.0.0 (replacing 9.6.3)...
remote: npm ERR! code EBADENGINE
remote: npm ERR! engine Unsupported engine
remote: npm ERR! engine Not compatible with your version of node/npm: npm@10.7.0
remote: npm ERR! notsup Not compatible with your version of node/npm: npm@10.7.0
remote: npm ERR! notsup Required: {"node":"^18.17.0 || >=20.5.0"}
remote: npm ERR! notsup Actual: {"npm":"9.6.3","node":"v19.9.0"}
.....
remote: ! Push rejected to protagram.
remote:
To https://git.heroku.com/protagram.git
! [remote rejected] HEAD -> main (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/protagram.git'
package.jsonのnodeのバージョンを指定している場所を修正したら治った。
"engines": {
"node": ">=18.0.0 <=20.x.x",
"npm": ">=9.6.3"
},
これを
"engines": {
"node": "20.11.0",
"npm": ">=9.6.3"
},
こう
node -vでlocalのnodeバージョンを確認して変更した。
これでうまく行った。
■GitHubのpushをトリガーにしてデプロイ
ただGitHubのmainブランチにpushされたのをトリガーにデプロイされるように設定した方が良い。
これは管理画面のDeployから
- Deployment methodでGitHubを選択
- App connected to GitHubでデプロイしたいリポジトリを接続
- Manual deployでブランチを選択
この設定でOKだったはず。
Cloudflareの設定
■サブドメインの設定
DNSの設定は以下のような感じ
www
admin
herokuで設定した管理画面のurlをhttps://admin.protagram.comにするための設定です。
HerokuのsettingsのDomeinsからtargetの情報をコピーしてこちらに貼ります。heroku側でも設定が必要です。
コンテンツ部分はtriangular-bee-xxxxxxxxxxxxx.herokudns.com
みたいな感じのやつです。
protagram.com
これはnuxtで作ったクライアントサイドで使うURLです。
cloudflare pageをを使っているのでそちらと紐づけています。
R2
これは画像などを置くs3のようなオブジェクトストレージ用のURLです。
画像などはhttps://storage.protagram.com/strapi_logo_832de14ba3.jpg
みたいなurlとなります。これもR2で設定が必要です。
R2
オブジェクトストレージの設定を行います。
backend編ではs3の設定方法を説明していたのですが、今回はcloudflare-r2の設定方法を説明します
strapi-provider-cloudflare-r2の設定
https://market.strapi.io/providers/strapi-provider-cloudflare-r2
npm install strapi-provider-cloudflare-r2 --save
.config/plugins.js
に以下のコードを書く
module.exports = ({ env }) => ({
// ...
upload: {
config: {
provider: "strapi-provider-cloudflare-r2",
providerOptions: {
accessKeyId: env("CF_ACCESS_KEY_ID"),
secretAccessKey: env("CF_ACCESS_SECRET"),
/**
* `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`
*/
endpoint: env("CF_ENDPOINT"),
params: {
Bucket: env("CF_BUCKET"),
},
/**
* Set this Option to store the CDN URL of your files and not the R2 endpoint URL in your DB.
* Can be used in Cloudflare R2 with Domain-Access or Public URL: https://pub-<YOUR_PULIC_BUCKET_ID>.r2.dev
* This option is required to upload files larger than 5MB, and is highly recommended to be set.
* Check the cloudflare docs for the setup: https://developers.cloudflare.com/r2/data-access/public-buckets/#enable-public-access-for-your-bucket
*/
cloudflarePublicAccessUrl: env("CF_PUBLIC_ACCESS_URL"),
/**
* Sets if all assets should be uploaded in the root dir regardless the strapi folder.
* It is useful because strapi sets folder names with numbers, not by user's input folder name
* By default it is false
*/
pool: false,
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
},
// ...
});
./config/middlewares.js
に以下を追加
module.exports = ({ env }) => [
// ...
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"connect-src": ["'self'", "https:"],
"img-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
env("CF_PUBLIC_ACCESS_URL") ? env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
],
"media-src": [
"'self'",
"data:",
"blob:",
"market-assets.strapi.io",
env("CF_PUBLIC_ACCESS_URL") ? env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
],
upgradeInsecureRequests: null,
},
},
},
},
// ...
];
.envには以下の値が必要。これは後でcloudflareの設定をする中で値を取得していく事となる。
■R2の設定
バケットを作って設定から以下を設定します。
カスタムドメイン
DNSで作ったstrage.protagram.comを設定する。
r2.dev サブドメイン
⇒ 許可しない
CORSポリシー
許可されたオリジン | 許可されたメソッド | 許可されたヘッダー | |
---|---|---|---|
http://localhost:1337 | GET | 開発用 | |
https://www.protagram.com | GET | クライアント | |
https://protagram-8f5098aac22c.herokuapp.com | GET | 管理画面 |
R2 APIトークンの作成
設定内容なこんな感じ
そしたら
- トークン値
- アクセスキーID
- シークレットアクセスキー
- エンドポイント
表示されるので.envに追加していきます。
CF_PUBLIC_ACCESS_URL=storage.protagram.com
CF_TOKEN=
CF_ACCESS_KEY_ID=
CF_ACCESS_SECRET=
CF_ENDPOINT=
CF_BUCKET=protagram
CloudFlare pagesの設定
カスタム ドメインの設定
protagram.com
設定 ⇒ 環境変数
変数名 | 値 |
---|---|
GTM_ID | GTM-xxxxx |
STRAPI_URL | https://admin.protagram.com |
GTMを使わないのであればGTM_IDは不要
設定 ⇒ ビルド&デプロイ
ビルドの構成のところがちょっと重要
buildしても/distというフォルダは生成されないが/distにする。
WWWのリダイレクト設定
サイドバーのWeb サイトからドメインを選択してルール ⇒ ページルール ⇒ ページルールを作成
以上のように設定します。
※現在ページルールはLegacy
となっているので、今だとリダイレクト ルールを使ったほうが良さそです。
まとめ
一度作った後にブログの記事として書いたので、漏れたミスがあったらすみません。
今回はherokuとcloudfrareを使ってブログを公開したが、herokuの料金がちょっと高いと感じました。
次もしstrapiを使って何かサービスを作ることがあれば規模にもよるが、supabaseとcloudfrare 、もしくはspabaseとverselの組み合わせでドメイン料金くらいで運用したいと思う。
参考サイト
https://hanzochang.com/articles/1#prepare-local-s3
https://docs.strapi.io/dev-docs/deployment/heroku