環境構築
構成

初回構築
Vercel
VercelでGitHubリポジトリをインポート
Root Directory:
apps/webを指定Framework Preset: Next.js(自動検出)
Environment Variables に上記の環境変数を設定
Production: 本番用の値を設定
Preview: プレビュー用の値を設定
Deploy
設定項目 |
値 |
|---|---|
Production Branch |
|
Preview |
|
Root Directory |
|
Framework |
Next.js(自動検出) |
変数名 |
用途 |
Production |
Preview |
|---|---|---|---|
|
バックエンドAPI |
|
|
|
サイトURL |
|
|
|
GTM |
|
(空) |
GitHub App (Webhook)
記事リポジトリへのpushで自動的に記事を更新するためのGitHub App設定。
GitHub Settings → Developer settings → GitHub Apps → New GitHub App
設定値:
GitHub App name:
shuntaka-blog-api(任意)Webhook URL:
https://api-endpoint/webhooks/githubWebhook secret: 任意の文字列を生成して設定(後でSSMに登録)
Permissions:
Repository permissions → Contents: Read-only
Subscribe to events: Push
作成後、App IDを控える
Private keyを生成してダウンロード
Webhook secretを控える(SSM登録用)
AWS
SSM Parameter Storeの登録
GitHub App秘密鍵を登録
export STAGE_NAME=""
aws ssm put-parameter \
--name "/${STAGE_NAME}/shuntaka/github-app/private-key" \
--type "SecureString" \
--value "$(cat path/to/private-key.pem)"
GitHub Webhook Secretを登録(署名検証用)
export STAGE_NAME=""
export WEBHOOK_SECRET=$(openssl rand -hex 32)
aws ssm put-parameter \
--name "/${STAGE_NAME}/shuntaka/github-webhook/secret" \
--type "SecureString" \
--value "${WEBHOOK_SECRET}"
# GitHub App設定画面で同じ値を設定
echo "GitHub Appに設定するSecret: ${WEBHOOK_SECRET}"
Cloudinaryの設定(OGP画像生成用)
Cloudinaryでアカウント作成
Dashboard から Cloud name, API Key, API Secret を取得
SSM Parameter Storeに登録
export STAGE_NAME=""
aws ssm put-parameter \
--name "/${STAGE_NAME}/shuntaka/cloudinary/api-secret" \
--type "SecureString" \
--value "your-api-secret"
OIDCプロバイダーの作成
アカウントに1つのみ作成(初回のみ)。
export STAGE_NAME=""
# stageNameはこのスタックでは使用しないが、getConfig()の実行に必要
bunx dotenv -- cdk deploy \
-c stageName=${STAGE_NAME} \
st-oidc-provider \
--require-approval never
GitHub Actions用のデプロイロールの作成
export STAGE_NAME=""
bunx dotenv -- cdk deploy \
-c stageName=${STAGE_NAME} \
${STAGE_NAME:0:1}-st-deploy-role \
--require-approval never
ホストゾーンの作成
export STAGE_NAME=""
export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query "Account" --output text)
bunx dotenv -- cdk deploy \
-c stageName=${STAGE_NAME} \
${STAGE_NAME:0:1}-st-global-dns \
--require-approval never
Route53にNSレコードを登録
AWSのRoute53からホストゾーンのNSレコードを確認し、ムームードメインのコンソール画面のNSレコードを変更
証明書の作成
export STAGE_NAME=""
bunx dotenv -- cdk deploy \
-c stageName=${STAGE_NAME} \
${STAGE_NAME:0:1}-st-tokyo-cert \
--require-approval never
# デプロイ中にAWSコンソール ap-northeast-1 リージョンのACMで、*.shuntaka.techドメインのDNS検証レコードをRoute53に追加
GitHu ActionsにEnvironmentを登録
ghコマンドで環境変数を設定(実際のシークレットはSSM Parameter Storeに格納):
Note: Webフロントエンド(Next.js)の環境変数はVercelダッシュボードで設定します。Vercelセクションを参照してください。
# 設定値(環境に応じて変更)
export STAGE_NAME=""
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
export GH_APP_ID=123456
export CLOUDINARY_CLOUD_NAME=your-cloud-name
export CLOUDINARY_API_KEY=123456789012345
# GitHub Environmentの作成(初回のみ)
gh api --method PUT repos/shuntaka9576/shuntaka-dev/environments/${STAGE_NAME}
# GitHub Actions 用(CDKデプロイで使用)
gh secret set AWS_ACCOUNT_ID --env ${STAGE_NAME} --body "${AWS_ACCOUNT_ID}"
# Lambda 環境変数用(CDK経由でLambdaに設定)
gh secret set GH_APP_ID --env ${STAGE_NAME} --body "${GH_APP_ID}"
gh variable set GH_APP_SECRET_PEM_KEY_NAME --env ${STAGE_NAME} --body "/${STAGE_NAME}/shuntaka/github-app/private-key"
gh variable set GH_WEBHOOK_SECRET_KEY_NAME --env ${STAGE_NAME} --body "/${STAGE_NAME}/shuntaka/github-webhook/secret"
gh secret set CLOUDINARY_CLOUD_NAME --env ${STAGE_NAME} --body "${CLOUDINARY_CLOUD_NAME}"
gh secret set CLOUDINARY_API_KEY --env ${STAGE_NAME} --body "${CLOUDINARY_API_KEY}"
gh variable set CLOUDINARY_API_SECRET_KEY_NAME --env ${STAGE_NAME} --body "/${STAGE_NAME}/shuntaka/cloudinary/api-secret"
usersテーブルにinstallation_idを登録。GitHub Appをリポジトリにインストール後、installation_idを確認して登録。
-- installation_idの確認方法:
-- GitHub App設定画面 → Install App → インストール済みリポジトリをクリック
-- URLの末尾の数字がinstallation_id (例: /installations/12345678)
UPDATE app.users
SET github_installation_id = 12345678
WHERE name = 'shuntaka';
メインスタックのデプロイ
export STAGE_NAME=""
bunx dotenv -- cdk deploy \
-c stageName=${STAGE_NAME} \
${STAGE_NAME:0:1}-st-main \
--require-approval never
完了したら、VercelとRoute53にAレコードの紐付けをしてください。
DBマイグレーション
export STAGE_NAME=""
cd tools/dsql-cli
export DSQL_CLUSTER_ENDPOINT=$(aws ssm get-parameter \
--name "/${STAGE_NAME}/shuntaka/dsql/cluster-endpoint" \
--query "Parameter.Value" --output text)
bun run convert --input ../../.legacy/dynamo/backup_prd-Article_20251229-083009.jsonl
# 既存のデータを削除する場合
# bun run drop --endpoint postgresql://postgres:postgres@localhost:5433/postgres
bun run migrate --endpoint $DSQL_CLUSTER_ENDPOINT
Renovate
依存関係の自動アップデートPRを作成するためのRenovate設定。
https://github.com/apps/renovate にアクセス
「Install」をクリック
対象リポジトリ(shuntaka9576/shuntaka-dev)を選択してインストール
リポジトリルートの
renovate.jsonが自動で読み込まれる
ローカル開発
本リポジトリはbare clone + git worktree構成で管理している。worktreeの管理にはWorktrunkを使用する。
shuntaka-dev/ # bare clone
├── .bare/ # git bare repository
├── .envrc # 共通環境変数(秘匿情報等)
├── preview/ # メインworktree(previewブランチ)
├── feature-foo/ # 作業worktree(wt switchで自動作成)
└── fix-bar/ # 作業worktree
初回セットアップ
lefthook
bare clone環境ではcore.hooksPathが不正なパスを指している場合がある。lefthookがworktreeで動作しない場合は以下を実行する(リポジトリに対して一度だけ)。
git config --local --unset core.hooksPath
previewワークツリーの環境変数
previewはWorktrunkのpre-startフックの対象外のため、初回のみ手動で.env.localと.envrcを作成する。
cat > .env.local <<'EOF'
WEB_PORT=3000
API_PORT=8080
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:8080
PORT=8080
DOCS_PORT=8000
EOF
cat > .envrc <<'EOF'
source_up
dotenv .env.local
EOF
direnv allow .
開発サーバーの起動
# 依存関係のインストール
bun install
# PostgreSQL起動(全worktreeで共有)
docker compose up -d postgres
# DBマイグレーション(初回のみ)
cd tools/dsql-cli
bun run migrate --endpoint postgresql://postgres:postgres@localhost:5433/postgres
cd ../..
# dev server起動(Next.js + Rust API + Sphinx)
bun run dev
ブランチ作業
wt switch --createで新しいworktreeを作成する。pre-startフックにより.env.local(ポート設定)、.envrc、依存関係のインストールが自動で行われる。
# worktree作成&切り替え
wt switch --create feature/new-thing
# dev server起動
bun run dev
初回のみフック承認が求められるのでyで承認する。承認は~/.config/worktrunk/approvals.tomlに保存され、次回以降は自動実行される。
▲ shuntaka-dev needs approval to execute 4 commands:
○ pre-start env: ...
○ pre-start envrc: ...
○ pre-start copy: ...
○ pre-start install: ...
❯ Allow and remember? [y/N] y
その他の操作。
# 既存worktreeに切り替え
wt switch preview
# worktree一覧(URLも表示)
wt list
# worktreeの削除
wt remove feature/new-thing
# previewブランチへマージ&削除
wt merge
ポートマッピング
複数worktreeのdev serverを同時に起動できるよう、worktreeごとにポートが自動割り当てされる。.config/wt.tomlのpre-startフックにより、wt switch --create時に.env.localと.envrcが自動生成される。
変数 |
内容 |
preview(既定) |
|---|---|---|
|
Next.js devサーバーポート |
3000 |
|
Rust APIポート |
8080 |
|
Sphinxドキュメントポート |
8000 |
|
フロントエンドURL |
|
|
API URL |
|
新規worktreeではブランチ名から10000-19999の範囲でポートが決定的に生成される。同じブランチ名なら常に同じポートになる。
ツール
psql接続(DSQL)
SSMからエンドポイントを取得してDSQLに接続する方法。
export STAGE_NAME=""
# SSMからDSQLエンドポイントを取得
HOST=$(aws ssm get-parameter \
--name "/${STAGE_NAME}/shuntaka/dsql/cluster-endpoint" \
--query "Parameter.Value" --output text)
# 認証トークンを生成
TOKEN=$(aws dsql generate-db-connect-admin-auth-token \
--hostname "$HOST" \
--region ap-northeast-1)
# psqlで接続(トークンをパスワードとして使用)
PGPASSWORD="$TOKEN" psql \
--dbname postgres \
--username admin \
--host "$HOST" \
--port 5432
dsql-cli
PostgreSQLを起動
# ルートディレクトリで
docker compose up -d postgres
マイグレーション実行
cd tools/dsql-cli
# ローカル
bun run migrate --endpoint postgresql://postgres:postgres@localhost:5433/postgres
# DSQL
export STAGE_NAME=""
export DSQL_CLUSTER_ENDPOINT=$(aws ssm get-parameter \
--name "/${STAGE_NAME}/shuntaka/dsql/cluster-endpoint" \
--query "Parameter.Value" --output text)
bun run migrate --endpoint $DSQL_CLUSTER_ENDPOINT
スキーマ削除
cd tools/dsql-cli
# ローカル
bun run drop --endpoint postgresql://postgres:postgres@localhost:5433/postgres
# DSQL
bun run drop --endpoint $DSQL_CLUSTER_ENDPOINT
DynamoDB→DSQLデータ変換
cd tools/dsql-cli
# 本番データを変換(99_seed_data.sqlを生成)
bun run convert --input ../../.legacy/dynamo/backup_prd-Article_20251229-083009.jsonl
# ローカルDBに投入
bun run drop --endpoint postgresql://postgres:postgres@localhost:5433/postgres
bun run migrate --endpoint postgresql://postgres:postgres@localhost:5433/postgres
# DSQLに投入
bun run drop --endpoint $DSQL_CLUSTER_ENDPOINT
bun run migrate --endpoint $DSQL_CLUSTER_ENDPOINT