Skip to content

Latest commit

Β 

History

History
343 lines (244 loc) Β· 8.46 KB

File metadata and controls

343 lines (244 loc) Β· 8.46 KB

Portainer Docker Stack with Traefik Integration

πŸ‡©πŸ‡ͺ Deutsch | πŸ‡«πŸ‡· FranΓ§ais

A production-ready Docker stack for Portainer CE with full Traefik v2+ integration, HTTPS/SSL support, and modern security features.

πŸ“‹ Table of Contents

✨ Features

  • βœ… 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

πŸ”§ Prerequisites

  • Docker Engine 20.10+
  • Docker Compose v2.0+
  • Running Traefik v2+ reverse proxy
  • Domain with DNS record pointing to your server

Traefik Network

The stack requires an external Docker network for Traefik:

docker network create traefik_proxy_network

Required Traefik Middlewares

This stack uses the following Traefik middlewares (optional):

  • redirect-to-https@file - HTTP β†’ HTTPS redirect
  • geo-block@file - Geo-blocking (23 high-risk countries)
  • security-headers@file - Security headers (HSTS, X-Frame-Options)
  • compression@file - Gzip/Brotli compression
  • rate-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.

πŸ“¦ Installation

Step 1: Clone repository

git clone https://github.com/csaeum/DockerStackPortainer.git
cd DockerStackPortainer

Step 2: Configure environment variables

cp .env.example .env
nano .env

Adjust the values in .env:

COMPOSE_PROJECT_NAME=portainer
HOSTRULE=Host(`portainer.your-domain.com`)
PROXY_NETWORK=traefik_proxy_network
RESTART=unless-stopped

Step 3: Start the stack

docker-compose up -d

Step 4: Initial setup

  1. Open https://portainer.your-domain.com in your browser
  2. Create an admin user (password min. 12 characters)
  3. Select "Docker Standalone" as environment
  4. Done! You can now manage Docker containers

βš™οΈ Configuration

docker-compose.yaml

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 access

Volumes

Portainer data is stored in ./volumes/:

  • Users, teams, roles
  • Settings and configurations
  • Container templates
  • Registries

Important: Back up this folder regularly!

🏷️ Traefik Labels

Basic Configuration (current)

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=9000

Advanced Configuration (recommended)

For 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=9000

Benefits:

  • βœ… Automatic HTTP β†’ HTTPS redirect
  • βœ… TLS 1.3 enforced
  • βœ… Geo-blocking against high-risk countries
  • βœ… HSTS and security headers
  • βœ… Brute-force protection via rate-limiting

πŸš€ Usage

Stack Management

# 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

Create Backup

# Stop Portainer
docker-compose down

# Create backup
tar -czf portainer-backup-$(date +%Y%m%d).tar.gz volumes/

# Restart stack
docker-compose up -d

Restore from Backup

# 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

πŸ”’ Security

Best Practices

  1. Strong Admin Password - Min. 16 characters, special chars, numbers
  2. Enable 2FA - In Portainer: User β†’ My account β†’ Enable 2FA
  3. Use Geo-Blocking - Traefik middleware geo-block@file
  4. Rate-Limiting - Protection against brute-force attacks
  5. Regular Updates - docker-compose pull && docker-compose up -d
  6. IP Whitelisting - If you always access from the same IP

IP Whitelisting (optional)

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 IP

Add it to the labels:

- traefik.http.routers.${COMPOSE_PROJECT_NAME}.middlewares=portainer-ip-whitelist@file,geo-block@file,security-headers@file

Docker Socket Security

Portainer 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

πŸ› Troubleshooting

Problem: 404 Not Found

Cause: Container not in Traefik network

# Check network
docker network inspect traefik_proxy_network

# Restart container
docker-compose down && docker-compose up -d

Problem: 502 Bad Gateway

Cause: 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 sh

Problem: Let's Encrypt Certificate Error

Cause: 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 acme

Problem: 401 Unauthorized after Update

Cause: Session cookies invalid after container restart

# Clear browser cache
# Or: Use private/incognito window

πŸ“Š Stack Information

  • Portainer Version: portainer/portainer-ce:lts
  • Required Port: 9000 (internal only, accessible via Traefik)
  • Volumes: ./volumes/ (bind-mount)
  • Network: traefik_proxy_network (external)

🀝 Contributing

Contributions are welcome! Please create a pull request or open an issue.

πŸ“„ License

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:

Buy Me a Coffee GitHub Sponsors PayPal


πŸ”— Links