Dokploy / Dokploy/dokploy

After DB recovery / schema errors, UI forces "Setup the server" even when users and projects still exist (isAdminPresent only checks member.role = owner)

Open
#5,192 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

To Reproduce
  1. Run a normal single-node Dokploy Swarm install (dokploy/dokploy:v0.30.0) with existing admin user, organization, projects, and domains.
  2. Force an unclean interruption of dokploy-postgres (in our case: host dockerd crashed with fatal error: concurrent map iteration and map write in BuildKit, then Docker restarted and Swarm restarted tasks). Postgres entered crash-loop (task: non-zero exit (1)), consistent with WAL/checkpoint damage (PANIC: could not locate a valid checkpoint record observed during recovery).
  3. Recover Postgres data (WAL reset / dump-restore) so that:
    • "user" still has the original admin row
    • organization still exists
    • project / application / domains metadata still exist
  4. Restart Dokploy.
  5. Observe that the web UI still redirects to /register and shows "Setup the server".
  6. Concurrently, Traefik (managed by Dokploy) may come back without usable Docker/Swarm provider discovery, so public apps also look "dead" even though containers/volumes still exist.

Minimal DB condition that triggers the UI bug even without corruption:

  • "user" count >= 1
  • member has no row with role = 'owner'

Then / redirects to /register.

Current vs. Expected behavior

Current behavior

  • UI treats the instance as a fresh install ("Setup the server" / register flow).
  • This happens even when application data is present.
  • Logs may show schema/migration problems (e.g. missing columns such as buildsConcurrency, failed ALTER TABLE), but the product still continues and mis-signals "uninitialized".
  • Webhooks (e.g. "Dokploy Server Restarted") can still fire, which contradicts the Setup screen.
  • Root cause in code: isAdminPresent() only checks for member.role === "owner" (see packages/server/src/services/admin.ts). Presence of users/projects is ignored. After recovery, member can be empty while "user" and organization remain, so Setup is forced.

Expected behavior

Dokploy should distinguish at least these states:

  1. Truly uninitialized (no users / no orgs) → Setup/register is OK.
  2. Recoverable / degraded (users/projects exist, but membership/schema/migration is broken) → show a maintenance/recovery error page, not Setup.
  3. Prefer detecting admin via broader signals (e.g. existing "user" + organization.owner_id, or any owner/admin membership), and/or provide a documented recovery path without pretending the server is brand new.

Also: when migrations fail, fail closed into an explicit error state instead of serving the onboarding UI.

Provide environment information
Operating System: Ubuntu (Hetzner VPS)
Arch: x86_64
Dokploy version: v0.30.0
Docker Swarm: single-node manager
RAM: 8 GB
Postgres: postgres:16 (dokploy-postgres Swarm service)
Traefik: managed by Dokploy (standalone dokploy-traefik); Docker/Swarm provider became unusable after recovery
Which area(s) are affected? (Select all that apply)

Authentication, Databases, Docker, Traefik, Application

Are you deploying the applications where Dokploy is installed or on a remote server?

Same server where Dokploy is installed

Additional context
Why this is dangerous

Dokploy positions itself as the manager of Docker/Swarm + Traefik. After a host-level Docker daemon crash, the panel DB can enter a half-recovered state. Because Setup is gated only on member.owner, operators are pushed toward "create a new admin" while production metadata still exists. That is the opposite of safe recovery UX for a control plane that owns Swarm state.

Evidence from our incident (redacted)
  • Host did not reboot (uptime remained multi-week); dockerd itself crashed and restarted.
  • Immediately after Docker restart, dokploy-postgres tasks looped with non-zero exit (1).
  • After DB files were recoverable:
    • "user" = 1 (original admin email still present)
    • organization = 1
    • project = 4
    • member owner rows = 0 → UI forced Setup/register
  • Inserting a member row with role='owner' for the existing org owner immediately made /register redirect away and restored the login page.
  • Separately, Traefik Docker API provider errors (client version 1.24 is too old...) meant label-based routes did not come back; file-based Traefik config was required to restore public traffic. This reinforces that recovery currently requires bypassing Dokploy’s managed path.
Suggested product fixes
  1. Change isAdminPresent() to consider existing users/org owners, not only member.role='owner'.
  2. If users exist but owner membership is missing, show Recovery / Repair UI (or auto-heal membership from organization.owner_id), never fresh Setup.
  3. If migrations fail, block onboarding and show the migration error prominently.
  4. Document a supported disaster-recovery procedure for dokploy-postgres that preserves identity and does not imply re-install.
  5. Make Traefik recovery less dependent on Docker provider alone (ensure file routes remain authoritative after daemon crashes).
Related (not duplicates)
  • #4253 — silent crash after "Migration complete"
  • #5112 — Traefik Swarm provider misconfig / recovery pain
  • #4686 — "Setup Server" UX confusion (remote servers; different scope)
Will you send a PR to fix it?

No

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/server/src/services/admin.ts at isAdminPresent(), then trace the /register redirect and the existing setup flow. Compare the current owner-membership check with the reported user and organization states. Done should distinguish an uninitialized server from a recoverable degraded state and avoid showing Setup when existing users or projects remain.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, postgresql, typescript
Domain
authentication, databases, devops, frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.