Infrastructure guide

Portainer Docker Compose Setup: CE, Persistent Data, and Safe Access

Install Portainer CE with persistent state, restricted access, a clear Docker-socket threat model, and a backup that does not overpromise.

Published and reviewed by OpenAlt · September 25, 2026

Detailed image of illuminated server racks showcasing modern technology infrastructure.
Photo by panumas nikhomkhai on Pexels

TL;DR

Portainer Community Edition (CE) gives a small self-hosting server a Docker UI, but it does not remove the need to understand Docker. Use the official CE image, store Portainer’s state in a named portainer_data volume, expose HTTPS on port 9443, and protect both the admin interface and Docker socket.

The Docker socket grants powerful control over the host. Treat Portainer as a privileged administration service: restrict network access, use a strong administrator password, back up its data, and test upgrades before applying them.

TOC

CE vs BE

Choose CE unless you specifically need Business Edition capabilities or commercial support. Portainer publishes separate installation paths for Community Edition and Business Edition. Do not copy a Business Edition command into a CE deployment or assume that old tutorials use the same image.

CE is appropriate for many personal servers, labs, and small self-hosting environments. It provides a web interface for managing Docker environments, containers, images, networks, volumes, and stacks. The UI can simplify routine work, but it does not replace backups, access control, change review, or host-level recovery planning.

If your goal is a broader deployment workflow, compare Portainer with other self-hosting platforms, explore one-click self-hosting, or browse OpenAlt’s self-hosting directory.

Docker socket threat model

Mounting /var/run/docker.sock gives Portainer control over the Docker daemon, so the Portainer container should be considered highly privileged. Anyone who gains administrator access to Portainer may be able to create containers that mount host paths, access secrets, change networking, or otherwise affect the host.

A read-only bind mount does not make the Docker API harmless. The socket is an interface to the daemon; the important risk is what the daemon can do, not merely whether the socket file can be modified.

Reduce exposure with layered controls:

  • Keep port 9443 private to your LAN, VPN, or management network.
  • Do not forward the admin interface directly to the public internet.
  • Use a strong, unique administrator password and protect any reverse proxy with authentication and TLS.
  • Give Portainer access only to Docker environments that it must manage.
  • Keep the host, Docker Engine, Portainer, and reverse proxy updated.
  • Review unfamiliar stacks, images, bind mounts, and environment variables before deployment.

Portainer improves visibility and workflow. It does not turn untrusted Docker workloads into safe workloads.

Compose setup

This Compose file uses the official CE image, a named data volume, HTTPS on port 9443, and an automatic restart policy. The :2 tag pins the image to the major version line while allowing compatible minor and patch updates; replace it with a tested exact tag or digest when you need stricter reproducibility.

services:
  portainer:
    image: portainer/portainer-ce:2
    container_name: portainer
    restart: unless-stopped
    ports:
      - "127.0.0.1:9443:9443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Save this as a Compose file in a dedicated directory, then start it with your normal Docker Compose workflow. Binding to 127.0.0.1 keeps the service local to the host. If a trusted reverse proxy or private network must reach Portainer directly, bind the port to the required interface and enforce firewall rules.

The named portainer_data volume is essential. It stores Portainer’s database, configuration, users, settings, and related state outside the container’s writable layer. Recreating the container should not erase that data.

An IT professional operates a computer in a server room, managing network systems and connected devices.
Photo by panumas nikhomkhai on Pexels
Detailed view of a server rack with a focus on technology and data storage.
Photo by panumas nikhomkhai on Pexels

Initial administrator

Open https://localhost:9443 and create the first administrator before connecting environments. Portainer’s official setup flow requires an administrator password of at least 12 characters, followed by an environment wizard.

Your browser may warn about a self-signed certificate on the first visit. That is expected for a fresh local installation. For a long-lived or remotely accessed deployment, place Portainer behind a trusted TLS setup or otherwise manage certificate trust deliberately.

Do not reuse the Docker host’s root password, SSH password, or a password used elsewhere. Store the credential in a password manager and restrict access to the Portainer URL.

Verify the environment

Confirm that Portainer can see the intended local Docker environment before deploying anything important. After setup, open the environment view and check that the Docker Engine is reachable and that the displayed host matches the machine you intended to manage.

Create a low-risk test container or inspect an existing noncritical service. Verify that Portainer can display containers, images, networks, and volumes. If you use stacks, remember that Portainer accepts Compose-format files through the web editor, file upload, Git repositories, or templates, as described in the stack deployment documentation.

Do not treat visibility as proof of recoverability. A listed volume is not automatically backed up, and a displayed stack is not necessarily reproducible unless its Compose file, image references, secrets, and external dependencies are documented.

Back up and restore

Back up the portainer_data volume separately from your application data. Portainer’s own data contains its management state; your databases, uploads, media, and application volumes live elsewhere and require their own backup strategy.

Stop Portainer before making a consistent volume archive, then create an archive from the named volume:

docker compose stop portainer
docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/portainer_data.tgz -C /data .
docker compose start portainer

Store the archive away from the Docker host and periodically test that it can be read. A backup that has never been restored is only an assumption.

To restore, stop Portainer and extract the archive into an empty volume with the same name:

docker compose stop portainer
docker volume create portainer_data
docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine \
  tar xzf /backup/portainer_data.tgz -C /data
docker compose start portainer

If the volume already contains data, use a temporary restoration volume and validate it before replacing the active volume. Keep a copy of the current data until the restored Portainer instance has been checked.

This process restores Portainer’s configuration and management database. It does not back up application volumes, host files, databases inside other containers, registry credentials stored elsewhere, or the Compose files used to recreate applications.

Upgrade and rollback

Upgrade only after confirming that a recent Portainer backup and application backups exist. Review the release notes, pull the selected image, and recreate the service using your usual Compose workflow:

docker compose pull portainer
docker compose up -d portainer

Watch the logs and open the UI after the upgrade. Confirm that the administrator account, local environment, stacks, and endpoint access still work.

For rollback, use the previously tested image tag or digest rather than guessing a version. Restore the matching portainer_data backup if a database migration occurred. Do not assume that every newer Portainer data format can be opened safely by an older image.

Troubleshooting

SymptomLikely causePractical check
Port 9443 is unreachableThe service is stopped, bound to localhost, or blocked by a firewallCheck container status, the bind address, and local access from the host
Browser shows a certificate warningPortainer is using a fresh self-signed certificateConfirm the URL and use trusted TLS for regular remote access
Environment is unavailableThe socket mount is missing or Docker is not runningInspect the Compose volumes and Docker Engine status
Settings disappeared after recreationportainer_data was not mountedConfirm the named volume exists and is attached to /data
A stack fails to deployInvalid Compose syntax, missing image, secret, path, or variableValidate the file and check Portainer’s deployment logs
Upgrade behaves unexpectedlyA moving tag changed or data migration is incompatiblePin a tested version, restore a compatible backup, and review logs

FAQ

Is Portainer CE free?

Yes. Portainer CE is the Community Edition and is intended for community use. It has a separate installation path from Business Edition; choose the CE image and documentation when deploying CE.

Is the Docker socket dangerous?

Yes. Access to the Docker socket is effectively access to the Docker daemon. A compromised Portainer administrator may be able to control containers and reach sensitive host resources. Restrict the UI and protect administrator credentials.

What data must be backed up?

Back up portainer_data for Portainer’s users, settings, endpoints, and management database. Separately back up application volumes, databases, Compose files, secrets, configuration files, and any host data your services need.

Does Portainer back up containers?

No. Portainer manages containers but is not a complete application-backup system. Recreating a container does not restore its data, and a Portainer data backup does not include application volumes.

Should port 9443 be public?

Usually not. Keep it on localhost, a private LAN, or a VPN, and use a controlled reverse proxy when remote access is necessary. Never expose an unprotected Docker administration interface directly to the public internet.