# Portainer vs Dockhand — Analysis & Recommendation

*Assessed: March 2026 | Portainer Business Edition 2.39.0 LTS | Dockhand v1.0.20*

---

## 1. Context — How This Homelab Uses Portainer

This homelab runs **Portainer Business Edition** as its container management platform across 5 hosts and ~81 stacks (~157 containers total). It is important to understand the *actual* usage pattern before evaluating alternatives:

**What Portainer is used for here:**
- **Deployment target** — the CI workflow (`portainer-deploy.yml`) calls Portainer's REST API to deploy stack updates; Portainer is the endpoint, not the engine
- **Container UI** — logs, exec, resource view, per-host visibility, container lifecycle
- **Stack inventory** — single pane of glass across all 5 hosts

**What Portainer's built-in GitOps is NOT used for:**
Portainer's own GitOps polling/webhook engine is largely bypassed. The custom CI workflow handles all of:
- Detecting changed files via git diff
- Classifying stacks (GitOps vs detached vs string)
- Injecting secrets at deploy time
- Path translation between legacy and canonical paths
- Notifications via ntfy

This distinction matters: most GitOps-related complaints about Portainer CE don't apply here because those features aren't being relied upon.

---

## 2. Portainer Business Edition — Current State

### Version
**2.39.0 LTS** — the latest stable release as of February 2026. ✅

### Key bugs fixed in recent releases relevant to this setup

| Fix | Version |
|-----|---------|
| GitOps removing containers when image pull fails (data-loss bug) | 2.39.0 |
| Webhook URLs regenerating unexpectedly on stack edits | 2.37.0 |
| Stack update button silently doing nothing | 2.33.4, 2.37.0 |
| CSRF "Origin invalid" error behind reverse proxy | 2.33.0+ |

### Pain points still present (despite BE license)

| Issue | Impact |
|-------|--------|
| Non-root compose path bug (Portainer 2.39 ignores `composeFilePathInRepository`) | Forces `atlantis-arr-stack` and `derper-atl` into "string stack" workaround in CI |
| 17+ stacks reference legacy `Atlantis/` / `Calypso/` symlink paths | Requires path translation logic in CI workflow |
| GUI "Pull and Redeploy" always fails | By design — credentials are injected by CI only, never saved in Portainer |
| `#11015`: GitOps polling silently breaks if stack creator account is deleted | Low risk (single-user setup) but worth knowing |
| No git submodule support | Not currently needed but worth noting |

### BE features available (that CE users lack)

Since you're on Business Edition, these are already unlocked and relevant:

| Feature | Relevance |
|---------|-----------|
| **Relative path volumes** | Eliminates the need for string stack workarounds — compose files can use `./config:/app/config` sourced from the repo. Worth evaluating for `atlantis-arr-stack` migration. |
| **Shared Git credentials** | Credentials defined once, reusable across stacks — reduces per-stack credential management |
| **Image update notifications** | In-UI indicator when a newer image tag is available |
| **Activity + auth logs** | Audit trail for all API and UI actions |
| **GitOps change windows** | Restrict auto-deploys to specific time windows (maintenance windows) |
| **Fleet Governance Policies** | Policy-based management across environments (added 2.37–2.39) |
| **Force redeployment toggle** | Redeploy even when no Git change detected |

---

## 3. Dockhand — What It Is

**GitHub:** https://github.com/Finsys/dockhand
**Launched:** December 2025 (solo developer, Jarek Krochmalski)
**Stars:** ~3,100 | **Open issues:** ~295 | **Latest:** v1.0.20 (Mar 3 2026)

Dockhand is a modern Docker management UI built as a direct Portainer alternative. It is positioned at the homelab/self-hosted market with a clean SvelteKit UI, Git-first stack deployment, and a lighter architectural footprint.

### Key features
- Git-backed stack deployment with webhook and auto-sync
- Real-time logs (full ANSI color), interactive terminal, in-container file browser
- Multi-host via **Hawser agent** (outbound-only connections — no inbound firewall rules needed)
- Vulnerability scanning (Trivy + Grype integration)
- Image auto-update per container
- OIDC/SSO, MFA in free tier
- SQLite (default) or PostgreSQL backend

### Notable gaps
- **No Docker Swarm support** (not planned)
- **No Kubernetes support**
- **RBAC is Enterprise/paid tier**
- **LDAP/AD is Enterprise/paid tier**
- **Mobile UI** is not responsive-friendly
- **~295 open issues** on a 3-month-old project — significant for production use
- **No proven migration path** from Portainer

### Licensing
**Business Source License 1.1 (BSL 1.1)** — source-available, converts to Apache 2.0 on January 1, 2029.
Effectively free for personal/homelab use with no practical restrictions. Not OSI-approved open source.

---

## 4. Comparison Table

| Dimension | Portainer BE 2.39 | Dockhand v1.0 |
|---|---|---|
| Age / maturity | 9 years, battle-tested | 3 months, early adopter territory |
| Proven at 80+ stacks | Yes | Unknown |
| Migration effort | None (already running) | High — 81 stacks re-registration |
| GitOps quality | Buggy built-in, but CI bypasses it | First-class design, also has bugs |
| UI/UX | Functional, aging | Modern, better DX |
| Multi-host | Solid, agent-based | Solid, Hawser agent (outbound-only) |
| Relative path volumes | Yes (BE) | Yes |
| Shared credentials | Yes (BE) | N/A (per-stack only) |
| RBAC | Yes (BE) | Enterprise/paid tier only |
| Audit logging | Yes (BE) | Enterprise/paid tier only |
| OIDC/SSO | Yes (BE) | Yes (free tier) |
| Docker Swarm | Yes | No |
| Kubernetes | Yes (BE) | No |
| Open issue risk | Low (known issues, slow-moving) | High (295 open, fast-moving target) |
| License | Commercial (BE) | BSL 1.1 → Apache 2.0 2029 |
| Production risk | Low | High |

---

## 5. Recommendation

### Now: Stay on Portainer BE 2.39.0

You are already on the latest LTS with the worst bugs fixed. The BE license means the main CE pain points (relative path volumes, shared credentials, audit logs) are already available — many of the reasons people leave Portainer CE don't apply here.

The custom CI workflow already handles everything Dockhand's GitOps would replace, and it is battle-tested across 81 stacks.

**One concrete improvement available now:** The non-root compose path bug forces `atlantis-arr-stack` into the string stack workaround in CI. Since BE includes relative path volumes, it may be worth testing whether a proper GitOps stack with `composeFilePathInRepository` set works correctly on 2.39.0 — the bug was reported against CE and may behave differently in BE.

### In ~6 months: Reassess Dockhand

Dockhand's architectural direction is better than Portainer's in several ways (outbound-only agents, Git-first design, modern UI). At ~3 months old with 295 open issues it is not a safe migration target for a production 81-stack homelab. Revisit when the criteria below are met.

### Dockhand revisit criteria

Watch for these signals before reconsidering:

- [ ] Open issue count stabilises below ~75–100
- [ ] A named "stable" or LTS release exists (not just v1.0.x incrementing weekly)
- [ ] Portainer → Dockhand migration tooling exists (stack import from Portainer API)
- [ ] 6+ months of no breaking regressions reported in `r/selfhosted` or GitHub
- [ ] RBAC available without Enterprise tier (or confirmed single-user use case is unaffected)
- [ ] Relative volume path / host data dir detection bugs are resolved

---

## 6. References

| Resource | Link |
|----------|------|
| Dockhand GitHub | https://github.com/Finsys/dockhand |
| Portainer releases | https://github.com/portainer/portainer/releases |
| Portainer BE feature matrix | https://www.portainer.io/pricing |
| Related: Portainer API guide | `docs/admin/PORTAINER_API_GUIDE.md` |
| Related: GitOps comprehensive guide | `docs/admin/GITOPS_COMPREHENSIVE_GUIDE.md` |
| Related: CI deploy workflow | `.gitea/workflows/portainer-deploy.yml` |
