Registry authentication for Compose services (project-scoped)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- docker, docker-compose, typescript
- 領域
- devops, infrastructure
調査の方向性
まず packages/server/src/utils/builders/compose.ts から始め、次に Application の認証フローを比較し、プロジェクトスコープのアプローチを選択する前に #5159 と #5224 を確認してください。Part 1 では Settings → Registry フォームの場所も特定する必要があります。Compose がリンクされたプロジェクト Registry をアプリごとに分離された認証でサポートし、projectRegistry マイグレーションが存在し、Server フィールドの動作が修正されていれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Data in examples is anonymized (registry.example.com, acme, servers dev / prod).
What problem will this feature address?
Compose services have no registry-authentication mechanism. A Compose deploy that pulls a private image relies entirely on a docker login that was run out of band on the target server, and there is no first-class, per-deploy way to establish it.
How it fails in practice
Setup (anonymized):
- One Compose service, image
registry.example.com/acme/wordpress:prodfrom a private registry. - Deployed to a remote
prodserver (not the Dokploy host). - Registry added in Settings → Registry with valid credentials.
Deploy log:
Image registry.example.com/acme/wordpress:prod Pulling
Image registry.example.com/acme/wordpress:prod Error
Head "https://registry.example.com/v2/acme/wordpress/manifests/prod": unauthorized: Authentication required
Error response from daemon: Head "...": unauthorized: Authentication required
Error: ❌ Docker command failed
Why it happens
getBuildComposeCommand (packages/server/src/utils/builders/compose.ts) emits no docker login step. The generated script runs docker compose up / docker stack deploy on the target server, and the pull authenticates only from that server's ~/.docker/config.json. DOCKER_CONFIG is injected into the env file but hardcoded to the shared /root/.docker.
The "Server (Optional)" field in the Settings → Registry dialog is the only path to seed that state. It:
- runs a one-off
docker loginon save (control-plane host if empty, orexecAsyncRemote(serverId, …)for a picked server); - is never persisted — no column on
registry,update/creatediscard it after use,registry.onedoesn't return it. On re-open the dropdown is always blank (<Select defaultValue>never reflects an async-loaded value either); - on Cloud, editing a registry without re-picking a server throws
"Select a server to add the registry"; - writes the shared
/root/.docker/config.jsonon the chosen host.
Contrast with Application (works)
Application authenticates per deploy:
- Source = Docker image →
buildRemoteDockerembedsdocker loginin the deploy script onbuildServerId || serverId; the same creds go to the Docker API on swarm service create (getAuthConfig). - Git build → push (multi-node swarm) →
getRegistryCommands(utils/cluster/upload.ts) embedsdocker login+tag+push. - Pull on other swarm nodes →
authConfigfrom the registry row.
Credentials travel with the deploy; nothing has to pre-exist on the host; it is self-healing. Compose has none of this.
Second problem: credential isolation on shared hosts
Because the seeding path writes the shared /root/.docker/config.json, a host that runs services from more than one project accumulates logins for every registry that was ever seeded on it. Any workload or shell on that host can then pull from all of them.
Concrete case: a DevOps operator manages several projects, each with its own private AWS ECR. If dev and prod (or a single shared box) get seeded for multiple projects' registries, project A's server holds project B's registry credentials in the shared Docker config. There is no per-project or per-service credential scoping.
Also affected / not affected
- Databases (
postgres,mysql,mariadb,mongo,redis) — schema has onlydockerImage, no registry/credential fields, and the deploy creates the service with noauthconfig. Private-registry images do not work for databases today at all. - Applications — unaffected; they already authenticate per deploy.
Describe the solution you'd like
Two parts. Part 1 is small and independent; part 2 is the feature.
Part 1 — fix the Settings → Registry "Server" field (small, no migration)
- Rewrite the label and description to say what it does: "Run
docker loginfor this registry on the selected servers now, to verify credentials / pre-authenticate." It is an action, not a stored association. - Fix
<Select defaultValue={field.value}>→value={field.value}and includeserverIdin theform.reset(...)branch so it stops rendering blank. - Position it next to Test Registry as a verification helper.
Part 2 — project-scoped registry authentication for Compose
Data model
- New
projectRegistryjoin table (projectId,registryId), many-to-many.registrystays organization-scoped; the association is explicit and cascade-deleted on project or registry delete. - No new columns on
registry. No per-server table. No change toapplications.
Deploy flow (Compose)
Before docker compose up / docker stack deploy, the generated script:
export DOCKER_CONFIG="<COMPOSE_PATH>/<appName>/.docker" # per-app, replaces shared /root/.docker
mkdir -p "$DOCKER_CONFIG"
# one login per registry linked to this service's project (fatal on failure):
printf %s "$R1_PASS" | docker login registry.example.com -u "$R1_USER" --password-stdin || exit 1
printf %s "$R2_PASS" | docker login 123456789012.dkr.ecr.eu-west-1.amazonaws.com -u "$R2_USER" --password-stdin || exit 1
docker compose -p <app> -f <file> up -d --build --remove-orphans
# or: docker stack deploy -c <file> <app> --prune --with-registry-auth
~/.docker/config.json(here, the per-app one) storesauthskeyed by registry hostname, so multiple logins coexist.docker compose/docker pullmatches each image's host to its entry automatically — no ordering concern.stack deploy --with-registry-authforwards the matching entries to swarm.
Result
- No dependency on out-of-band host state; self-healing like Application. A bad credential surfaces in the deploy log.
- Credentials for project A's registries land only in project A's services' isolated config dirs — a shared host never accumulates other projects' logins.
- Registries are set once per project, not per service.
- Two private registries in one Compose file → link both to the project.
Validation
- A project may link at most one registry per hostname (a second login to the same host would overwrite the first). Different ECR accounts have different hosts and are fine.
- Registry must belong to the same organization as the project.
Out of scope for the first PR (possible follow-ups): applying project registries to databases' authconfig; environment-level (dev/prod) scoping below project level; rewiring Applications to inherit project registries.
Describe alternatives you've considered
-
Bind registries to servers instead of projects. Rejected. Wrong granularity — "server X may use registry R" means every workload on X can, including services from another project that happen to deploy there. It also reintroduces a persistent host login and the need to track "is the login still valid" (stale on any external
config.jsonchange), which the per-deploy approach removes. -
A single
registryId/buildRegistryIdFK on the compose service (the approach in #5159 / #5224). Good direction and matches the Application pattern, but as the sole solution it is: single registry only; framed around the build server → push → pull flow, so the plain "privateimage:with no build server" case (the example above) is not covered; and it does not address the shared-/root/.dockerisolation problem (it adds cross-org validation, not per-project/per-service scoping). The project-scoped model can build on #5159 once merged, or replace the association layer. -
Do nothing — manual
docker loginon each server. The current workaround. Breaks silently whenever the host config is cleared or a token expires; does not scale to multiple servers or multiple registries. -
Auto-run
docker loginwhen a server is added. Rejected as too implicit — the new server may not have Docker ready, credentials may not apply, and failures happen silently in the background. An explicit link plus a visible "authenticate" action is clearer.
Additional context
Related issues / PRs
- #5224 (open) — feat(compose): remote build server and registry for prebuilt deploys. Requests build server + build registry on Compose, mirroring the app flow, with registry login on build and deploy hosts.
- #5159 (open, XL, currently CONFLICTING) — implementation of #5224. Adds
compose.buildServerId+compose.buildRegistryId(nullable FKs), migration0191, cross-org registry validation oncompose.update, server-delete guardrails. - #4148 (closed) — Docker Compose: Dedicated Build Server Support.
- #4150 / #4152 / #4046 (closed PRs) — earlier attempts at the same, not merged.
- #4804 (closed) — registry login "succeeds" but push fails on a remote/build server until a manual
docker loginon the VPS; same root cause (deploy-time auth on the right host). - #4518 (open) — after a restore, deploy fails until an extra save re-authenticates.
Nothing existing proposes project-scoped registry binding or per-app DOCKER_CONFIG isolation; both are new here. Neither covers the pure-pull Compose case or multi-registry-per-unit.
Migration
- Nothing stored needs migrating:
registrynever had a persistedserverId.registryrows and Application FKs are untouched. Migration = create the emptyprojectRegistrytable. - Non-breaking: a Compose service with no linked registry keeps the current behavior (pull from the host
~/.docker/config.json), so hosts already seeded manually keep working. Optional best-effort backfill: match image hostnames in a compose file against existing registries byregistryUrland pre-create links; skip if unreliable and show a hint on the service instead.
Caveat
docker stack deploy --with-registry-auth stores auth in the swarm raft log (encrypted, per-service). That path is inherently not ephemeral — it is a swarm mechanism, not a Dokploy issue, and applies regardless of this change.
Will you send a PR to implement it?
Maybe, need help — happy to implement, but would like to agree on the approach first (extend #5159's per-service FK vs. the project-scoped model here), and confirm whether Part 1 (the "Server" field fix) can land as its own small PR immediately.
- 主要言語
- TypeScript
- スター
- 38.2k
- フォーク
- 3.1k
- 平均マージ
- 2日 11時間
- マージ済み PR(30日)
- 65
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Dokploy/dokploy のほかの issue
-
needs-triage🔍
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
Dokploy/dokploy#5836 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Server threshold (CPU/Memory) alerts for the main Dokploy server never reach any notification対応中かも @ghazy2001 が 2 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
Dokploy/dokploy#5830 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Add a "System" option to the dark/light mode setting (follow OS appearance)対応中かも @fabianfrankwerner が 24 日前に担当しました。 オープンenhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
Dokploy/dokploy#5638 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
compose.search omits services missing from member accessedServices, even for owners/admins対応中かも @imrja8 が 4 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
Dokploy/dokploy#5361 · コメント 2 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[Feature Request] Show usage example for File Mounts created in the UI対応中かも @jereok91 が 46 日前に担当しました。 オープンenhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
Dokploy/dokploy#5147 · コメント 3 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
Dokploy/dokploy の issue をすべて見る
似ている issue
-
🐛 bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
LibreChat-AI/LibreChat#17733 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
TypeStrong/typedoc#3150 ·
-
accessibility bug good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信
-
Normalize image-source MIME types before SVG dispatch対応中かも @HarsH-1877 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
tscircuit/image-utils#58 · コメント 1 件 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 74/100
メンテナーはふだん 2 日以内に返信