Next.jsとSentryの連携でSENTRY_AUTH_TOKENをSecret mountで安全に扱う方法
はじめに
Next.jsアプリケーションでエラー監視のためにSentryを導入する際、ソースマップをSentryにアップロードすることで本番環境でのエラーを正確にデバッグできるようになります。しかし、このプロセスにはSENTRY_AUTH_TOKEN
という秘密情報が必要になります。この記事では、DockerのSecret mountを使ってSENTRY_AUTH_TOKEN
を安全に扱う方法を紹介します。
前提知識
- Next.jsの基本的な知識
- Sentryの基本的な理解
- Dockerの基本的な使い方
なぜSecret mountが必要なのか
Sentryにソースマップをアップロードするには、通常以下のように環境変数を設定します:
SENTRY_AUTH_TOKEN=your_auth_token
SENTRY_ORG=your_org
SENTRY_PROJECT=your_project
しかし、このように環境変数をDockerfileに直接記述したり、.env
ファイルに保存したりすると、以下の問題が発生します:
- セキュリティリスク: ビルドイメージ内に秘密情報が残る可能性がある
- 情報漏洩: GitHubなどのリポジトリに誤ってコミットしてしまう危険性
- 柔軟性の欠如: CI/CDパイプラインごとに設定を変更する必要がある
これらの問題を解決するために、DockerのSecret mountが有効です。
Secret mountとは
Secret mountは、ビルド時にのみ秘密情報をコンテナ内で利用可能にする機能です。ビルドが完了すると、その情報は最終イメージには含まれません。これにより、秘密情報の漏洩リスクを大幅に減らすことができます。
実装方法
1. Dockerfileの準備
まず、Next.jsプロジェクトのDockerfileを準備します。以下はNext.js公式リポジトリのwith-docker-multi-env例をベースにした構成です:
# syntax=docker.io/docker/dockerfile:1
FROM node:lts AS base
# 1. Install dependencies only when needed
FROM base AS deps
# libc6-compatはalpineイメージで必要になる場合があります
RUN apk add --no-cache libc6-compat
WORKDIR /app
# パッケージマネージャに応じて依存関係をインストール
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
# 2. ソースコードのビルド
FROM base AS builder
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY . .
# Sentryの設定
ARG SENTRY_ORG
ARG SENTRY_PROJECT
# Sentryのソースマップアップロード用のシークレットマウント
RUN \
SENTRY_AUTH_TOKEN=$(cat /run/secrets/SENTRY_AUTH_TOKEN) \
SENTRY_ORG=${SENTRY_ORG} \
SENTRY_PROJECT=${SENTRY_PROJECT} \
npm run build
# 3. 本番環境のイメージ作成
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY /app/public ./public
# Next.jsの出力トレースを活用してイメージサイズを削減
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY /app/.next/standalone ./
COPY /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]
ここで重要なのは以下の部分です:
RUN \
SENTRY_AUTH_TOKEN=$(cat /run/secrets/SENTRY_AUTH_TOKEN) \
SENTRY_ORG=${SENTRY_ORG} \
SENTRY_PROJECT=${SENTRY_PROJECT} \
npm run build
この記述により、ビルド時にのみSENTRY_AUTH_TOKEN
が利用可能になります。
2. next.config.jsの設定
Next.jsプロジェクトでSentryを使用するには、通常以下のような設定をします:
// next.config.js
const { withSentryConfig } = require('@sentry/nextjs');
const nextConfig = {
// 他の設定...
};
const sentryWebpackPluginOptions = {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
// その他のオプション...
};
module.exports = withSentryConfig(nextConfig, sentryWebpackPluginOptions);
3. Dockerビルドの実行
Secret mountを使用してビルドするには、以下のようにコマンドを実行します:
docker build \
--build-arg SENTRY_ORG=your-org \
--build-arg SENTRY_PROJECT=your-project \
--secret id=SENTRY_AUTH_TOKEN,env=SENTRY_AUTH_TOKEN \
-t my-nextjs-app .
環境変数SENTRY_AUTH_TOKEN
の値がビルド時にのみコンテナ内で利用可能になります。また、SENTRY_ORG
とSENTRY_PROJECT
はビルド引数として渡されます。
4. CI/CDパイプラインでの設定
GitHub ActionsなどのCI/CDパイプラインでも同様に設定できます:
# .github/workflows/build.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: my-registry/my-nextjs-app:latest
build-args: |
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_PROJECT=${{ vars.SENTRY_PROJECT }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
メリット
Secret mountを使用することで得られる主なメリットは次のとおりです:
- セキュリティの向上: 秘密情報が最終イメージに含まれない
- コード管理の簡素化: 秘密情報をコードリポジトリから分離できる
- CI/CDとの統合: 様々なCI/CDシステムでシームレスに動作する
注意点
- BuildKitが有効になっている必要があります(Docker 18.09以降ではデフォルトで有効)
- 明示的に有効化するには以下の方法があります:
- 環境変数で設定:
export DOCKER_BUILDKIT=1
- Docker設定ファイル(
~/.docker/config.json
)で設定:{ "features": { "buildkit": true } }
-
docker build
コマンドに--buildkit
フラグを追加
- 環境変数で設定:
- 詳細はDocker BuildKitのドキュメントを参照してください
- 明示的に有効化するには以下の方法があります:
- ローカル開発時とCI/CDパイプラインでの一貫性を保つことが重要
-
SENTRY_AUTH_TOKEN
は機密情報のため、適切なシークレット管理サービスを使用して保存・管理すべきです- 各CI/CDサービスのシークレット管理機能を活用しましょう:
- クラウドプロバイダのシークレット管理サービスも利用可能です:
- ローカル開発時には
.env.local
ファイルなどを使用し、gitignoreに追加してコミットされないようにしましょう
まとめ
Next.jsとSentryを連携する際に必要となるSENTRY_AUTH_TOKEN
は、DockerのSecret mount機能を使うことで安全に扱うことができます。これにより、セキュリティリスクを低減しながら、効率的なCI/CDパイプラインを構築できます。
もしあなたのプロジェクトでSentryを使用しているなら、ぜひSecret mountの導入を検討してみてください。
Discussion