dokploy-ghcr-deploy について
dokploy-ghcr-deployは、Docker化したGitHubリポジトリのイメージをGHCRに公開し、mainへのプッシュ時にDokployでデプロイするためのスキルです。GitHub Actions、Dokploy、シークレット、手動でのレジストリトークン設定を段階的に案内します。
主な機能
- 01GitHub Actionsの公開ワークフローを準備
- 02DockerイメージをGHCRに公開
- 03Dokploy MCPツールでアプリを設定
- 04ghでGitHubリポジトリのシークレットを設定
- 05GHCRトークンの手動設定を案内
活用シーン
- 01main更新後の自動デプロイを設定
- 02GitHubリポジトリをDokployアプリに接続
- 03GHCRのイメージ公開とアクセスを設定
- 04初回リリース前にデプロイの起動を検証
MCP 対応
このスキルはDokploy MCPサーバーへの接続を必要とし、そのツールでDokployのプロジェクト、アプリ、ドメイン、APIキーを作成・設定します。その後、GitHub ActionsがDokployのデプロイAPIを呼び出します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jeffreyyvdb/ dokploy-ghcr-deploy --skill dokploy-ghcr-deployインストール後、Claude Code で/dokploy-ghcr-deployを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEREADME.mdassets/docker-publish.yml.template詳細
Dokploy + GHCR の自動デプロイ
Docker 化された GitHub リポジトリを、main へのプッシュごとに自動で再デプロイする Dokploy アプリにするための、エンドツーエンドの手順です。ビルドは GitHub Actions で実行し、イメージは GHCR にプッシュします(デフォルトではプライベートです)。ワークフローの最後のステップから REST 呼び出しを行い、Dokploy がイメージを取得して再デプロイします。
この方法を使う理由:
- Docker Hub ではなく GHCR — Docker Hub の無料プランではプライベートリポジトリは 1 つに制限されますが、GHCR ではプライベートパッケージを無制限に利用できます。プッシュ時の認証には組み込みの
GITHUB_TOKENを使うため、ワークフロー側で追加の PAT は不要です。 - レジストリの Webhook ではなく API トリガー — GHCR はプッシュ Webhook を発火しないため、レジストリ側の Webhook(Docker Hub → Dokploy の場合に使える方式)に頼るのではなく、ワークフローから Dokploy の
/api/application.deployに POST します。
フェーズを順番に進めてください。それぞれに明確な完了条件があります。問題がある場合は、次へ進まないでください。
前提条件 — まず確認すること
可能な場合は、これらを並行して目立たないように確認し、問題がある場合にのみユーザーへ伝えてください。
- Dockerfile が存在し、ポートを公開していること。 ファイルを読み込みます。
EXPOSEを検索し、ポート番号を控えてください。Dokploy のドメイン設定で必要になります。Dockerfile がない場合、またはEXPOSEがない場合は、そこで中断してユーザーに確認してください。フレームワークのデフォルト値から作成してはいけません(根拠なく推測することになります)。 .dockerignoreが存在すること。 なければ、最小限のファイル(node_modules、.git、build、dist、テスト、.env*)を追加するかユーザーに提案してください。これは作業を妨げる条件ではありません。ghCLI が認証済みであること。gh auth statusで有効なアカウントが表示される必要があります。認証されていない場合は中断し、まずgh auth loginを実行するようユーザーに依頼してください。- Dokploy MCP が接続されていること。
mcp__dokploy-mcp__user-sessionを呼び出してください。エラーが発生した場合は中断し、続行する前に Dokploy MCP に接続するようユーザーに依頼してください。これがないと、このスキルでは Dokploy 側の作業を実行できません。 - GitHub のリモート。
git remote get-url originを解析してowner/repoを抽出します。イメージパスでは GHCR が大文字を拒否するため、小文字に変換してください。リモートが GitHub 以外の場合、このスキルは適用できないことをユーザーに伝えてください。
ユーザーから収集する情報
これらを 1 回の AskUserQuestion 呼び出しにまとめ、ユーザーが 5 回ではなく 1 回で回答できるようにしてください。括弧内はデフォルト値です。あらかじめ入力し、ユーザーが変更できるようにしてください。
- Dokploy のプロジェクト名(デフォルト:リポジトリ名)
- Dokploy のアプリ名(デフォルト:
web) - 設定するパブリックドメイン(すでに Dokploy ホストに解決される必要があります。
*.example.comのようなワイルドカードがある場合は、<project>.example.comを提案してください) - Dokploy のベース URL(例:
https://dokploy.example.com)— これは推測できないため、必ず尋ねてください APP_ENV=production以外の追加環境変数 — 設定を省略できることを案内してください。後から Dokploy の UI で追加できます。各項目が^[A-Z_][A-Z0-9_]*=に一致することを検証し、application-saveEnvironmentに送信する前に、生の改行を含む値を拒否してください。値に余計な改行があると、別の変数が意図せず注入されるおそれがあります。
フェーズ A — リポジトリの準備
assets/docker-publish.yml.templateから.github/workflows/docker-publish.ymlを作成します。このテンプレートは${{ github.repository }}を使用し、実行時に小文字に変換するため、ほとんどのリポジトリでは変更せずに使えます。通常、何かを置換する必要はありません。- まだフィーチャーブランチにいない場合は作成します(
mainに直接コミットしないでください。シークレットを設定した後、ワークフローを PR とともに一括で反映させるためです)。 - ワークフローをステージングしてコミットします。まだプッシュしないでください。最初のワークフロー実行が、準備の整っていないアプリに対して実行され、デプロイ履歴に失敗が残ることを防ぐため、まず Dokploy と GitHub のシークレットを設定します。
フェーズ B — MCP 経由での Dokploy のセットアップ
順番に実行し、失敗したら中止します。各ツール呼び出しで、次の呼び出しに必要な ID が返されるため、都度控えてください。
- 組織を特定する —
mcp__dokploy-mcp__organization-activeを呼び出し、organizationIdを保存します。 mcp__dokploy-mcp__project-createをnameと短いdescriptionを指定して呼び出します。応答にはprojectIdと、自動作成されるデフォルトのenvironmentId(productionという名前)の両方が含まれるため、両方を保存します。mcp__dokploy-mcp__application-createをname(アプリ名)とenvironmentIdを指定して呼び出します。applicationIdを保存します。アプリはsourceType: "github"で開始し、次に Docker プロバイダーを保存するとdockerに切り替わります。mcp__dokploy-mcp__application-saveDockerProviderを以下の値で呼び出します。applicationIddockerImage: "ghcr.io/<lowercase-owner>/<lowercase-repo>:latest"registryUrl: "ghcr.io"username: "<lowercase-owner>"password: "PAT_PLACEHOLDER"— このスタブにより MCP 呼び出しが有効になり、このまま残します。実際の PAT はフェーズ E でユーザーが Dokploy UI に直接設定するため、この会話を通過することはありません。
mcp__dokploy-mcp__application-saveEnvironmentを以下の値で呼び出します。applicationIdcreateEnvFile: trueenv: "APP_ENV=production\n..."(ユーザーが追加した内容も含めます)buildArgs: ""、buildSecrets: ""—undefinedではなく、明示的に空文字列を指定します。「注意点」を参照してください。
mcp__dokploy-mcp__domain-createを以下の値で呼び出します。applicationIdhost: "<domain-the-user-gave>"port: <port-from-Dockerfile>https: true、certificateType: "letsencrypt"path: "/"、stripPath: false、domainType: "application"
mcp__dokploy-mcp__user-createApiKeyをname: "github-actions-deploy-<repo>"とmetadata: {"organizationId": "<from step 1>"}を指定して呼び出します。keyを保存します。このキーは一度しか表示されません。デフォルトのレート制限は 24 時間あたり 10 リクエストであることをユーザーに伝え、main に頻繁にプッシュする場合は Dokploy UI から上限を引き上げられると案内してください。
フェーズ C — gh 経由で GitHub シークレットを設定する
3 つのシークレットを 1 回の Bash 呼び出しにまとめて設定し、ユーザーの承認を一度で済ませます。
gh secret set DOKPLOY_URL --repo <owner>/<repo> --body "<dokploy-base-url>" && \
gh secret set DOKPLOY_API_KEY --repo <owner>/<repo> --body "<api-key-from-B7>" && \
gh secret set DOKPLOY_APPLICATION_ID --repo <owner>/<repo> --body "<applicationId-from-B3>"
その後、コードをプッシュする前に API のスモークテストを実施します。read -s によりキーが ~/.bash_history に記録されず、最後の unset によりシェルからキーが削除されるため、プロセス環境に残りません。
read -rsp "Paste DOKPLOY_API_KEY (not echoed): " DOKPLOY_API_KEY; echo
DOKPLOY_URL='https://your-dokploy.example.com'
APP_ID='<applicationId from B3>'
DOKPLOY_API_KEY="$DOKPLOY_API_KEY" \
curl -fsS --max-time 30 -o /dev/null -w "%{http_code}\n" \
-X POST "${DOKPLOY_URL%/}/api/application.deploy" \
-H "x-api-key: $DOKPLOY_API_KEY" \
-H "Content-Type: application/json" \
--data "$(jq -cn --arg id "$APP_ID" '{applicationId:$id}')"
unset DOKPLOY_API_KEY
200 が返ることを確認します。それ以外の場合は URL、キー、またはアプリ ID が間違っています。先に進む前に修正してください。まだイメージがプッシュされていないためデプロイは失敗しますが、トリガーは成功するはずです。これにより、認証経路が正しいことを確認できます。
フェーズ D — プッシュして PR を作成する
ブランチをプッシュし、gh pr create で PR を作成します。PR の本文には以下を記載してください。
- 設定が必要な 3 つのシークレット(設定済みであることを確認してください)
- Dokploy アプリの詳細(プロジェクト、アプリ、ドメイン、ポート)
- マージすると初回の実際のデプロイがトリガーされること
フェーズ E — GHCR PAT(唯一の手動ステップ)
GitHub には PAT を発行する API がないため、ユーザーが UI で操作する必要があります。そうでないかのように装ってはいけません。
PAT をこの会話に通してはいけません。 チャット履歴に read:packages PAT が残るのは認証情報の漏えいです。会話の記録は通常サーバー側に保存され、PAT を使えばユーザーが参照できるすべてのプライベートパッケージを取得できます。そのため、ユーザーにはチャットではなく、Dokploy に直接貼り付けてもらいます。ここに貼り付けるよう求めてはいけません。また、実際の値を使って mcp__dokploy-mcp__application-saveDockerProvider を呼び出してもいけません。フェーズ B の手順 4 にある PAT_PLACEHOLDER スタブは、Dokploy UI から直接置き換えます。
ユーザーには次のとおり正確に伝えてください:
- GitHub → Settings → Developer settings → Personal access tokens (classic) → Generate new token → スコープは
read:packagesのみ → 有効期限を90 日に設定(GitHub がマシン認証情報に推奨する最長期間です。「No expiration」は選ばないでください)→ 発行 → トークンをクリップボードにコピーします。- Dokploy → Projects → your project → your app → General → Docker provider → Password フィールドにトークンを貼り付け → Save。
- ここで「saved」と返信します(トークンは送らず、貼り付けないでください)。
「saved」の確認が取れた場合に限り、フェーズ F に進みます。
ローテーションが必要になった場合も、同じ手順に従います。GitHub で失効させ、新しい PAT を発行し、Dokploy UI に貼り付けます。チャットでの手順はありません。
このステップを自動化しない理由:gh CLI のトークンにはデフォルトで read:packages が含まれていません(スコープは通常 repo, read:org, gist, admin:public_key です)。また、gh auth refresh -s read:packages を実行すると、他のすべてのスコープが付いたままのユーザースコープ OAuth トークンが発行されます。これはサービスパスワードとして保存するには権限が多すぎます。read:packages のみにスコープを限定した専用の classic PAT を Dokploy UI から設定するのが、最も適切な方法です。
フェーズ F — 初回デプロイ
- PR をマージする(または
mainにプッシュする)。ワークフローが実行されます。 - Actions タブを確認します。ビルドによって 2 つのタグ(
latestとsha-<short>)がプッシュされ、最後のステップから Dokploy に 2xx が返されるはずです。 - Dokploy → app → Deployments で、新しいデプロイが「Pulling」→「Running」→「Done」と進んだことを確認します。
- ドメインにアクセスします。Dockerfile で指定したポートでアプリが応答するはずです。
Dokploy のデプロイに ghcr.io/v2/ からの「denied: denied」が表示される場合、PAT が間違っているか、有効期限が切れています。フェーズ E に戻ってください。
注意点(苦労して学んだこと)
- MCP の zod ユニオンは
undefinedを拒否します。application-saveDockerProviderではregistryUrl, username, passwordがすべて必要です(省略せず、空文字列または実際の値を渡してください)。application-saveEnvironmentではbuildArgsとbuildSecretsが必要です。""を渡してください。これらを省略すると、内容の分かりにくい検証エラーに時間を取られます。 - GHCR のイメージパスはすべて小文字でなければなりません。 ワークフローテンプレートでは
${IMAGE_NAME,,}によって対応しています。自分で作成する場合は忘れないでください。 - GHCR に Docker Hub の webhook フローを提案してはいけません。 GHCR はプッシュ webhook に対応していません。Dokploy のドキュメントに記載されている webhook フローは Docker Hub の場合のみです。
- Docker Hub の無料プランではプライベートリポジトリは 1 つまでです。 そのため、このスキルではデフォルトで GHCR を使います。Docker Hub に触れるのは、使用しない理由を説明する場合だけにしてください。
- パッケージの公開設定。 GHCR パッケージは初回プッシュ時にソースリポジトリの公開設定を引き継ぎます。プライベートリポジトリならプライベートパッケージになります。追加の API 呼び出しは不要です。リポジトリがパブリックならパッケージもパブリックになることを、ユーザーに一度伝えてください。
- Dokploy API キーのデフォルトのレート制限は 10/24h です。 ほとんどの
push to mainフローでは問題ありません。ユーザーが 1 日に何度もデプロイする場合(例:多くのマージを行うトランクベース開発)は、Dokploy UI で上限を引き上げてください。 gh auth statusのスコープだけでは GHCR からのプルには不十分です。 一般的なghトークンにはrepo, read:org, gist, admin:public_keyが含まれますが、read:packagesは含まれていません。そのため、フェーズ E では CLI トークンを利用できません。APP_ENVを変更してはいけません。 Vercel と Dokploy の両方へのデプロイに対応するコードベースでは、VERCEL_ENVと混同しないよう、APP_ENVを条件分岐に使用していることがよくあります。Dokploy では常にproductionに設定してください。
このスキルで意図的に行わないこと
- 既存の Dokploy アプリのドメインは移行しません。ユーザーが GitHub ソースの Dokploy アプリを置き換える場合は、新しいプロジェクトに新しいアプリを作成するか(既存のアプリに影響を与えず、ダウンタイムなし)、その場で再設定するか(ドメインの切り替えが必要)を確認します。デフォルトでは新しいプロジェクトを選びます。
- あるアプリから別のアプリへ環境変数をコピーしません。一覧表示は問題ありませんが、稼働中の Stripe や DB のシークレットをアプリ間でそのままコピーすると、上書きや二重書き込みのリスクがあります。
- プレビュー環境、ヘルスチェック、レプリカは設定しません。スコープの拡大にあたるため、ユーザーから依頼された場合に追加します。