Portainer

# prepare certificate
step ca certificate docker.home.kokomi.site /data/smallstep/portainer.crt /data/smallstep/portainer-key
# automatic renew daemon
nohup step ca renew --daemon --expires-in 30h /data/smallstep/portainer.crt /data/smallstep/portainer-key &
 
docker volume create portainer_data
docker run -d -p 9443:9443 --name portainer --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /data/portainer/certs:/certs \
  -v portainer_data:/data \
  portainer/portainer-ce:lts \
  --sslcert /certs/portainer.crt --sslkey /certs/portainer-key

因为 portainer 容器内缺少 shell,推荐用 cntr 进行调试,但注意在 LXC 中需要设置 ulimit

另外其他一些选型

  • DPanel 界面设计过时,功能与 1Panel 类区分不大、功能多于需求
  • Dockge 专门给 Compose 设计的,界面很好,并且能展示完整的终端进度输出,可以作为 Portainer 的辅助。但直接用本地终端跑不就好了

Dockge

Traefik

version: "3.8"
services:
  traefik:
    image: traefik
    container_name: "traefik"
    restart: unless-stopped
	security_opt:
      - no-new-privileges:true
    # All static configuration is provided via command-line arguments
    command:
	  - "--api.dashboard=true"
      - "--api.insecure=false"
 
	  - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=proxy"
 
	  - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.websecure.http.tls=true"
    ports:
      # Expose HTTP port
      - "80:80"
      # Expose HTTPS port
      - "443:443"
      # Expose the dashboard (optional, for direct access if needed, but we use routing)
      - "8080:8080"
    volumes:
      # Mount the Docker socket to allow Traefik to listen to Docker events
      # Using :ro (read-only) is a security best practice
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      # Mount a named volume to persist Let's Encrypt certificates
      - "letsencrypt_data:/letsencrypt"
    networks:
      # Connect Traefik to the dedicated proxy network
      - "proxy"
    # Use labels to configure Traefik to expose its own dashboard
    labels:
      - "traefik.enable=true"
 
      # Dashboard router
      - "traefik.http.routers.dashboard.rule=Host(`docker.home.kokomi.site`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.tls=true"
 
      # Basic‑auth middleware
      #- "traefik.http.middlewares.dashboard-auth.basicauth.users=<PASTE_HASH_HERE>"
      #- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"
  whoami:
    image: traefik/whoami
    container_name: whoami
    restart: unless-stopped
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.home.kokomi.site`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
 
# Define the named volume for persisting certificate data
volumes:
  letsencrypt_data:
 
# Define the external network
networks:
  proxy:
    name: proxy