Skip to Content

Self-Host Portainer: Manage All Your Docker Containers from One Dashboard in 15 Minutes

Self-Host Portainer: Manage All Your Docker Containers from One Dashboard in 15 Minutes

If you're running more than a couple of Docker containers, you know the pain: docker ps gives you a wall of text, docker logs requires you to remember container names, and inspecting resource usage means parsing JSON output. Portainer solves this by giving you a clean, powerful web UI to manage everything Docker — containers, images, volumes, networks, and even Docker Swarm or Kubernetes clusters.

In this guide, you'll deploy Portainer CE (Community Edition) on any Docker host and get a centralized dashboard up and running in about 15 minutes.

Why Self-Host Portainer?

  • Unified view: See all containers, images, volumes, and networks across multiple Docker environments
  • Easy management: Start, stop, restart, inspect, and delete containers with a few clicks
  • Stack deployments: Deploy multi-container applications using docker-compose files directly from the UI
  • User management: Create teams and control who can access what (CE supports local users; BE adds LDAP/OAuth)
  • Lightweight: Runs in a single container with minimal resource overhead
  • No vendor lock-in: Open-source (zlib license), self-hosted, your data stays local

Prerequisites

  • A VPS or server with Docker installed (Ubuntu 22.04/24.04, Debian 12, or similar)
  • Minimum 1 CPU, 1GB RAM (2GB+ recommended for the host)
  • Docker Engine 20.10+ and Docker Compose plugin
  • A domain pointing to your server (optional, for reverse proxy setup)
  • Ports 9000 (HTTP) and 9443 (HTTPS) available

Step 1: Create the Docker Compose File

Create a directory for Portainer and a docker-compose.yml file:

mkdir -p ~/portainer && cd ~/portainer

Paste this into docker-compose.yml:

version: "3.8"

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - portainer_data:/data
    ports:
      - "8000:8000"
      - "9443:9443"
      - "9000:9000"
    environment:
      - TZ=UTC

volumes:
  portainer_data:

What this does:

  • portainer-ce:latest: The community edition image (stable, regularly updated)
  • docker.sock: Gives Portainer access to the Docker daemon (required for management)
  • portainer_data: Persistent volume for Portainer's database and settings
  • 9443: HTTPS web UI (recommended)
  • 9000: HTTP web UI (useful for local access or reverse proxy)
  • 8000: Edge agent tunnel (for managing remote Docker hosts)
  • no-new-privileges: Security hardening to prevent privilege escalation

Step 2: Deploy Portainer

Start the container:

docker compose up -d

Verify it's running:

docker ps --filter name=portainer

You should see output like:

CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS         PORTS                                                                                            NAMES
a1b2c3d4e5f6   portainer/portainer-ce:latest   "/portainer"             5 seconds ago   Up 3 seconds   0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:9443->9443/tcp   portainer

Step 3: Initial Setup

Open your browser and navigate to:

https://your-server-ip:9443

Note: You'll see a browser warning about the self-signed certificate. Click "Advanced" → "Proceed" (or add an exception). This is normal for the initial setup.

On first launch:

  1. Create admin user: Enter a username (or leave as admin) and a strong password (minimum 12 characters recommended)
  2. Connect to Docker: Select Get Started → Docker (local environment)
  3. Done! You'll land on the Portainer dashboard

Step 4: Verify Everything Works

Once logged in, you should see:

  • Dashboard: Overview of your Docker environment (running/stopped containers, image count, volume usage)
  • Containers: List of all containers with start/stop/restart/delete actions
  • Images: All pulled images with prune options
  • Networks: Docker networks with create/manage options
  • Volumes: Persistent volumes with browse and cleanup tools

Try these quick tests:

  1. View container logs: Click any running container → Logs tab — much nicer than docker logs -f
  2. Open a shell: Container → Console → Connect — instant web-based exec
  3. Check stats: Container → Stats — real-time CPU, memory, network, and disk I/O
  4. Deploy a stack: Stacks → Add stack → paste a docker-compose file → Deploy

Step 5: (Optional) Secure with a Reverse Proxy

For production, put Portainer behind Traefik or Nginx Proxy Manager with a valid TLS certificate. Here's a Traefik example:

# Add labels to the portainer service in docker-compose.yml
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portainer.rule=Host(`portainer.yourdomain.com`)"
      - "traefik.http.routers.portainer.entrypoints=websecure"
      - "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
      - "traefik.http.services.portainer.loadbalancer.server.port=9000"

Then access Portainer at https://portainer.yourdomain.com with a valid certificate.

Next Steps

Now that Portainer is running, consider these follow-ups:

  • Add remote environments: Use the Portainer Edge Agent to manage other Docker hosts from one dashboard
  • Set up stacks: Convert your docker-compose files into Portainer stacks for one-click deployments
  • Enable notifications: Configure webhook notifications for container events
  • Explore Portainer BE: If you need LDAP, OAuth, or role-based access control, check out the Business Edition (free for up to 5 users)
  • Backup Portainer data: The portainer_data volume contains your config — add it to your backup strategy

Related Guides

With Portainer managing your Docker fleet, you'll spend less time memorizing CLI flags and more time shipping. Deploy it once, and you'll wonder how you managed containers without it.

Self-Host Keycloak: Enterprise SSO for Your Homelab in 15 Minutes