Portainer
Portainer CE, the community edition, shows what Docker is running and lets you act on it from the browser: containers, logs, volumes, networks and images, with restart, exec, stop and image pulls a click away. It reaches the Docker daemon through a socket proxy that decides which API calls pass; Portainer itself never holds the socket. Two services: Portainer and the socket proxy. For stacks deployed from Git, Dockhand is the other management interface here.
Last run on a host 8 Nov 2026
Pinned at 2.45.3 (released 21 Oct 2026) · the newest upstream release
In the upstream images: 0 CRITICAL · 6 HIGH with a published fix — per image
To try it: Docker, nothing else. See Try it locally.
To deploy it behind the proxy: Traefik running and a domain.
Try it locally
Section titled “Try it locally”On your own machine, with no proxy, domain or certificate. From core/portainer/:
cp .env.local.example .env.localdocker compose -f docker-compose.local.yml --env-file .env.local up -ddocker compose -f docker-compose.local.yml --env-file .env.local logs app | grep setup_tokenOpen http://localhost:9000 within five minutes, paste the token into Setup
token and create the administrator. Stop it again with the same command and
down.
Installation
Section titled “Installation”From core/portainer/:
-
Copy the environment file and set
APP_TRAEFIK_HOSTandTZ:Terminal window cp .env.example .envThere is no secret to generate: the first administrator is created in the interface.
-
List
portainer-edgeinEDGE_NETWORKSincore/traefik/.env, then render and restart Traefik — see edge networks. -
Start it and read the setup token, which Portainer prints once:
Terminal window docker compose up -ddocker compose logs portainer-app | grep setup_token -
Within five minutes of the start, open
https://<APP_TRAEFIK_HOST>, paste the token into Setup token, and create the administrator with a strong password. -
Turn on two-factor authentication in the user settings.
The setup token is what keeps whoever reaches the page during those five minutes from claiming the instance. Portainer asks for the same token when it restores from a backup. Past the five minutes the setup locks until the container restarts.
Verify
Section titled “Verify”docker compose ps # two services, healthydocker compose logs socket-proxy # the API calls the proxy handlesIn the interface, list the containers, open one’s logs and pull an image.
Going further
Section titled “Going further”What the socket proxy allows
Section titled “What the socket proxy allows”The proxy’s environment in docker-compose.yml is the permission set:
| Variables | Grant |
|---|---|
CONTAINERS, SERVICES, NETWORKS, VOLUMES, IMAGES, SYSTEM |
read access |
EXEC, POST, DELETE |
changes |
ALLOW_START, ALLOW_STOP, ALLOW_RESTARTS |
container lifecycle |
As shipped, that is full access for a trusted administrator. Anything that can
change containers is equivalent to root on the host. For a read-only view, set
POST, DELETE and EXEC to "0".
Who can reach it
Section titled “Who can reach it”The route ships access-vpn, limit-strict and headers-standard, and names
tls-strict as its TLS option. If the interface comes up blank or half-rendered
on a cold cache, the proxy answered 429 to its first load: move to
limit-standard, which keeps the headers and widens the burst to 500.
Further hosts
Section titled “Further hosts”The Portainer Agent, core/portainer-agent/, puts another host into the same
interface. Edge agents connect back to the central Portainer on TCP 8000, which
this stack does not publish: it carries no TLS and only EDGE_KEY as
authentication. Publish it on a VPN address only, never 0.0.0.0. The steps are
in the agent’s README. Dockhand with Hawser covers
several hosts over HTTPS through Traefik, without an extra port.
Backup
Section titled “Backup”| Database | an embedded key-value store in volumes/data — no database server, no dump hook |
| State | volumes/data — users, environments, stacks, registries, access policies |
| Quiescing | stop the container or snapshot the filesystem; the store is written continuously |
For borgmatic, back up volumes/data with the container
stopped. Portainer’s own backup function, in the interface, writes one encrypted
archive; write it to a path the file backup covers.
What a loss costs is the environment definitions and access policies, not the containers — everything Portainer manages keeps running while it is down.
Updates
Section titled “Updates”Portainer migrates its database at start, one way.
-
Read the release notes.
-
Back up
volumes/data— the complete Portainer state. -
Raise
APP_TAGin.env, then:Terminal window docker compose pull && docker compose up -ddocker compose logs portainer-app --tail 100 -
Log in, and check that the environments still connect and the users are there.
To roll back, restore volumes/data and set the previous APP_TAG.
Troubleshooting
Section titled “Troubleshooting”The setup page refuses to create the administrator. The five-minute window
has passed. docker compose restart portainer-app, read the new token, and open
the page again.
The interface loads blank or half-rendered. limit-strict answered 429 to
the first load — see Who can reach it.
An action fails with a permission error from Docker. The socket proxy does
not grant that API call. Check its variables, then docker compose up -d.
An edge agent loops on a failed handshake. The environment was not saved in
the interface before EDGE_ID and EDGE_KEY were copied.
Repository files
Section titled “Repository files”core/portainer/README.md— setup, socket proxy, edge agentscore/portainer/.env.examplecore/portainer-agent/README.md— the agent for further hostscore/portainer/UPSTREAM.md— upgrade checklist and rollback
Official sources
Section titled “Official sources”© 2026 SecDockBlueCode Apache-2.0Site content CC BY-NC 4.0