Managing Docker from the command line works fine — until you’re juggling 20+ containers across multiple stacks. That’s where Portainer comes in. It gives you a clean web UI to manage everything: containers, images, volumes, networks, and even Docker Compose stacks.

Portainer CE (Community Edition) is free, open source, and takes about 2 minutes to set up. Here’s how to get it running on your server.


What Is Portainer?

Portainer is a lightweight management UI for Docker (and Kubernetes). Instead of remembering docker ps, docker logs, docker exec commands, you get a dashboard that shows everything at a glance.

Key features:

  • Container management — Start, stop, restart, remove, inspect logs, open a console
  • Stack deployment — Paste a docker-compose.yml and deploy from the UI
  • Image management — Pull, tag, and remove images
  • Volume and network management — Create, inspect, and clean up
  • User management — Multiple users with role-based access
  • Templates — One-click app deployment from a template library
  • Edge agents — Manage remote Docker hosts from a single Portainer instance
  • Resource monitoring — CPU, memory, and network stats per container

Prerequisites

Before you start, you need:

  • A Linux server (Ubuntu 22.04+, Debian 12+, or similar)
  • Docker installed and running
  • A user with Docker permissions (or root access)
  • Port 9443 available (Portainer’s HTTPS UI)

Don’t have Docker yet? Install it:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect

Step 1: Create a Docker Volume

Portainer stores its configuration in a Docker volume. Create it first:

docker volume create portainer_data

This persists your settings, users, and stack configurations across container restarts and updates.


Step 2: Deploy Portainer CE

Run Portainer with a single Docker command:

docker run -d \
  --name portainer \
  --restart=always \
  -p 8000:8000 \
  -p 9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

What each flag does:

FlagPurpose
-dRun in the background (detached)
--restart=alwaysAuto-start on boot and after crashes
-p 8000:8000Edge agent communication port
-p 9443:9443Web UI (HTTPS)
-v /var/run/docker.sock:...Gives Portainer access to Docker
-v portainer_data:/dataPersistent configuration storage

Docker Compose Alternative

If you prefer Compose (recommended for production):

# docker-compose.yml
version: '3'
services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    ports:
      - "8000:8000"
      - "9443:9443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Deploy it:

docker compose up -d

Step 3: Initial Setup

Open your browser and go to:

https://your-server-ip:9443

You’ll see a certificate warning since Portainer uses a self-signed cert by default — accept it and continue.

Create Admin Account

On first launch, Portainer asks you to create an admin account:

  1. Enter a username (default: admin)
  2. Set a strong password (minimum 12 characters)
  3. Click Create user

⚠️ Important: Do this immediately after deployment. If you don’t create an admin within a few minutes, Portainer locks itself for security.

Connect to Docker

Next, choose your environment:

  1. Select DockerManage the local Docker environment
  2. Click Connect

You’ll see your Docker dashboard with all running containers.


Step 4: Explore the Dashboard

Once connected, the dashboard shows:

Home

  • Overview of all environments (local Docker, remote hosts, Kubernetes clusters)
  • Quick stats: running containers, images, volumes, networks

Containers

  • List of all containers with status, image, created time, and ports
  • Click any container to see logs, inspect details, open a console, or view stats
  • Bulk actions: start, stop, restart, remove multiple containers at once

Stacks

  • Deploy docker-compose stacks directly from the UI
  • Paste YAML, upload a file, or reference a Git repository
  • Update stacks by editing the YAML and clicking Update the stack

Images

  • View all pulled images with size and tags
  • Pull new images from Docker Hub or private registries
  • Remove unused images to free disk space

Volumes

  • List all volumes with mount points and size
  • Create new volumes, remove unused ones
  • See which containers are using each volume

Networks

  • View Docker networks (bridge, host, overlay, custom)
  • Create new networks for container isolation

Step 5: Deploy Your First Stack

Let’s deploy something useful through Portainer. Go to StacksAdd stack.

Name: uptime-kuma

Web editor — paste this:

version: '3'
services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: always
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma-data:/app/data

volumes:
  uptime-kuma-data:

Click Deploy the stack. Portainer pulls the image and starts the container. You now have Uptime Kuma running, managed through the Portainer UI.


Step 6: Put Portainer Behind a Reverse Proxy

Running Portainer on port 9443 with a self-signed cert isn’t great for production. Put it behind a reverse proxy for proper HTTPS.

Traefik Labels

Update your Compose file:

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    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"
    networks:
      - traefik

networks:
  traefik:
    external: true

volumes:
  portainer_data:

Note: When behind a reverse proxy, Portainer serves HTTP on port 9000 internally. The proxy handles TLS termination.

See our SSL Certificates Guide for full setup instructions.

Caddy

p}ortarienveerr.syeo_uprrdooxmyaipno.rctoamin{er:9000

Step 7: Configure Settings

Go to Settings in the left sidebar:

Authentication

  • Enable OAuth (GitHub, Google, OIDC) for team access
  • Set session timeout
  • Restrict access with teams and roles

Edge Compute

  • Enable if you want to manage remote Docker hosts
  • Each remote host runs a lightweight Edge Agent that phones home to Portainer

App Templates

  • Portainer ships with 30+ templates (WordPress, Nginx, Redis, etc.)
  • Add custom template URLs for your own stack library

Backup

  • Settings → Backup — download a full backup of Portainer config
  • Schedule regular backups (or mount the volume to your backup system)

Updating Portainer

Portainer updates are simple — pull the new image and recreate the container:

docker stop portainer
docker rm portainer
docker pull portainer/portainer-ce:latest
docker run -d \
  --name portainer \
  --restart=always \
  -p 8000:8000 \
  -p 9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

Your data persists in the portainer_data volume, so nothing is lost.

With Compose:

docker compose pull
docker compose up -d

Troubleshooting

Can’t access the UI

  • Check the container is running: docker ps | grep portainer
  • Verify the port is open: curl -k https://localhost:9443
  • Check firewall rules: sudo ufw status

“Timeout” on initial setup

  • If you waited too long, Portainer may have locked. Remove and recreate:
    docker rm -f portainer
    docker volume rm portainer_data
    docker volume create portainer_data
    # Re-run the docker run command
    

Docker socket permission denied

  • Make sure you mounted /var/run/docker.sock
  • Check socket permissions: ls -la /var/run/docker.sock
  • The container runs as root by default, which should have access

Container stats not showing

  • Stats require cgroup v2 (default on modern systems)
  • Check: stat -fc %T /sys/fs/cgroup/ — should output cgroup2fs

Portainer CE vs Business Edition

FeatureCE (Free)Business ($)
Container management
Stack deployment
User management
RBAC (Role-Based Access)BasicAdvanced
Registry management
Git-based deployments
Edge computeLimitedFull
Kubernetes managementBasicFull
SupportCommunityProfessional

For most self-hosters, CE is more than enough. Business Edition is aimed at teams managing multiple clusters in production.


What to Deploy Next

Now that you have a Docker management UI, check out these guides for services to run:

Deploy them all as Portainer stacks and manage everything from one dashboard.


Portainer makes Docker approachable. Whether you’re running 3 containers or 30, having a visual dashboard saves time and prevents mistakes. Set it up once and you’ll wonder how you managed without it.