Docker Next.js ローカルデプロイスキル
目的
このスキルは、バージョン管理されたイメージタグを使用して、Next.jsアプリケーションをDockerでビルド・実行するために使用します。
このスキルはプロジェクト名をハードコーディングしてはなりません。ユーザーが特定の名前を指定しない限り、現在のリポジトリからイメージ名を推測します。
プロジェクト名の解決
ビルド前に、以下の値を決定します:
PROJECT_NAME=<解決されたプロジェクト名>
IMAGE_NAME=<解決されたイメージ名>
IMAGE_VERSION=<解決されたバージョン>
IMAGE_TAG=${IMAGE_NAME}:${IMAGE_VERSION}
CONTAINER_NAME=<解決されたコンテナ名>
ENV_FILE=<解決されたenvファイル>
HOST_PORT=<解決されたホストポート>
CONTAINER_PORT=<解決されたコンテナポート>
解決ルール:
-
ユーザーがイメージ名を指定した場合は、それを使用します。
-
それ以外の場合は、
package.jsonを読み込み、nameフィールドを使用します。 -
package.jsonにnameがない場合は、現在のフォルダ名を使用します。 -
イメージ名を正規化します:
- 小文字にする
- スペースとアンダースコアをハイフンに置き換える
- Dockerイメージ名として無効な文字を削除する
-
ユーザーがバージョンを指定した場合は、それを使用します。
-
それ以外の場合は、デフォルトで
1.0.0を使用します。 -
ユーザーがコンテナ名を指定した場合は、それを使用します。
-
それ以外の場合は、正規化されたイメージ名をコンテナ名として使用します。
-
ユーザーがenvファイルを指定した場合は、それを使用します。
-
それ以外の場合は、デフォルトで
.env.productionを使用します。 -
ユーザーがポートを指定した場合は、それらを使用します。
-
それ以外の場合は、デフォルトで
HOST_PORT=4000、CONTAINER_PORT=3000を使用します。
例:
package.json name: nextjs-skill-app-workshop
PROJECT_NAME=nextjs-skill-app-workshop
IMAGE_NAME=nextjs-skill-app-workshop
IMAGE_VERSION=1.0.0
IMAGE_TAG=nextjs-skill-app-workshop:1.0.0
CONTAINER_NAME=nextjs-skill-app-workshop
ENV_FILE=.env.production
HOST_PORT=4000
CONTAINER_PORT=3000
安全ルール
ビルドまたは実行コマンドを実行する前に:
-
現在の作業ディレクトリがプロジェクトルートであることを確認します。
-
Dockerfileが存在することを確認します。 -
envファイルが存在することを確認します。
-
Dockerがインストールされ、実行中であることを確認します。
-
要求されたイメージタグがすでにローカルに存在するか確認します。
-
要求されたコンテナ名がすでに存在するか確認します。
-
envファイルからシークレットを決して出力しないでください。
-
ユーザーが明示的に要求しない限り、
latestタグを使用しないでください。 -
以下のような破壊的なクリーンアップコマンドを実行しないでください:
docker system prunedocker image prunedocker volume prune
-
ユーザーの明示的な確認なしに、既存のコンテナを停止、削除、または置き換えないでください。
-
ユーザーが明確に確認しない限り、既存のバージョンタグを再ビルドしないでください。
事前チェック
以下のチェックを最初に実行します:
pwd
ls -la
test -f package.json && echo "OK: package.json found" || echo "WARN: package.json not found"
test -f Dockerfile && echo "OK: Dockerfile found" || echo "ERROR: Dockerfile not found"
test -f "$ENV_FILE" && echo "OK: env file found: $ENV_FILE" || echo "ERROR: env file not found: $ENV_FILE"
docker --version
docker info >/dev/null && echo "OK: Docker daemon is running" || echo "ERROR: Docker daemon is not running"
Dockerfileがない場合は、処理を停止して問題を報告します。
envファイルがない場合は、処理を停止して問題を報告します。ユーザーが要求しない限り、プレースホルダーenvファイルを作成しないでください。
Dockerデーモンが実行されていない場合は、処理を停止し、ユーザーにDocker DesktopまたはDocker Engineを起動するように指示します。
推奨ヘルパーコマンド
package.jsonからイメージ名を推測するには:
node -p "require('./package.json').name"
package.jsonが存在しないか、nameがない場合は、現在のディレクトリ名を使用します:
basename "$PWD"
プロジェクト名を手動で正規化するには、小文字のケバブケースを使用します。
例:
My Next App -> my-next-app
nextjs_skill_app -> nextjs-skill-app
バージョンタグの確認
ビルド前に、要求されたイメージタグがすでに存在するか確認します:
docker image inspect "$IMAGE_TAG" >/dev/null 2>&1 \
&& echo "EXISTS: $IMAGE_TAG" \
|| echo "AVAILABLE: $IMAGE_TAG"
また、このイメージの既存のローカルバージョンを一覧表示します:
docker images "$IMAGE_NAME" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}"
要求されたイメージタグがすでに存在する場合:
docker buildを実行しないでください。- そのバージョンがすでにローカルに存在することを報告します。
- 次のパッチバージョン(例:1.0.1)を提案します。
- 新しいバージョンを使用するか、同じタグを明示的に再ビルドするかをユーザーに尋ねます。
ユーザーが明確に確認した場合のみ、既存のタグを再ビルドします。
コンテナ名の確認
コンテナを実行する前に、コンテナ名がすでに存在するか確認します:
docker ps -a --filter "name=^/${CONTAINER_NAME}$" \
--format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
同じ名前のコンテナがすでに存在する場合:
- 同じ名前で別のコンテナを実行しないでください。
- 既存のコンテナのステータスを報告します。
- 停止/削除するか、別のコンテナ名を使用するかをユーザーに尋ねます。
- 自動的に削除しないでください。
ビルドコマンド
イメージタグが存在しない場合は、以下を実行します:
docker build -t "$IMAGE_TAG" .
ビルド後、イメージが存在することを確認します:
docker image inspect "$IMAGE_TAG" >/dev/null \
&& echo "OK: image built successfully: $IMAGE_TAG" \
|| echo "ERROR: image not found after build: $IMAGE_TAG"
実行コマンド
イメージが存在し、コンテナ名が使用可能な場合、以下を実行します:
docker run --restart=always -d \
--name "$CONTAINER_NAME" \
--env-file "$ENV_FILE" \
-p "${HOST_PORT}:${CONTAINER_PORT}" \
"$IMAGE_TAG"
実行後の検証
コンテナ実行後、以下で検証します:
docker ps --filter "name=^/${CONTAINER_NAME}$" \
--format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
docker logs --tail=80 "$CONTAINER_NAME"
curl -I "http://localhost:${HOST_PORT}"
期待される結果:
- コンテナステータスが
Upであること。 - ポートマッピングに
${HOST_PORT}->${CONTAINER_PORT}が含まれていること。 - ログに致命的なエラーが表示されないこと。
curl -Iが200、301、302、307、308などのHTTPレスポンスを返すこと。
curlが失敗した場合は、ログを調べて原因を報告します。
一般的な障害対応
イメージタグがすでに存在する
報告:
イメージタグがすでにローカルに存在します:
<IMAGE_TAG>
推奨アクション:
- 新しいパッチバージョン(例:1.0.1)を使用する
- または、同じタグの再ビルドを明示的に確認する
コンテナ名がすでに存在する
報告:
コンテナはすでに存在します:
<CONTAINER_NAME>
停止/削除するか、別のコンテナ名を指定してください。
ポートがすでに使用中
確認:
lsof -i :"$HOST_PORT"
ポートを使用しているプロセスを報告し、HOST_PORTを変更するかユーザーに尋ねます。
envファイルが見つからない
報告:
Envファイルが見つかりませんでした:
<ENV_FILE>
このファイルが存在するまで、--env-fileでコンテナを実行できません。
シークレットを出力したり推測したりしないでください。
Dockerデーモンが実行されていない
報告:
Dockerはインストールされていますが、デーモンが実行されていません。
Docker DesktopまたはDocker Engineを起動してから、事前チェックを再実行してください。
最終レスポンス形式
終了時に、以下を報告します:
結果:
- プロジェクト:<PROJECT_NAME>
- イメージ:<IMAGE_TAG>
- コンテナ:<CONTAINER_NAME>
- Envファイル:<ENV_FILE>
- ポート:http://localhost:<HOST_PORT>
- 再起動ポリシー:always
- 検証:成功/失敗
使用したコマンド:
<重要なコマンドの一覧>
備考:
<警告、既存のイメージ/コンテナの競合、またはフォローアップアクション>
既存のバージョンタグ、envファイルの欠落、既存のコンテナ、Dockerエラー、ポート競合などによりワークフローが停止した場合は、ブロックしている問題と最も安全な次のコマンドを明確に示します。