Featured image of post Portainer Container Management Complete Guide: Visual Docker Operations from Installation to Production

Portainer Container Management Complete Guide: Visual Docker Operations from Installation to Production

Deploy Portainer on your VPS from scratch for visual Docker container monitoring, management, and orchestration. Includes security hardening, multi-host management, Stack deployment, and best practices.

Why Do You Need Portainer?

In self-hosting and VPS operations, Docker containerization has become the standard. But command-line Docker operations are not beginner-friendly, and management complexity rises sharply as the number of containers grows. Portainer provides an intuitive web UI that lets you:

  • Visually monitor all containers: status, resource consumption, and network connections
  • One-click application deployment: via templates and Stacks (Compose files)
  • Image and volume management: browse, pull, and remove images; manage persistent storage
  • Multi-host management: manage multiple servers from a single Portainer instance
  • Role-based access control: fine-grained permissions for team collaboration

Prerequisites

Assuming you have a VPS running Ubuntu 22.04/24.04 or Debian 12, with at least 1GB RAM.

# Update the system
sudo apt update && sudo apt upgrade -y

# Install Docker (if not already installed)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker

# Verify Docker is running properly
docker version
docker info

The simplest way to run Portainer Server via Docker:

# Create a Portainer data volume for persistence
docker volume create portainer_data

# Start Portainer Server
docker run -d \
  --name portainer \
  --restart always \
  -p 9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

Parameter explanation:

  • -p 9443:9443: Maps the container’s 9443 port to the host (HTTPS)
  • -v /var/run/docker.sock: Mounts the Docker socket, allowing Portainer to control Docker
  • -v portainer_data:/data: Persists Portainer’s configuration and data

After starting, visit https://your-ip:9443, set the admin password, and you’re in.

⚠️ Security Note: For initial setup, using HTTP port 8000 is simpler:

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

Method 2: Deploy Using Docker Compose

For more structured management, Docker Compose is recommended:

# docker-compose.yml
version: '3.8'

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    ports:
      - "9443:9443"
      - "8000:8000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    networks:
      - portainer_net

volumes:
  portainer_data:

networks:
  portainer_net:
    driver: bridge
docker compose up -d

Method 3: Traefik Reverse Proxy Integration

If you’re already using Traefik as a reverse proxy, you can auto-configure Portainer via labels:

version: '3.8'

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=9443"
    networks:
      - proxy

volumes:
  portainer_data:

networks:
  proxy:
    external: true

First Use: Portainer Interface Overview

After logging in, you’ll see these core functional areas:

1. Environment Management

Portainer uses the concept of “environments” to manage different Docker hosts. On first login, it guides you to choose:

  • Local environment: Docker on the current server
  • Remote environment: Docker engines on other servers

2. Container Management

Click “Containers” to see all running containers, each showing:

  • CPU/Memory usage
  • Running status (Running/Stopped/Restarting)
  • Network port mappings
  • Uptime

Common operations:

  • Start/Stop/Restart: One-click container lifecycle control
  • Logs: View real-time log output
  • Exec: Enter the container to execute commands
  • Inspect: View detailed container configuration
  • Clone/Update: Quickly rebuild based on existing configuration

3. Image Management

Manage all downloaded Docker images:

  • Pull new images
  • Remove unused images to free space
  • View image details and layer information

Periodic cleanup command (also available via Portainer UI):

docker system prune -a --volumes

4. Stack Deployment (Compose Management)

Portainer’s most powerful feature is Stacks—it allows you to edit and deploy Docker Compose files through the web UI.

Example: Deploying Nextcloud:

version: '3.8'

services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: always
    ports:
      - "8080:80"
    volumes:
      - nextcloud_data:/var/www/html
      - nextcloud_config:/var/www/html/config
    environment:
      - MYSQL_HOST=db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nc_user
      - MYSQL_PASSWORD=your_secure_password
    networks:
      - nextcloud_net

  db:
    image: mariadb:10.11
    container_name: nextcloud_db
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nc_user
      - MYSQL_PASSWORD=your_secure_password
    networks:
      - nextcloud_net

volumes:
  nextcloud_data:
  nextcloud_config:
  db_data:

networks:
  nextcloud_net:
    driver: bridge

In the Portainer UI:

  1. Left menu → Stacks → Add stack
  2. Select “Build” mode (from local docker-compose.yml file)
  3. Paste the configuration above
  4. Click “Deploy the stack”

Advanced Features

Multi-Host Management

Portainer supports unified management of Docker engines across multiple servers:

  1. Start the Portainer Agent on managed servers:
docker volume create portainer_agent_data
docker run -d \
  --name portainer-agent \
  --restart always \
  -p 9001:9001 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_agent_data:/data \
  portainer/agent:latest
  1. In the main Portainer:
    • Settings → Environments → Add environment environment
    • Select “Agent” type
    • Enter the remote server’s IP and port 9001
    • Enter the Agent key (viewable in Settings → Endpoint synchronization)

Security Hardening

1. Enable HTTPS

Using Let’s Encrypt certificates:

# Install certbot
sudo apt install certbot -y

# Obtain certificate
sudo certbot certonly --standalone -d portainer.yourdomain.com

# Modify docker-compose.yml to mount certificates
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - portainer_data:/data
  - /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem:/cert/fullchain.pem
  - /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem:/cert/privkey.pem

2. Configure Reverse Proxy Authentication

Add Basic Auth in front of Nginx:

server {
    listen 443 ssl;
    server_name portainer.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem;

    location / {
        auth_basic "Portainer Admin";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass https://localhost:9443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Generate htpasswd file:

sudo apt install apache2-utils -y
sudo htpasswd -c /etc/nginx/.htpasswd admin

3. Restrict Network Access

Allow Portainer access only from specific IPs:

# Using UFW firewall
sudo ufw allow from your-admin-IP to any port 9443
sudo ufw deny 9443

Backup and Restore

Portainer’s configuration is stored in the portainer_data volume, making backups straightforward:

# Backup Portainer data
docker run --rm \
  -v portainer_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/portainer_backup_$(date +%Y%m%d).tar.gz -C /data .

# Restore
docker run --rm \
  -v portainer_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/portainer_backup_YYYYMMDD.tar.gz -C /data

Monitoring and Alerting Integration

Portainer itself doesn’t provide alerting, but it integrates well with external tools:

Auto-Updates with Watchtower

version: '3.8'

services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_POLL_INTERVAL=3600  # Check every hour
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_NOTIFICATIONS=shoutrrr
      - WATCHTOWER_NOTIFICATION_SHOUTRRR_URLS=discord://your-webhook-url
      - WATCHTOWER_NOTIFICATION_SHOUTRRR_TITLE=Portainer Update Alert

Prometheus Integration

Portainer provides API endpoints that can be integrated into a Prometheus monitoring stack.

Troubleshooting

Q1: Portainer cannot connect to Docker socket

Cause: Docker socket permission issue or incorrect container mounting.

Solution:

# Check if Docker socket exists
ls -la /var/run/docker.sock

# Verify Portainer container has correct mount
docker inspect portainer | grep docker.sock

Q2: Container starts and immediately exits

Cause: Image pull failure or port conflict.

Solution:

# Check container logs
docker logs portainer

# Check port conflicts
ss -tlnp | grep 9443

Q3: How to migrate Portainer to another server?

Steps:

  1. On the old server, backup the portainer_data volume
  2. Install Docker and Portainer on the new server
  3. Restore the backup data to the new server’s portainer_data volume
  4. Start Portainer and re-import your environment configurations

Q4: What’s the difference between Portainer CE and EE?

FeatureCE (Community)EE (Enterprise)
CostFreePaid
Container Management
Stack Deployment
Multi-Host Management
RBAC PermissionsBasicAdvanced
Kubernetes Management
Audit Logs
SupportCommunityOfficial

For individuals and small teams, the CE version is more than sufficient.

Best Practices Summary

  1. Always use volumes: Never store important data inside containers; use named volumes or bind mounts
  2. Set restart policies: Configure restart: always or restart: unless-stopped for all critical services
  3. Regular backups: At minimum, back up Portainer data and container volumes weekly
  4. Use network isolation: Create separate Docker networks for different services
  5. Limit exposed ports: Only expose ports when necessary; use a reverse proxy to统一管理 entries
  6. Keep updated: Regularly update Portainer and all container images
  7. Enable log rotation: Prevent log files from filling up disk space

Alternatives Comparison

ToolProsCons
PortainerFeature-rich, beautiful UI, active communityRequires extra resources
Docker Compose CLIZero overhead, lightweightOnly suitable for few containers
RancherK8s support, enterprise-gradeResource-heavy, complex
CoolifyHeroku-like experience, freeNewer project, smaller ecosystem
Landoop UIMinimalist, container-focusedLimited features

Conclusion

Portainer is a powerful tool for VPS operators, simplifying complex Docker operations into visual clicks. Whether you’re a newcomer to containers or a seasoned operator managing dozens of services, Portainer significantly boosts productivity.

Combined with reverse proxy, auto-updates, and regular backups, you can build a reliable production-grade container management platform.


This guide applies to Ubuntu 22.04/24.04, Debian 12, and Docker 24+.

📺 看视频版教程 → DuckDB Lab YouTube

Subscribe for more DuckDB & AI automation tutorials