Portainer CE: Secure Docker Management UI on Linux
- Author :Liam K.
- Date :August 3, 2026
- Time :16 minutes
Portainer gives you a clean web UI for Docker without giving every engineer raw SSH access to the daemon. Used carefully, it speeds up stack deployments and troubleshooting. Used carelessly, it becomes a privileged attack surface. This guide installs Portainer CE the right way: HTTPS only, strong admin setup, and least-privilege team access.
Prerequisites
- Ubuntu 22.04+ or Debian 12 with Docker Engine and Compose plugin installed
- Domain for
portainer.example.com - Nginx or Caddy available for TLS termination
- Firewall allowing 80/443 only from trusted networks when possible
Step 1: Create Volumes and Compose File
sudo mkdir -p /opt/portainer
cd /opt/portainer
sudo tee docker-compose.yml >/dev/null <<'EOF'
services:
portainer:
image: portainer/portainer-ce:2.21.4
container_name: portainer
restart: unless-stopped
[...]Step 2: Put Portainer Behind Nginx TLS
sudo tee /etc/nginx/sites-available/portainer >/dev/null <<'EOF'
server {
listen 80;
server_name portainer.example.com;
location / {
proxy_pass https://127.0.0.1:9443;
proxy_ssl_verify off;
proxy_http_version 1.1;
[...]Step 3: Complete First-Time Admin Setup
Visit https://portainer.example.com within five minutes of first start and create the admin user. If the window expires, restart the container and try again. Use a long password and enable MFA in Settings → Authentication once the environment is online.
Step 4: Deploy a Sample Stack
# In Portainer UI: Stacks → Add stack → paste compose
# Example: whoami behind the same host network pattern
services:
whoami:
image: traefik/whoami:v1.10
restart: unless-stopped
ports:
- "127.0.0.1:8081:80"Step 5: Restrict Access and Roles
- Create non-admin users for day-to-day operators.
- Scope environment access per team instead of sharing the admin account.
- Prefer deploying via Git-backed stacks when possible to keep audit trails.
- Lock down source IPs with firewall or VPN if Portainer manages production hosts.
Step 6: Backup Portainer Data
sudo docker run --rm \
-v portainer_portainer_data:/data \
-v /var/backups:/backup \
alpine tar czf /backup/portainer-$(date +%F).tar.gz -C /data .
# Restore
sudo docker compose -f /opt/portainer/docker-compose.yml down
sudo docker run --rm \
-v portainer_portainer_data:/data \
[...]Production Checklist
- Never publish Portainer ports on
0.0.0.0without TLS and access control. - Keep Docker socket access limited to Portainer and trusted automation only.
- Pin image tags instead of using
latest. - Review users and API tokens quarterly.
- Document which stacks are managed in Portainer versus GitOps tooling.
"A container UI is an operations accelerator only when authentication, TLS, and change ownership are treated as production controls."
Technical Author

System administrator and technical writer specializing in server infrastructure, security and deployment. Creating comprehensive guides to help you master server administration.