Migrate from Portainer
This guide walks you through migrating a production Portainer deployment to dockmesh. The migration is non-destructive — both tools can run side-by-side during the transition, and you can roll back at any point before you remove Portainer.
Why migrate
Section titled “Why migrate”Common reasons self-hosters and teams move from Portainer to dockmesh:
- RBAC locked behind Portainer Business — dockmesh ships custom roles in the free binary
- SSO/OIDC locked behind Portainer Business — dockmesh supports Azure AD, Google, Keycloak, Okta, Authentik free
- No native stack migration between hosts in Portainer — dockmesh moves stacks with volume transfer + rollback
- No auto-scaling in Portainer — dockmesh has threshold-based scaling with safety checks
- Single-binary deployment — dockmesh is one ~15 MB file; Portainer requires its own container + volume + upgrades
Before you start
Section titled “Before you start”Check these prerequisites on your Portainer server:
- Docker 20.10+ with API 1.41+
- Access to
/var/run/docker.sock - Your compose.yaml files (or the ability to export them from Portainer)
- A volume backup strategy — even though migration is non-destructive, always back up first
Step 1 — Install dockmesh alongside Portainer
Section titled “Step 1 — Install dockmesh alongside Portainer”dockmesh and Portainer don’t conflict. They can share the same Docker daemon.
On your Portainer server, install dockmesh:
curl -fsSL https://get.dockmesh.dev | bashBy default, dockmesh binds to :8080. If Portainer is already using 8080, set a different port:
Environment="DOCKMESH_HTTP_ADDR=:8090"Restart:
systemctl daemon-reloadsystemctl restart dockmeshOpen http://your-server:8090. Both Portainer and dockmesh now see the same containers.
Step 2 — Export your stacks from Portainer
Section titled “Step 2 — Export your stacks from Portainer”Portainer stores stacks as Compose files. You need to get those files into dockmesh’s stack directory.
Option A — Stacks created via “Web editor” in Portainer
Section titled “Option A — Stacks created via “Web editor” in Portainer”- Open Portainer → Stacks → pick a stack
- Click the Editor tab
- Copy the full YAML
- On the server, save it to
/opt/dockmesh/stacks/<host>/<stack-name>/compose.yaml
Repeat for every stack.
Option B — Stacks created via Git repository in Portainer
Section titled “Option B — Stacks created via Git repository in Portainer”Even easier — dockmesh also supports Git-backed stacks. In dockmesh Stacks → New stack → Git, enter the same repo URL and branch, and dockmesh will pull the compose file directly.
Option C — Bulk export via Portainer API
Section titled “Option C — Bulk export via Portainer API”For 10+ stacks, scripting saves time:
# Get all stackscurl -H "X-API-Key: $PORTAINER_KEY" https://portainer.example/api/stacks \ | jq -r '.[] | "\(.Id) \(.Name)"'
# For each stack, pull the compose filefor id in $(curl -s -H "X-API-Key: $PORTAINER_KEY" \ https://portainer.example/api/stacks | jq -r '.[].Id'); do name=$(curl -s -H "X-API-Key: $PORTAINER_KEY" \ https://portainer.example/api/stacks/$id | jq -r .Name) curl -s -H "X-API-Key: $PORTAINER_KEY" \ "https://portainer.example/api/stacks/$id/file" \ | jq -r .StackFileContent > /opt/dockmesh/stacks/local/$name/compose.yamldoneStep 3 — Import running containers
Section titled “Step 3 — Import running containers”For containers that were started via docker run or manually (not Compose stacks), use dockmesh’s docker run importer:
- In Portainer or via CLI, get the
docker runequivalent:docker inspect <container>has most of what you need. Community tools like runlike generate a clean one-line command. - In dockmesh: Stacks → New stack → Import from docker run
- Paste the command — dockmesh generates the compose.yaml
Step 4 — Set up RBAC and SSO
Section titled “Step 4 — Set up RBAC and SSO”This is usually the main reason for the migration. In dockmesh:
- Settings → Roles → New role — create custom roles with granular permissions
- Settings → Authentication → OIDC → Add provider — point to Azure AD, Google, Keycloak, or any OIDC provider
- Settings → Group mappings — map IdP group claims to dockmesh roles
See RBAC docs and SSO docs for details.
Step 5 — Add your other hosts
Section titled “Step 5 — Add your other hosts”If you had multiple Portainer Edge agents, switch them to dockmesh agents:
- Hosts → Add host in dockmesh — get an enrollment token
- On each remote host, run the agent install command the UI generates
- dockmesh agents connect outbound via mTLS — same networking model as Portainer Edge, but all agent features are free
You can keep the old Portainer Edge agents running — they don’t conflict. Remove them after everything is stable.
Step 6 — Verify and switch over
Section titled “Step 6 — Verify and switch over”For 1-2 weeks, run both tools side-by-side. Use dockmesh for all new stack changes, and keep Portainer read-only as a fallback view.
Checks before removing Portainer:
- All stacks visible in dockmesh
- Deploy, stop, restart all work from dockmesh UI
- Users have been migrated to new roles
- SSO works for your team
- Backups are configured and have completed at least one successful run
Step 7 — Remove Portainer
Section titled “Step 7 — Remove Portainer”Once you’re confident:
docker stop portainerdocker rm portainerdocker volume rm portainer_data # deletes Portainer's database, not your container dataYour container volumes and compose files are untouched — they’re managed by Docker and the filesystem, not Portainer.
Common gotchas
Section titled “Common gotchas”Compose file differences
Section titled “Compose file differences”Portainer supports Compose v2 and v3 with its own extensions. dockmesh uses the standard Compose spec — the 99% overlap means most files work unchanged. The exceptions:
- Portainer-specific labels (
io.portainer.*) are ignored — safe to leave or remove - Portainer template variables (
{{.Values.foo}}) need to be resolved — dockmesh uses.envfiles
Volume ownership
Section titled “Volume ownership”When dockmesh deploys a stack, Docker creates volumes using the project name. If your Portainer stack was named analytics_prod, the volume is analytics_prod_pgdata. dockmesh (when creating a new stack with the same name) will reuse these volumes — your data stays put. Just keep the stack name identical.
Endpoint concepts
Section titled “Endpoint concepts”Portainer calls a Docker host an “endpoint”. dockmesh calls it a host. The enrollment flow is the same outbound-mTLS pattern, just different terminology.
Going back
Section titled “Going back”If something’s not working, just use Portainer as before. dockmesh only reads the same Docker socket — it doesn’t mutate Portainer’s database. Stop/remove the dockmesh binary and you’re back to pure Portainer.
See also
Section titled “See also”- Quick Start — deploy your first dockmesh stack
- RBAC & Roles — replace Portainer Business role management
- Multi-Host — replace Portainer Edge agents
- Backup & Restore — set up your first backup job