Portainer Docker Setup: Manage Every Container from One Dashboard
If you have ever typed docker ps five times in one hour, you know the pain. Terminal management works for one container. It breaks when you have ten. Portainer gives you a visual interface for Docker—containers, images, networks, volumes, and even remote nodes—all from a single dashboard. This guide walks you through a production-ready Portainer Docker setup, from a single server to a secured, multi-node management plane.
If you want a faster walkthrough focused on the basics, check out Portainer Docker Setup: Stop Managing Containers from the Terminal.
What You Will Build
By the end of this guide you will have:
- Portainer CE running in Docker with persistent data
- HTTPS access with a proper SSL certificate
- Multiple Docker environments managed from one UI
- Stack deployments via Git-backed Docker Compose files
- User access controls for team-based container management
Prerequisites
Before you start, gather the following:
- A Linux server (Ubuntu 22.04+ or Debian 12+) with Docker installed
- At least 1 CPU core and 1 GB RAM (2 GB recommended for multi-node setups)
- A domain or subdomain pointed at your server (for HTTPS)
- Basic familiarity with Docker and Docker Compose
- Ports 8000 and 9443 available (or 9000 for HTTP legacy access)
Verify Docker is running:
docker --version
docker compose version
docker ps
If Docker is not installed:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Step 1: Deploy Portainer with Docker Compose
The cleanest way to run Portainer is a single Docker Compose file. It defines the volume, the socket mount, and the ports.
Create a project directory:
mkdir ~/portainer && cd ~/portainer
Write a docker-compose.yml:
version: "3.8"
services:
portainer:
image: portainer/portainer-ce:lts
container_name: portainer
restart: always
ports:
- "8000:8000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
networks:
- portainer-net
volumes:
portainer_data:
name: portainer_data
networks:
portainer-net:
name: portainer_network
Start the container:
docker compose up -d
Verify it is running:
docker ps --filter name=portainer
Open https://your-server-ip:9443 in a browser. Portainer generates a self-signed certificate by default, so you will see a security warning. Skip it for now—we fix that in Step 3.
Step 2: Complete Initial Setup
On first launch, Portainer asks you to create an admin user. Do this immediately—there is no default password.
- Navigate to
https://your-server-ip:9443 - Create an admin username and password (use a strong password)
- Select Manage the local Docker environment
- Click Get Started
You now see the Portainer dashboard with your local Docker environment. You can already view containers, start and stop them, inspect logs, and manage volumes. But we are not done yet.
Step 3: Secure Portainer with HTTPS and a Reverse Proxy
Self-signed certificates are fine for testing. In production, you want a real certificate and a clean domain. The easiest path is Caddy.
Add Caddy to Your Compose File
Update your docker-compose.yml:
version: "3.8"
services:
portainer:
image: portainer/portainer-ce:lts
container_name: portainer
restart: always
expose:
- "9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
networks:
- portainer-net
caddy:
image: caddy:2.8
container_name: caddy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
networks:
- portainer-net
volumes:
portainer_data:
name: portainer_data
caddy-data:
caddy-config:
networks:
portainer-net:
name: portainer_network
Create Caddyfile:
portainer.yourdomain.com {
reverse_proxy portainer:9443
tls internal
}
Restart the stack:
docker compose down
docker compose up -d
Once DNS propagates, Caddy fetches a Let's Encrypt certificate automatically. Your Portainer instance is now at https://portainer.yourdomain.com with a trusted certificate.
For a deeper look at visual management patterns and team workflows, read Portainer Docker Setup: The Developer's Guide to Visual Container Management.
Step 4: Add a Remote Docker Environment
Portainer shines when you manage more than one server. You can add remote Docker hosts via the Portainer Agent.
Install the Agent on a Remote Server
On the remote server, run:
docker run -d \
-p 9001:9001 \
--name portainer_agent \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
portainer/agent:lts
Port 9001 is the agent's API. Ensure it is open in your firewall:
sudo ufw allow 9001/tcp
Add the Environment in Portainer
- In Portainer, go to Environments → Add Environment
- Select Docker Standalone over Agent
- Enter the remote server's IP and port 9001
- Give it a name like
prod-server-02 - Click Connect
You now have two servers in one dashboard. Switch between them with a dropdown. No more SSH context switching.
Step 5: Deploy Stacks from Git
Portainer can pull Docker Compose files from Git and deploy them automatically. This turns Portainer into a lightweight CI/CD frontend for your containers.
Create a Stack from a Git Repository
- In Portainer, go to Stacks → Add Stack
- Select Git Repository
- Enter your repository URL (e.g.,
https://github.com/your-org/infrastructure) - Set the Compose path (e.g.,
docker-compose.ymlorstacks/app.yml) - Enable Automatic updates if you want Portainer to redeploy on every Git push
- Click Deploy the stack
Portainer clones the repo, reads the Compose file, and deploys it to the selected environment. You can view logs, scale services, and update the stack from the UI.
If you are tired of typing Docker commands and want a more human-friendly approach, Portainer Docker Setup: Stop Typing docker ps and Start Managing Containers Like a Human covers the day-to-day UI workflow in detail.
Step 6: Configure Teams and Access Control
Running Portainer as a single admin is fine for personal use. For teams, you need users, teams, and role-based access.
Create a Team and Assign Access
- Go to Users → Teams and create a team (e.g.,
Developers) - Go to Users and add team members
- Go to Environments, select an environment, and click Manage access
- Assign the
Developersteam with Operator or User role
Operators can start, stop, and view logs. Users have read-only access. Admins manage everything. This prevents accidental container deletion by someone who just wanted to check logs.
Tips and Troubleshooting
Portainer shows a blank page or connection refused
- Verify the container is running:
docker ps --filter name=portainer - Check that port 9443 is not blocked by a firewall
- If using a reverse proxy, confirm the upstream port matches the exposed container port
Cannot connect to the Docker socket
- Ensure
/var/run/docker.sockis mounted read-write into the Portainer container - On SELinux-enabled systems, add the
--privilegedflag or set the proper SELinux context
Remote agent connection fails
- Verify port 9001 is open on the remote server firewall
- Check that the agent container is running on the remote host
- Ensure the Portainer Server can reach the remote IP on port 9001 (test with
telnetornc)
SSL certificate errors behind reverse proxy
- Portainer uses a self-signed cert internally. If Caddy or Nginx handles TLS, let the proxy trust the backend or use HTTP internally
- Alternatively, mount your own certificates into Portainer and disable the reverse proxy's SSL handling
Stack deployment from Git fails
- Confirm the repository is accessible (public or credentials configured)
- Verify the Compose file path is correct relative to the repo root
- Check the Portainer logs for parsing errors: Containers → portainer → Logs
Data loss after container restart
- Ensure the
portainer_datavolume is a named volume or host bind mount, not an anonymous volume - Without persistent storage, all settings, users, and environments reset on redeploy
Next Steps
You now have a working Portainer Docker setup with HTTPS, remote node management, Git-backed stacks, and team access controls. That is more than most teams start with. From here, consider:
- Enabling Docker Swarm mode and managing swarm services from Portainer
- Setting up registry authentication for private image repositories
- Configuring backup jobs for the Portainer data volume
- Using Portainer's Edge Agent for devices behind NAT or firewall
- Integrating webhooks for automatic stack redeployment on Git pushes
Container management does not have to mean memorizing flags. With Portainer, you see what is running, fix what is broken, and deploy what is next—all from one place.
Need Help at Scale?
If you are running production workloads and need Swarm orchestration, multi-team RBAC, custom registry integration, or migration from Rancher, we can help. Contact the Sysbrix team and we will build a container management layer that fits your infrastructure.