
Strapi V4をHerokuとS3にデプロイし、安くて自由なHeadlessCMS環境を手に入れる。
本記事ではStrapi v4をherokuにデプロイする流れを説明します。セルフホスティング型の利点を生かし、安価で多機能なHeadlessCMS環境を手に入れましょう。ローカル開発環境の構築方法と、本番環境の構築をガイドします。画像保存のストレージはAWS-S3を利用し、ホスティング先はheroku、記事保存のDBにはPostgreSQLを使用します。
公開日2022.01.27
更新日2022.02.02
はじめに
この記事は、HeadlessCMSであるStrapi(v4)の導入方法をまとめた 技術記事 です。下記の方を想定して記述しています。
目次
目次
対象読者
- HeadlessCMSを使ってサイトを構築したい人。
- HeadlessCMSを毎月「安い」料金で運用したい人。
- Strapi v4の導入の流れを追いたい人。それにより競合のHeadlessCMSと比較しながら、初期導入コストをざっくり見積もりたい人。
- Strapi「V4」の導入に詰まったので、問題解決したい人。V4のドキュメントがアップデートされていなく、困っている。
要求知識
- ターミナル(CUI)が使える。
- herokuの初期設定ができる。
- AWS S3の初期設定ができる。
- Postgresqlまたはそれに類するRDBの設定の知識。
Strapiとは?〜安くて多機能なHeadlessCMS
Strapiはセルフホスティング型のHeadlessCMSです。
HeadlessCMSは初期構築が不要なクラウド型と、自分で初期設定を行うセルフホスティング型の2つに大別でき、Strapiは後者にあたります。
初期導入のコストはかかるものの、月々の支払いはホスティング代のみと安く済みます。競合製品の中も、頭ひとつ抜けた優れたUXと多機能さを持っています。メディアやブログの運用はもちろん、バックエンドサーバーにも使えますので、アプリのプロトタイピングやモデリングにも最適です。
2021年12月にV4へのメジャーアップデートが行われ、より快適なUIや開発環境に一新されました。
💡 補足:クラウド型・セルフホスティング型とは?
- クラウド型HeadlessCMS ノーコードで初期設定ができるものの、ランニングコストが高い。大体5000円/月からのスタート。法人で運用するには手軽な価格帯だが、個人の場合、高い費用に。サービスによってはフリープランがあるができることに制限が。
- セルフホスティング型HeadlessCMS 初期費用のコストと知識が求められるものの、ランニングコストはホスティング料金のみなので、月々の支払いは安く済む。herokuの最安プランであれば$7(1000円程度)。また拡張性も申し分なく、クラウド型の高価格プランに匹敵するオプションを利用できる。
Strapiのランニングコスト
ホスティングにはheroku、画像保存ストレージにはAWS-S3を利用。月10,000PVのアクセスを想定すると、毎月1,000円程度で済む計算です。
利用サービス① heroku
- 合計 70USD(980円)
- コンテナ - Hobby ($7/dyno/月)
- DB(Postgresql) - Hobby Dev Basic (無料)
- 10000行まで無料
- 同時接続20
利用サービス② AWS-S3
- 前提 画像保存量 5GB/月の読取回数 100万回/月の書込回数 1000回
- 合計 0.50USD (70円)
- 毎月の保存金額 0.13 USD(5GB _ 0.025USD/GB )
- 画像読取 0.37 USD (1,000,000回 _ 0.00000037USD/回 )
- 画像書込 0.0047 USD (1000回 * 0.00000037USD/回 )
本記事のゴール
この記事で何を作るのかについて、簡単に概要を説明します
できるようになること
- Dockerを使って、ローカルでStrapiV4の開発(設定)ができる。
- HerokuにStrapiをデプロイする。
- HerokuにStrapiを本番モードで起動する。
- AWS-S3にStrapiのストレージを設定できる。
- StrapiV4でGraphQLを利用できるようにする。
やらないこと
- Strapiに接続するフロントエンドの開発
最終完成図
上記のゴールを満たす最終完成図は下記です。この完成図になるように解説していきます。
ローカル開発環境
- Docker環境
- Strapiコンテナ
- nodeコンテナーをベースに作られている。nodeでstrapiが起動しているコンテナ
- Strapiコンテナ
- Postgresql コンテナ
- Strapiから接続するDBコンテナ
- AWS S3(設置は任意)
- Strapiからアップロードしたメディアを保存する。
- 設置は任意。開発環境で設置しなくてもいいが、本番と近しい環境にしておいた方が何かと便利なので設置。(エラー等があった場合気軽にローカルで検証できるため)
本番環境
- heroku
- Dyno
- heroku PostgreSQL
- AWS S3
必要な事前準備
Dockerのインストール
- https://www.docker.com/products/docker-desktop
- 開発環境の設定に必要です
AWS S3のBucket作成と、アクセス権限の発行
- AWSのS3にアクセスし、開発用のbucketと、本番用のbucketを作成します、
- StrapiからアクセスするIAMを作成します。
- 開発用bucketにアクセスできる、ACCESS_KEYとACCESS_SECRETを控えます。
- 本番用のbucketにアクセスできる、ACCESS_KEYとACCESS_SECRETを控えます。
- 具体的なやり方は下記記事等をご参考ください
Herokuの契約
- https://jp.heroku.com/
- アカウントを作成し、ブラウザでログインしておきます。
ローカル開発環境をつくる
この項目では、ローカル開発環境の構築方法を説明していきます。
Docker-imageを作る
Dockerfileをcloneします。
git clone https://github.com/hanzochang/strapi-v4-dockerfile.git
- ❗注意:これは非公式のDockerfileです 公式がStrapi「v4」に対応したdocker-imageを出していないため、issue等を参考に筆者が改築しました。
docker-imageをビルドします。
docker-compose up
しばらく時間がかかります。パッケージのインストール、ファイル生成、DBのマイグレーションを実施します。
strapiコンテナから上記のような出力がされていれば起動成功です。 止めたい場合は、ctrl + cでストップすることができます。次回以降も、同じコマンドで起動することができます。
ローカル開発環境のStrapiにアクセスします。
http://localhost:1337/admin にアクセスすると管理者ユーザーの登録画面が起動します。ローカルの管理者ユーザーを作成し、ログインをします。最後のチェックボックスをチェックすると、Strapi開発チームからのメールを受け取ることができます。
この登録が完了すると、Strapiのダッシュボードが表示されます。
この画面が表示されれば、無事ローカル開発環境でのStrapiの起動完了です👏
テーブルを作りレコードを追加する
ここまでの操作でローカルでStrapiを起動することができました。
ですが、テーブルやレコードは空です。この状態だと説明に支障があるので、以下の解説でテーブルとレコードの作成を行います。
テーブルを作る
ContentTypeBuilderを使って、テーブルを作ってみましょう。「Create a collection type」から、新しいテーブルを作成することができます。
テーブル作成後は、カラムを追加することができます。カラムに対応した入力インターフェースを設定することができます。カラムにはJSONを選ぶことができたりと、柔軟なテーブル設計を行うことができます。
カラムを設定した後に「save」を押すと、Strapiが再起動し、DBのマイグレーションが反映されます。
最初のデータを入力する
ContentManagerから、データの入力をします。
最後「publish」を押すことを忘れないでください。 後述のGraphQLでの読み出し時に必要です。(publishではないレコードはcollectionの読み出し時に出力されないという仕様があるため)
💬 余談:テーブルを追加した時に何が起こっているのか
Strapi上での変更は、すぐにDBに反映されました。 実際には下記のようなことが起こっています。
DB更新の流れ
- GUIでテーブルの追加をする
- 更新がsrc/配下のファイルが更新される
- strapiが再起動する。再起動が走るタイミングでDBのマイグレーションが走る
- strapiはapp/src/配下の変更をwatchし続けていて変更があれば再起動するようになっている
- DBが更新される。
この流れを利用すると
GUIを使わなくとも、直接src配下のファイルを操作することでDBのマイグレーションを走らせることができます。 GUIを通さず素早くDBを更新したい場合は、ファイルの直接操作をするのも手です。
なお本番では
今回説明したテーブル追加(Content-TypeBuilder)は、本番ではDisableになっています。本番環境ではGUIから直接DBの変更やファイルの変更ができないようになっています。
そのため、開発はローカル環境で行います。
GUIコンソールまたは直接ファイルの編集を行うことで、ファイルを変更し、DBのマイグレーションを進めます。そのソースコードを本番にPUSHし、本番に反映する、というのが開発の流れです。
AWSのS3設定する
メディアファイルをAWS-S3にアップロードできるように設定します。
# app/配下で実行すること
yarn add @strapi/provider-upload-aws-s3
./config/plugins.js にS3の設定値を書き込みます。
module.exports = ({ env }) => ({
upload: {
provider: 'aws-s3',
providerOptions: {
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_ACCESS_SECRET'),
region: env('AWS_REGION'),
params: {
Bucket: env('AWS_BUCKET_NAME'),
},
},
},
})
./config/middlewares.jsに設定値を書き込みます。
module.exports = ({ env }) => [
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', `${env('CDN_BASE_URL')}`],
'media-src': ["'self'", 'data:', 'blob:', `${env('CDN_BASE_URL')}`],
upgradeInsecureRequests: null,
},
},
},
},
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::favicon',
'strapi::public',
]
DockerfileにAWSのKeyを設定します。
version: '3'
services:
strapi:
image: strapi/strapi
environment:
DATABASE_CLIENT: postgres
DATABASE_NAME: strapi
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USERNAME: strapi
DATABASE_PASSWORD: strapi
AWS_ACCESS_KEY_ID: # 開発用BucketにアクセスできるIAMのKEY
AWS_ACCESS_SECRET: # 開発用BucketにアクセスできるIAMのSECRET
AWS_REGION: # AWSのREGION
AWS_BUCKET: # 開発用Bucket名
CDN_BASE_URL: # S3ベースURL 例:https://s3.ap-northeast-1.amazonaws.com/example-example/
動作確認をします。
dockerの再起動をし、アップロードできることを確認します。
# ctrl + cで既存のプロセスを終了後、下記コマンド入力でもう一度起動
docker-compose up
設定が正しいかを確認
ファイルのURLを確認し、正しいURLでアップロードされていることを確認します。
GraphQLを設定する
Strapiにgraphqlをインストールします。 初期状態ではgraphqlでデータを取得できません。 公式の提供するプラグインのインストールが必要です。
@strapi/plugin-graphqlのインストール
docker上でのインストールが必要なので、コンテナに入ります。
docker-compose run strapi bash
コンテナのbashで、下記コマンドを実行します。
yarn add @strapi/plugin-graphql
GraphQLの読取権限の付与
次に、アクセス権限の設定を行います。
初期設定では、外部からの読取書込権限がありませんので、権限を付与します。
Settings>User&Permissions plugin>Roleから、Pluginを選択します。
前述の「データモデルを作る」で作成したモデルを選び、findとfindOneにチェックボックスをオンにし「save」します。
GraphQLの実行をテスト
http://localhost:1337/graphql にアクセスすると、GraphQLのplaygroundが起動します。
autocompleteがききますので、導かれるままにクエリを組み上げていくことで、データを取得することができるようになります。
また、特定のモデルのコレクションを取得したい場合は下記のクエリで取得できます。
クライアントからアクセスするエンドポイント
なおクライアント側からリクエストするエンドポイントも、http://localhost:1337/graphql になります。
以上がローカル開発環境の解説でした。
大きく下記の4点を行いました。
ここまででやったことの復習
- Docker-imageを作り、Strapiを起動する
- 最初のテーブルを作りレコードを追加する
- AWSのS3設定する
- GraphQLを設定する
ローカルで開発をすすめていきましょう
ここまでの流れでローカルで開発を進めることができるようになりました。 自分の作りたいテーブルを追加していき、gitにcommitしていきながら開発を進めていきます。 何の特殊なことはない、通常通りの開発です。
この項目から、ローカルで開発したStrapiをherokuにpushし、本番環境として構築していく方法を解説します。
本番用環境を作る
この項目から、ローカルで開発したStrapiをherokuにpushし、本番環境として構築していく方法を解説します。
herokuのコンテナの用意をする
ブラウザでherokuにログインしておきます。
https://id.heroku.com/login でログインを済ませておきます。
CLIでherokuにログインします。
ローカル開発環境で作成した作業ディレクトリの「app/」に移動し、herokuにログインします。
heroku login
URLが出力されるので、先ほどログインしたブラウザでアクセスします。その後CLIでのログインが完了となります。
herokuのプロジェクトを作成します。
herokuのプロジェクトを作成します。
heroku create あなたのプロジェクト名
https://dashboard.heroku.com/apps/ にアクセスすると、プロジェクトが生成されていることが確認できます。
なおこのタイミングでは料金は発生していません。
herokuでDBの用意をする
herokuにPostgresqlを設置します。
herokuにPostgresqlを設置します。1行ですぐに用意できます。
heroku addons:create heroku-postgresql:hobby-dev
PostgreSQLの設置が成功したかを確認する
設置を確認するには、下記コマンドをリクエストします。
heroku config
ここで、下記のようなパラメータが返却されていれば設置は完了です。
DATABASE_URL: postgres://ebitxebvixeeqd:dc59b16dedb3a1eef84d4999sb4baf@ec2-50-37-231-192.compute-2.amazonaws.com: 5432/d516fp1u21ph7b
herokuに環境変数を設定する
下記の手順で、ConfigVars(環境変数入力フォーム)に移動し、キーと値を入力します。
各種設定値の解説
- AWS_ACCESS_KEY_ID
- 本番用S3へのアクセス権限を持つIAMのKEY_IDを入力します。
- AWS_ACCESS_SECRET
- 本番用S3へのアクセス権限を持つIAMの本番用ACCESS_KEYを入力します。
- AWS_BUCKET
- 本番用S3のバケット名を入力します
- AWS_REGION
- 本番用S3のRegionを入力します。
- CDN_BASE_URL
- S3のベースURLを設定します。
- 例:https://s3.ap-northeast-1.amazonaws.com/example-example/
- DATABASE_URL
- データベースURLが設定されています。
- MY_HEROKU_URL
- 自身がホストするURLを設定します。
- NODE_ENV
- productionと設定します。
Strapiに本番DBの設定をする
本番用のDBの設定をします。「app/src/config/env/production」にdatabase.jsを設置し、下記の内容を書き込みます。herokuの環境変数の「DATABASE_URL」から、各パラメータをパースできる設定にします。
const parse = require('pg-connection-string').parse
const config = parse(process.env.DATABASE_URL)
module.exports = ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: config.host,
port: config.port,
user: config.user,
database: config.database,
password: config.password,
ssl: {
rejectUnauthorized: false,
},
},
debug: false,
},
})
💡 余談:NODE_ENV production専用のconfigファイルを作る
Strapiの環境変数のNODE_ENVをproductionの状態で起動すると、本番モードで起動することができます。
本番モード用のconfigは別に記述することができ、 「app/src/config/env/production」 配下にファイルを設置することでproduction専用のconfigを設定することができます。ここに設置されたconfigを最優先で読み込む処理になります。
本番デプロイ
上記の追加をcommitし
git add .
git commit -m "Update database config"
herokuにpushします。
git push heroku main
push終了後、herokuを開きます。
heroku open
設定の不備等で起動できていない場合があります。その際は下記コマンドでログを確認し、エラーの原因を突き止めて修正します。
heroku logs --tail
GraphQLの公開権限の設定
ローカル環境で設定した公開権限の設定を本番でも行います。 (公開権限の設定は、ファイルではなくDBに保存されるので、ローカルとは別に本番でも設定が必要となります。)
前述の「データモデルを作る」で作成したモデルを選び、findとfindOneにチェックボックスをオンにし「save」します。
production環境で起動した場合、graphqlのplaygroundは立ち上がりません。下記のようにローカルで立ち上げたplayground経由で、graphqlをテストしてください。(他のgraphqlツールでも可)
本番起動時の確認事項
S3にアップロードできるかを確認
S3にメディアファイルをアップロードできているか確認してください。
レコード作成できるかの確認
レコードを作成し、DBに書き込めるかを確認してください。
本番環境の課金について
ここまでの構築で、herokuの料金は発生しません。無料版の場合、herokuのコンテナにアクセスがないと、自動的にスリープモードに入ってしまうので、スリープ状態でユーザーからのアクセスなどが入ると、レスポンスに時間がかかってしまうリスクがあります。
またnext.js等のCDNを持ったクライアントツールを利用する場合、デプロイのビルド時にタイムアウトしてしまうリスク等が発生します。
そういったリスクを避けたい場合は、課金を行うことをおすすめします。herokuのコンテナの課金は$7/月からです。クラウド型のHeadlessCMSに比べても格安ですので検討してみてはいかがでしょうか。またアクセスがPV1万程度であればS3のストレージ料金も数百円くらいに収まる計算なので、かなり安いランニングコストになります。
終わりに
以上がStrapiの本番環境構築手順の解説でした。 StrapiV4は2021年の12月にリリースされたばかりの新しいツールです。公式でもドキュメントや開発ツールの用意が間に合っていないのが現状です。公式の情報最新情報も合わせて確認しましょう。
お問い合わせはこちらから
ご希望に応じて職務経歴書や過去のポートフォリオを提出可能ですので、必要な方はお申し付けください。
また内容とによっては返信ができない場合や、お時間をいただく場合がございます。あらかじめご了承ください。