Portainer CE: Secure Docker Management UI on Linux
Containers

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

bash
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
[...]
Command truncated. Copy to view full command.

Step 2: Put Portainer Behind Nginx TLS

bash
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;
[...]
Command truncated. Copy to view full command.

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

bash
# 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

bash
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 \
[...]
Command truncated. Copy to view full command.

Production Checklist

  • Never publish Portainer ports on 0.0.0.0 without 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

Technical Author - Liam K.
Liam K.

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