Kituwa IT · Self-hosting guides

Install Portainer CE with Docker Compose

Self-hosted Docker management UI

docker guimanagementupdates

Portainer is a web UI for Docker: see every container, volume and network, view logs, exec into a shell, and update an image with a button press. If you host more than a handful of services, it pays for itself in the first afternoon.

Category
Dev & data
License
zlib (Business add-on)
Needs
Docker socket
Image
portainer/portainer-ce

What it is

A visual Docker manager with stack templates, container recreation, volume browsing, and registry management. The free Community Edition covers everything a self-hoster needs: stacks, logs, exec, and container health. Portainer's paid tiers add RBAC and multi-node, which most home servers don't need.

Before you start

  • It mounts /var/run/docker.sock, which is root on the host. Anyone with a Portainer admin account has your machine. Two-factor auth is not optional.
  • The default admin password is portainer for about five minutes. The UI nags you to change it; don't ignore the nag.
  • Portainer stacks and plain docker compose files fight over the same containers. Pick one source of truth or you'll get "orphan container" warnings forever.

1 — Write the compose file

Command / configuration
services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    ports:
      - "127.0.0.1:9443:9443"
      - "127.0.0.1:8000:8000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    environment:
      TZ: UTC
    healthcheck:
      test: ["CMD", "/portainer", "--healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  portainer_data:
    name: portainer_data

2 — Start it

Command / configuration
mkdir -p ~/services/portainer
cd ~/services/portainer
docker compose up -d
docker compose logs -f portainer | grep -i "portainer is ready\|error"

3 — First-run setup

  1. Open http://yourhost:9443 and set the admin password immediately. The port is 9443 for the modern UI; 8000 exists for the legacy one and the API, and you can leave it alone.
  2. Turn on two-factor authentication under User settings. With Docker socket access, this is the difference between a leaked password and a compromised server.
  3. Import your existing stacks. Stacks → Add stack → Upload compose file works, but for anything you manage on the command line, it's cleaner to leave them as-is and use Portainer only for logs, exec and resource views.
  4. Set up a user with no docker group equivalent — i.e. don't grant them Environment management — for read-only observation.
  5. Check Settings → Local volumes to confirm your named and bind-mounted volumes appear. If the volume list is empty, the /var/lib/docker/volumes mount is wrong for your Docker data root.

4 — Useful daily moves

Command / configuration
# container update with log inspection - what the GUI button does
docker compose pull
docker compose up -d --remove-orphans
docker compose logs --tail=50

# confirm nothing auto-restarted in a crash loop
docker ps -a --filter "status=restarting" --format '{{.Names}}'
Portainer is a full root-equivalent consoleAnyone who can reach it and has admin rights can bind-mount / into a new container and read every file on the machine. Don't expose 9443 to the internet, don't reuse a password you've typed elsewhere, and keep 2FA on. If you need remote access, put it behind WireGuard or Tailscale.

Help when you need it

Want help getting this running?

We can help with a supported Linux host, application setup, migration or troubleshooting. Contact us to confirm the software, scope and scheduling before ordering.

Related guides

← Browse all 30 guides · Back to top