π©πͺ Deutsch | π«π· FranΓ§ais
A production-ready Docker stack for Portainer CE with full Traefik v2+ integration, HTTPS/SSL support, and modern security features.
- Features
- Prerequisites
- Installation
- Configuration
- Traefik Labels
- Usage
- Security
- Troubleshooting
- License
- β Portainer CE - Modern Docker management interface
- β Traefik Integration - Automatic routing and SSL certificates
- β Let's Encrypt - Automatic HTTPS certificates
- β Persistent Storage - Data persists across container updates
- β Production-Ready - Best practices for security and performance
- Docker Engine 20.10+
- Docker Compose v2.0+
- Running Traefik v2+ reverse proxy
- Domain with DNS record pointing to your server
The stack requires an external Docker network for Traefik:
docker network create traefik_proxy_networkThis stack uses the following Traefik middlewares (optional):
redirect-to-https@file- HTTP β HTTPS redirectgeo-block@file- Geo-blocking (23 high-risk countries)security-headers@file- Security headers (HSTS, X-Frame-Options)compression@file- Gzip/Brotli compressionrate-limit@file- DoS protection (100 req/s)
If these middlewares are not available, remove them from the labels or create them in your traefik-dynamic.yaml.
git clone https://github.com/csaeum/DockerStackPortainer.git
cd DockerStackPortainercp .env.example .env
nano .envAdjust the values in .env:
COMPOSE_PROJECT_NAME=portainer
HOSTRULE=Host(`portainer.your-domain.com`)
PROXY_NETWORK=traefik_proxy_network
RESTART=unless-stoppeddocker-compose up -d- Open
https://portainer.your-domain.comin your browser - Create an admin user (password min. 12 characters)
- Select "Docker Standalone" as environment
- Done! You can now manage Docker containers
The stack uses the following configuration:
volumes:
portainer_data:
driver: local
driver_opts:
device: ${PWD}/volumes # Persistent storage
o: bind
type: none
services:
portainer:
image: portainer/portainer-ce:lts
command: -H unix:///var/run/docker.sock
container_name: ${COMPOSE_PROJECT_NAME}
networks:
- ${PROXY_NETWORK}
restart: ${RESTART}
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock # Docker accessPortainer data is stored in ./volumes/:
- Users, teams, roles
- Settings and configurations
- Container templates
- Registries
Important: Back up this folder regularly!
labels:
- traefik.enable=true
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=${HOSTRULE}
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=websecure-https
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls.certresolver=letsEncrypt
- traefik.http.services.${COMPOSE_PROJECT_NAME}.loadBalancer.server.port=9000For maximum security, add the following labels:
labels:
- traefik.enable=true
# HTTP Router (for HTTPS redirect)
- traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.rule=${HOSTRULE}
- traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.entrypoints=web-http
- traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.middlewares=redirect-to-https@file
# HTTPS Router
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=${HOSTRULE}
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=websecure-https
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls.certresolver=letsEncrypt
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls.options=modern@file
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=geo-block@file,security-headers@file,compression@file,rate-limit@file
- traefik.http.services.${COMPOSE_PROJECT_NAME}.loadBalancer.server.port=9000Benefits:
- β Automatic HTTP β HTTPS redirect
- β TLS 1.3 enforced
- β Geo-blocking against high-risk countries
- β HSTS and security headers
- β Brute-force protection via rate-limiting
# Start stack
docker-compose up -d
# View logs
docker-compose logs -f
# Stop stack
docker-compose down
# Restart stack
docker-compose restart
# Delete stack including volumes (CAUTION!)
docker-compose down -v# Stop Portainer
docker-compose down
# Create backup
tar -czf portainer-backup-$(date +%Y%m%d).tar.gz volumes/
# Restart stack
docker-compose up -d# Stop stack
docker-compose down
# Delete old data
rm -rf volumes/*
# Restore backup
tar -xzf portainer-backup-YYYYMMDD.tar.gz
# Start stack
docker-compose up -d- Strong Admin Password - Min. 16 characters, special chars, numbers
- Enable 2FA - In Portainer: User β My account β Enable 2FA
- Use Geo-Blocking - Traefik middleware
geo-block@file - Rate-Limiting - Protection against brute-force attacks
- Regular Updates -
docker-compose pull && docker-compose up -d - IP Whitelisting - If you always access from the same IP
Create a Traefik middleware:
# In traefik-dynamic.yaml
http:
middlewares:
portainer-ip-whitelist:
ipWhiteList:
sourceRange:
- "192.168.1.0/24" # Your local network
- "1.2.3.4/32" # Your office IPAdd it to the labels:
- traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=portainer-ip-whitelist@file,geo-block@file,security-headers@filePortainer requires access to /var/run/docker.sock - this means full root access to the Docker host!
Important:
- Never expose Portainer publicly without authentication
- Only grant trusted users Portainer admin access
- Regularly review audit logs
Cause: Container not in Traefik network
# Check network
docker network inspect traefik_proxy_network
# Restart container
docker-compose down && docker-compose up -dCause: Port 9000 is incorrect or container not running
# Check container status
docker-compose ps
# Check logs
docker-compose logs portainer
# Inspect container network
docker exec -it portainer shCause: DNS not pointing to your server or rate-limit reached
# Check DNS
dig portainer.your-domain.com +short
# Check Traefik logs
docker logs traefik 2>&1 | grep -i acmeCause: Session cookies invalid after container restart
# Clear browser cache
# Or: Use private/incognito window- Portainer Version:
portainer/portainer-ce:lts - Required Port: 9000 (internal only, accessible via Traefik)
- Volumes:
./volumes/(bind-mount) - Network:
traefik_proxy_network(external)
Contributions are welcome! Please create a pull request or open an issue.
This project is licensed under the GPL-3.0-or-later License - see LICENSE for details.
Made with β€οΈ by WSC - Web SEO Consulting
This project is free and open source. If it helped you, I appreciate your support: