mcpField
D
dokploy-ghcr-deploy

dokploy-ghcr-deploy

github.com/jeffreyyvdbクラウド・DevOps251 回インストール27 週間前に更新
リポジトリ

dokploy-ghcr-deploy について

dokploy-ghcr-deployは、Docker化したGitHubリポジトリのイメージをGHCRに公開し、mainへのプッシュ時にDokployでデプロイするためのスキルです。GitHub Actions、Dokploy、シークレット、手動でのレジストリトークン設定を段階的に案内します。

主な機能

  1. 01GitHub Actionsの公開ワークフローを準備
  2. 02DockerイメージをGHCRに公開
  3. 03Dokploy MCPツールでアプリを設定
  4. 04ghでGitHubリポジトリのシークレットを設定
  5. 05GHCRトークンの手動設定を案内

活用シーン

  1. 01main更新後の自動デプロイを設定
  2. 02GitHubリポジトリをDokployアプリに接続
  3. 03GHCRのイメージ公開とアクセスを設定
  4. 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 と一緒にインストールされる参考資料やスクリプト。

LICENSE
README.md
assets/
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 します。

フェーズを順番に進めてください。それぞれに明確な完了条件があります。問題がある場合は、次へ進まないでください。

前提条件 — まず確認すること

可能な場合は、これらを並行して目立たないように確認し、問題がある場合にのみユーザーへ伝えてください。

  1. Dockerfile が存在し、ポートを公開していること。 ファイルを読み込みます。EXPOSE を検索し、ポート番号を控えてください。Dokploy のドメイン設定で必要になります。Dockerfile がない場合、または EXPOSE がない場合は、そこで中断してユーザーに確認してください。フレームワークのデフォルト値から作成してはいけません(根拠なく推測することになります)。
  2. .dockerignore が存在すること。 なければ、最小限のファイル(node_modules、.git、build、dist、テスト、.env*)を追加するかユーザーに提案してください。これは作業を妨げる条件ではありません。
  3. gh CLI が認証済みであること。 gh auth status で有効なアカウントが表示される必要があります。認証されていない場合は中断し、まず gh auth login を実行するようユーザーに依頼してください。
  4. Dokploy MCP が接続されていること。 mcp__dokploy-mcp__user-session を呼び出してください。エラーが発生した場合は中断し、続行する前に Dokploy MCP に接続するようユーザーに依頼してください。これがないと、このスキルでは Dokploy 側の作業を実行できません。
  5. 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 — リポジトリの準備

  1. assets/docker-publish.yml.template から .github/workflows/docker-publish.yml を作成します。このテンプレートは ${{ github.repository }} を使用し、実行時に小文字に変換するため、ほとんどのリポジトリでは変更せずに使えます。通常、何かを置換する必要はありません。
  2. まだフィーチャーブランチにいない場合は作成します(main に直接コミットしないでください。シークレットを設定した後、ワークフローを PR とともに一括で反映させるためです)。
  3. ワークフローをステージングしてコミットします。まだプッシュしないでください。最初のワークフロー実行が、準備の整っていないアプリに対して実行され、デプロイ履歴に失敗が残ることを防ぐため、まず Dokploy と GitHub のシークレットを設定します。

フェーズ B — MCP 経由での Dokploy のセットアップ

順番に実行し、失敗したら中止します。各ツール呼び出しで、次の呼び出しに必要な ID が返されるため、都度控えてください。

  1. 組織を特定する — mcp__dokploy-mcp__organization-active を呼び出し、organizationId を保存します。
  2. mcp__dokploy-mcp__project-create を name と短い description を指定して呼び出します。応答には projectId と、自動作成されるデフォルトの environmentId(production という名前)の両方が含まれるため、両方を保存します。
  3. mcp__dokploy-mcp__application-create を name(アプリ名)と environmentId を指定して呼び出します。applicationId を保存します。アプリは sourceType: "github" で開始し、次に Docker プロバイダーを保存すると docker に切り替わります。
  4. mcp__dokploy-mcp__application-saveDockerProvider を以下の値で呼び出します。
    • applicationId
    • dockerImage: "ghcr.io/<lowercase-owner>/<lowercase-repo>:latest"
    • registryUrl: "ghcr.io"
    • username: "<lowercase-owner>"
    • password: "PAT_PLACEHOLDER" — このスタブにより MCP 呼び出しが有効になり、このまま残します。実際の PAT はフェーズ E でユーザーが Dokploy UI に直接設定するため、この会話を通過することはありません。
  5. mcp__dokploy-mcp__application-saveEnvironment を以下の値で呼び出します。
    • applicationId
    • createEnvFile: true
    • env: "APP_ENV=production\n..."(ユーザーが追加した内容も含めます)
    • buildArgs: ""、buildSecrets: "" — undefined ではなく、明示的に空文字列を指定します。「注意点」を参照してください。
  6. mcp__dokploy-mcp__domain-create を以下の値で呼び出します。
    • applicationId
    • host: "<domain-the-user-gave>"
    • port: <port-from-Dockerfile>
    • https: true、certificateType: "letsencrypt"
    • path: "/"、stripPath: false、domainType: "application"
  7. 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 から直接置き換えます。

ユーザーには次のとおり正確に伝えてください:

  1. GitHub → Settings → Developer settings → Personal access tokens (classic) → Generate new token → スコープは read:packages のみ → 有効期限を90 日に設定(GitHub がマシン認証情報に推奨する最長期間です。「No expiration」は選ばないでください)→ 発行 → トークンをクリップボードにコピーします。
  2. Dokploy → Projects → your project → your app → General → Docker provider → Password フィールドにトークンを貼り付け → Save。
  3. ここで「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 — 初回デプロイ

  1. PR をマージする(または main にプッシュする)。ワークフローが実行されます。
  2. Actions タブを確認します。ビルドによって 2 つのタグ(latest と sha-<short>)がプッシュされ、最後のステップから Dokploy に 2xx が返されるはずです。
  3. Dokploy → app → Deployments で、新しいデプロイが「Pulling」→「Running」→「Done」と進んだことを確認します。
  4. ドメインにアクセスします。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 のシークレットをアプリ間でそのままコピーすると、上書きや二重書き込みのリスクがあります。
  • プレビュー環境、ヘルスチェック、レプリカは設定しません。スコープの拡大にあたるため、ユーザーから依頼された場合に追加します。

コメント