Why I needed this
Have a bunch of Docker containers running across multiple servers - home lab, VPS, testing environments. Was SSHing into each server, running docker commands, trying to remember which container was on which server.
Want to restart a container? SSH in, find the right server, remember the exact docker command. Check logs? Same deal. See resource usage? Run docker stats on every server.
Then someone mentioned Portainer. Web UI for Docker. Manage all your containers, images, volumes, networks from one dashboard. Sounded too good to be true.
What Portainer actually does
Web-based Docker management. Deploy containers, view logs, restart services, manage volumes and networks - all through browser. Connect multiple Docker hosts, manage everything from one place.
Free for most use cases. Open-source core with paid enterprise features.
So what is Portainer
Portainer is a lightweight management UI for Docker. It runs as a container itself and connects to your Docker engines, giving you full control through a web interface.
What it can do:
- Container management: Start, stop, restart, remove containers
- Image management: Pull, build, prune images
- Volumes & networks: Create, manage, delete storage and networking
- Logs viewer: View and filter logs in real-time
- Console access: Shell into containers from browser
- Stack deployment: Deploy docker-compose stacks via UI
- Multi-host: Manage multiple Docker servers from one dashboard
- User management: Team access with role-based permissions
Why it's better than CLI:
- See everything at a glance - no typing commands
- Visualize resource usage - CPU, memory, network
- Manage multiple servers from one place
- Team collaboration - share access without sharing SSH
- Quick troubleshooting - logs and console in browser
It doesn't replace Docker CLI for everything, but for day-to-day management, it's way faster and easier.
Getting Portainer running
Quick install with Docker
Simplest way - run it as a container:
# Create volume for data
docker volume create portainer_data
# Run Portainer
docker run -d \
-p 9443:9443 \
--name portainer \
--restart=unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
cr.portainer/portainer-ce:latest
Access at https://localhost:9443 (note the https).
First setup
Create admin password, then you're in. The UI will show your local Docker environment automatically.
Docker Compose method
version: '3'
services:
portainer:
image: cr.portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
networks:
- portainer_network
volumes:
portainer_data:
networks:
portainer_network:
driver: bridge
The docker.sock mount is crucial - it gives Portainer access to manage your Docker containers.
Managing multiple servers
Setting up Portainer Agent
To manage remote Docker hosts, install the Portainer Agent:
# On each remote server, run:
docker run -d \
-p 9001:9001 \
--name portainer-agent \
--restart=unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
cr.portainer/agent:latest
Connect agent to Portainer
In Portainer UI:
# 1. Go to "Environments" → "Add environment"
# 2. Choose "Docker Standalone"
# 3. Name it: "Home Lab Server"
# 4. Environment URL: agent-server-ip:9001
# 5. Click "Connect"
Now you can manage that remote server from the main Portainer dashboard.
My setup
Here's how I organize multiple servers:
# Main Portainer instance on VPS
# - URL: portainer.mydomain.com
# - Manages: all other servers
# Home lab server
# - Name: "Home Lab"
# - URL: 192.168.1.100:9001
# - Runs: Plex, Jellyfin, Home Assistant
# Production VPS
# - Name: "Production"
# - URL: prod-server-ip:9001
# - Runs: Customer-facing apps
# Testing server
# - Name: "Testing"
# - URL: test-server-ip:9001
# - Runs: Experimental stuff
All visible in one dashboard. Switch between environments with a click.
Day-to-day usage
Managing containers
From the Containers page:
# See all containers across all environments
# Start/stop/restart with one click
# View logs in real-time with filtering
# Access container console directly in browser
# Inspect container details and metadata
Deploying stacks
Upload docker-compose.yml through the UI:
# In Portainer:
# 1. Go to "Stacks" → "Add stack"
# 2. Name it: "my-app"
# 3. Upload docker-compose.yml or paste content
# 4. Click "Deploy the stack"
# Example stack:
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "80:80"
restart: unless-stopped
Managing images
Pull, prune, and manage Docker images:
# Pull new images
# View image details and layers
# Clean up unused images (one-click prune)
# Build images from Dockerfiles
# Way easier than docker CLI for cleaning up
Volumes and networks
Manage storage and networking:
# Browse volume contents
# Create, delete, manage volumes
# Inspect network configurations
# See which containers are using what
# Great for troubleshooting storage issues
Real stuff I use Portainer for
Quick troubleshooting
Container acting weird? Check logs in Portainer instead of SSHing:
# 1. Open container logs in browser
# 2. Filter by keyword (e.g., "ERROR")
# 3. See real-time updates
# 4. Restart if needed - one click
# No need to find which server it's on
Deploying updates
Update container images through the UI:
# Container → Edit → Duplicate
# Change image tag (e.g., :latest to :v2.0)
# Pull latest image
# Remove old container
# Done
Resource monitoring
See what's eating resources:
# Dashboard shows CPU, memory, network for all containers
# Identify resource hogs quickly
# See which containers need more resources
# Plan capacity upgrades
Team collaboration
Give team members access without giving SSH:
# Create user accounts
# Assign to environments (with restrictions)
# Set role: read-only or standard user
# Team can manage their own containers
# No need to share server credentials
Backup and restore
Portainer settings and configurations:
# Settings → Backup Portainer
# Download backup file
# Contains: users, endpoints, stacks, configs
# Restore to new Portainer instance if needed
Advanced features
Registry management
Connect to Docker registries:
# Add Docker Hub, GitLab, GHCR, private registries
# Browse images without using docker CLI
# One-click deploy from registry to container
Templates
Deploy popular apps with one click:
# Templates → Custom Templates
# Add URL to template file
# Deploy with pre-filled configurations
# Or use built-in templates:
# - Nginx
# - MySQL
# - PostgreSQL
# - Redis
# - Many more
Webhook notifications
Get notified about events:
# Settings → Webhooks
# Configure endpoints for events:
# - Container stops unexpectedly
# - Image update available
# - Resource usage threshold exceeded
# Send to Slack, Discord, etc.
Authentication
Secure access to Portainer:
# Use OAuth/OIDC for login
# - Google
# - GitHub
# - Microsoft
# - Custom OIDC provider
# Enable 2FA for extra security
# Configure IP whitelist for admin access
Helm support (Kubernetes)
Manage Kubernetes clusters too:
# Add Kubernetes endpoint
# Deploy Helm charts through UI
# Manage namespaces and deployments
# Same interface for Docker and K8s
Problems I hit
Agent can't connect
Portainer shows agent as "down".
# Fixed by
1. Checking firewall allows port 9001
2. Verifying agent container is running
3. Using IP address instead of hostname (DNS issues)
4. Checking docker.sock is mounted correctly
Lost access after update
Portainer update broke something.
# Fixed by
1. Restoring from backup (have backups!)
2. Or recreating container from scratch (data in volume persists)
3. Checking Portainer logs for specific error
Container shows wrong status
Portainer says stopped but Docker says running.
# Fixed by
1. Refreshing the page (cache issue)
2. Reconnecting the environment
3. Restarting Portainer container itself
Can't access container console
Console button doesn't work.
# Fixed by
1. Checking if image supports shell (some minimal images don't)
2. Trying different shell (/bin/bash, /bin/sh)
3. Verifying container is running
4. Checking if exec is supported in environment
Performance issues
Portainer becomes slow with many containers.
# Fixed by
1. Increasing resources for Portainer container
2. Reducing refresh interval
3. Archiving old environments not in use
4. Using filters to show only active containers
Portainer vs alternatives
| Portainer | Docker CLI | Rancher | Yacht | |
|---|---|---|---|---|
| Ease of use | ★★★★★ | ★★★☆☆ | ★★★☆☆ | ★★★★☆ |
| Web UI | Yes | No | Yes | Yes |
| Multi-host | Yes | Manual | Yes | Limited |
| Resource usage | Light | None | Heavy | Light |
| Team features | Good | None | Excellent | Basic |
| Learning curve | Low | Medium | High | Low |
| Best for | Docker management | Scripting/automation | Kubernetes | Home labs |
Portainer is the sweet spot for Docker management. Easier than CLI, lighter than Rancher, more features than Yacht.
Would I recommend it?
Absolutely. I use Portainer every day. Managing 50+ containers across 4 servers. Before Portainer, I'd spend way too much time SSHing into servers and running docker commands.
The multi-server management is the killer feature. See everything in one dashboard, switch environments with a click. No need to remember which container is on which server.
Logs viewer is super useful - see what's happening in real-time, filter by keyword. Way faster than docker logs with grep.
Team access is nice too. Give colleagues access to manage their own containers without giving them full server access.
It's free for most use cases. Only need paid version if you have huge teams or need enterprise features.
If you're running more than a few Docker containers, Portainer pays off immediately in time saved.
Links: portainer.io | GitHub: github.com/portainer/portainer | Docs: docs.portainer.io