add traefik container role

This commit is contained in:
Kevin Heyer 2025-06-14 17:15:24 +02:00
parent 12635d0a43
commit e83d05b79b
10 changed files with 271 additions and 0 deletions

View file

@ -0,0 +1,35 @@
---
container_traefik_version: "latest"
container_traefik_http_port: 80
container_traefik_https_port: 443
container_traefik_domain: "example.com"
container_traefik_san_domains:
- "example.com"
- "example.org"
container_traefik_cloudflare_mail: "your-email@example.com"
container_traefik_cloudflare_token: "your-cloudflare-token"
container_traefik_basicauth_user: "admin"
container_traefik_basicauth_password: "yourpassword"
# Static Traefik Routes
container_traefik_routers:
traefik:
entryPoints:
- "https"
rule: "Host(`example.example.com`)"
middlewares:
- default-headers
tls: {}
service: traefik
container_traefik_services:
traefik:
loadBalancer:
servers:
- url: "http://127.0.0.1"
passHostHeader: true
serversTransport: insecure-https
container_traefik_serversTransports:
insecure-https:
insecureSkipVerify: true

View file

@ -0,0 +1,57 @@
---
- name: Ensure data directories exist
ansible.builtin.file:
path: "{{ traefik_container_dir }}/data/{{ item }}"
state: directory
mode: '0755'
loop:
- "traefik"
- "certs"
- "logs"
- "traefik/config.d"
become: false
- name: Ensure log files exist
ansible.builtin.file:
path: "{{ traefik_container_dir }}/data/logs/{{ item }}"
state: touch
mode: '0644'
loop:
- "traefik.log"
- "access.log"
become: false
- name: Deploy Traefik configuration files
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ traefik_container_dir }}/data/{{ item.dest }}"
mode: '0644'
loop:
- { src: 'traefik.yml.j2', dest: 'traefik/traefik.yml' }
- { src: 'default.yml.j2', dest: 'traefik/config.d/default.yml' }
- { src: 'hosts.yml.j2', dest: 'traefik/config.d/hosts.yml' }
become: false
- name: Deploy Docker Compose and .env files
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ traefik_container_dir }}/{{ item.dest }}"
mode: '0644'
loop:
- { src: 'docker-compose.yml.j2', dest: 'docker-compose.yml' }
- { src: '.env.j2', dest: '.env' }
become: false
- name: Ensure Docker network exists
community.docker.docker_network:
name: traefik
state: present
docker_host: "unix:///run/user/1000/docker.sock"
become: false
- name: Start Traefik container
community.docker.docker_compose_v2:
project_src: "{{ traefik_container_dir }}"
pull: always
docker_host: "unix:///run/user/1000/docker.sock"
become: false

View file

@ -0,0 +1,29 @@
# Traefik Version
# Defines the version of Traefik to be used. By default, "latest" is used.
TRAEFIK_VERSION={{ container_traefik_version }}
TRAEFIK_DOMAIN={{ container_traefik_domain }}
# Ports
# Defines the ports on which Traefik will be available for HTTP and HTTPS traffic.
# By default, these are 80 (HTTP) and 443 (HTTPS).
TRAEFIK_HTTP_PORT={{ container_traefik_http_port }}
TRAEFIK_HTTPS_PORT={{ container_traefik_https_port }}
# Cloudflare API Access
# Your Cloudflare API credentials that Traefik uses to automatically obtain TLS certificates
# via the Cloudflare DNS provider.
# Replace the following placeholders with your actual Cloudflare details:
# - CLOUDFLARE_MAIL: Your Cloudflare email address
# - CLOUDFLARE_TOKEN: Your Cloudflare API token
CLOUDFLARE_MAIL={{ container_traefik_cloudflare_mail }}
CLOUDFLARE_TOKEN={{ container_traefik_cloudflare_token }}
# Basic Auth Configuration
# Basic authentication credentials for securing the Traefik dashboard.
# You can generate the password using the following command:
# echo $(htpasswd -nB yourusername) | sed -e s/\\$/\\$\\$/g
# Replace `yourusername` with the desired username.
# The generated value can then be placed in the `BASICAUTH_PASSWORD` variable.
TRAEFIK_BASICAUTH_USER={{ container_traefik_basicauth_user }}
TRAEFIK_BASICAUTH_PASSWORD={{ container_traefik_basicauth_password }}

View file

@ -0,0 +1,19 @@
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https

View file

@ -0,0 +1,44 @@
---
services:
traefik:
image: traefik:${TRAEFIK_VERSION}
container_name: traefik
restart: always
security_opt:
- "no-new-privileges:true"
networks:
- traefik
ports:
- ${TRAEFIK_HTTP_PORT}:80
- ${TRAEFIK_HTTPS_PORT}:443
volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock:ro
- ./data/traefik:/etc/traefik
- ./data/certs:/etc/certs:ro
- ./data/logs/traefik.log:/var/log/traefik.log
- ./data/logs/access.log:/var/log/crowdsec/traefik.log
environment:
- "CF_API_EMAIL=${CLOUDFLARE_MAIL:?error}"
- "CF_DNS_API_TOKEN=${CLOUDFLARE_TOKEN:?error}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_DOMAIN}`)"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.middlewares.basic-auth.basicauth.users=${TRAEFIK_BASICAUTH_USER}:${TRAEFIK_BASICAUTH_PASSWORD}"
- "traefik.http.routers.traefik-secure.middlewares=basic-auth"
- "traefik.http.routers.traefik-secure.rule=Host(`${TRAEFIK_DOMAIN}`)"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
{% for domain in container_traefik_san_domains %}
- "traefik.http.routers.traefik-secure.tls.domains[{{ loop.index0 }}].main={{ domain }}"
- "traefik.http.routers.traefik-secure.tls.domains[{{ loop.index0 }}].sans=*.{{ domain }}"
{% endfor %}
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
traefik:
external: true

View file

@ -0,0 +1,42 @@
http:
routers:
{% for router_name, router in container_traefik_routers.items() %}
{{ router_name }}:
entryPoints:
{% for ep in router.entryPoints %}
- "{{ ep }}"
{% endfor %}
rule: "{{ router.rule }}"
{% if router.middlewares is defined and router.middlewares %}
middlewares:
{% for m in router.middlewares %}
- {{ m }}
{% endfor %}
{% endif %}
{% if router.tls is defined and router.tls %}
tls: {}
{% endif %}
service: {{ router.service }}
{% endfor %}
services:
{% for service_name, service in container_traefik_services.items() %}
{{ service_name }}:
loadBalancer:
servers:
{% for server in service.loadBalancer.servers %}
- url: "{{ server.url }}"
{% endfor %}
passHostHeader: {{ service.loadBalancer.passHostHeader | default(true) | lower }}
{% if service.loadBalancer.serversTransport is defined %}
serversTransport: {{ service.loadBalancer.serversTransport }}
{% endif %}
{% endfor %}
serversTransports:
{% for transport_name, transport in container_traefik_serversTransports.items() %}
{{ transport_name }}:
{% for key, value in transport.items() %}
{{ key }}: {{ value | lower if value is boolean else value }}
{% endfor %}
{% endfor %}

View file

@ -0,0 +1,43 @@
api:
dashboard: true
log:
level: INFO
format: json
filePath: "/var/log/traefik.log"
accessLog:
filePath: "/var/log/access.log"
bufferingSize: 50
entryPoints:
http:
address: ":80"
https:
address: ":443"
serversTransport:
insecureSkipVerify: false
forwardingTimeouts:
dialTimeout: 10s
responseHeaderTimeout: 10s
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
watch: true
file:
directory: "/etc/traefik/config.d/"
watch: true
certificatesResolvers:
cloudflare:
acme:
email: "{{ container_traefik_cloudflare_mail }}"
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"

View file

@ -0,0 +1,2 @@
---
traefik_container_dir: "/opt/docker/traefik"