#cloud-config package_update: true package_upgrade: true packages: - wget - docker.io - docker-compose write_files: - path: /opt/traefik/docker-compose.yml content: | version: '3.7' services: traefik: image: traefik:v3.0 container_name: traefik restart: unless-stopped ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik.yml:/etc/traefik/traefik.yml:ro - ./dynamic.yml:/etc/traefik/dynamic.yml:ro - ./acme.json:/acme.json labels: - "traefik.enable=true" - "traefik.http.routers.dashboard.rule=Host(``traefik.localhost``)" - "traefik.http.routers.dashboard.service=api@internal" networks: - traefik networks: traefik: external: true - path: /opt/traefik/traefik.yml content: | api: dashboard: true insecure: true entryPoints: web: address: ":80" websecure: address: ":443" providers: docker: exposedByDefault: false file: filename: /etc/traefik/dynamic.yml watch: true certificatesResolvers: letsencrypt: acme: email: admin@example.com storage: /acme.json httpChallenge: entryPoint: web - path: /opt/traefik/dynamic.yml content: | http: middlewares: default-headers: headers: frameDeny: true sslRedirect: true browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 - path: /opt/traefik/acme.json content: "" permissions: '0600' runcmd: # Create directory - mkdir -p /opt/traefik - cd /opt/traefik # Set permissions - chmod 600 acme.json # Start Docker - systemctl enable docker - systemctl start docker # Create network - docker network create traefik # Start Traefik - docker-compose up -d # Configure firewall - ufw allow 80/tcp - ufw allow 443/tcp - ufw allow 8080/tcp - echo "Traefik dashboard available at http://localhost:8080"