compose.yaml.j2 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ---
  2. services:
  3. {{ service_name }}:
  4. image: docker.io/library/traefik:v3.6.8
  5. {% if not swarm_enabled %}
  6. {% if container_name %}
  7. container_name: {{ container_name }}
  8. {% endif %}
  9. security_opt:
  10. - no-new-privileges:true
  11. {% endif %}
  12. {% if container_hostname %}
  13. hostname: {{ container_hostname }}
  14. {% endif %}
  15. command:
  16. - "--global.checkNewVersion=false"
  17. - "--global.sendAnonymousUsage=false"
  18. {% if container_loglevel %}
  19. - "--log.level={{ container_loglevel }}"
  20. {% endif %}
  21. - "--ping=true"
  22. - "--ping.entryPoint=ping"
  23. {% if accesslog_enabled %}
  24. - "--accesslog=true"
  25. {% endif %}
  26. {% if dashboard_enabled %}
  27. - "--api.dashboard=true"
  28. - "--api.insecure=true"
  29. {% endif %}
  30. {% if prometheus_enabled %}
  31. - "--metrics.prometheus=true"
  32. - "--metrics.prometheus.entryPoint=metrics"
  33. - "--metrics.prometheus.addRoutersLabels=true"
  34. {% endif %}
  35. - "--entrypoints.ping.address=:8082"
  36. {% if prometheus_enabled %}
  37. - "--entrypoints.metrics.address=:9090"
  38. {% endif %}
  39. - "--entrypoints.web.address=:80"
  40. - "--entrypoints.web.http.encodedCharacters.allowEncodedSlash=true"
  41. {% if traefik_tls_enabled and traefik_tls_redirect %}
  42. - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
  43. - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
  44. {% endif %}
  45. {% if traefik_tls_enabled %}
  46. - "--entrypoints.websecure.address=:443"
  47. - "--entrypoints.websecure.http.encodedCharacters.allowEncodedSlash=true"
  48. - "--certificatesresolvers.{{ traefik_tls_certresolver }}.acme.email={{ traefik_tls_acme_email }}"
  49. - "--certificatesresolvers.{{ traefik_tls_certresolver }}.acme.caServer=https://acme-v02.api.letsencrypt.org/directory"
  50. - "--certificatesresolvers.{{ traefik_tls_certresolver }}.acme.dnsChallenge.provider={{ traefik_tls_certresolver }}"
  51. - "--certificatesresolvers.{{ traefik_tls_certresolver }}.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
  52. {% endif %}
  53. {% if traefik_tls_secure_ciphers %}
  54. - "--tls.options.default.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
  55. {% endif %}
  56. {% if traefik_tls_skipverify %}
  57. - "--serversTransport.insecureSkipVerify=true"
  58. {% endif %}
  59. {% if swarm_enabled %}
  60. - "--providers.swarm.endpoint=unix:///var/run/docker.sock"
  61. - "--providers.swarm.exposedByDefault=false"
  62. - "--providers.swarm.network={{ traefik_network }}"
  63. {% else %}
  64. - "--providers.docker=true"
  65. - "--providers.docker.exposedByDefault=false"
  66. - "--providers.docker.network={{ traefik_network }}"
  67. {% endif %}
  68. ports:
  69. - "{{ ports_http }}:80"
  70. - "{{ ports_https }}:443"
  71. {% if dashboard_enabled %}
  72. - "{{ ports_dashboard }}:8080"
  73. {% endif %}
  74. {#
  75. We always need volumes, because of the docker socket and certs storage
  76. - certs storage for ACME
  77. - docker socket for automatic service discovery
  78. - Traefik configuration in non-swarm mode
  79. #}
  80. volumes:
  81. - /var/run/docker.sock:/var/run/docker.sock:ro
  82. {% if volume_mode == 'mount' %}
  83. - {{ volume_mount_path }}:/var/traefik/certs/:rw
  84. {% elif volume_mode == 'local' or volume_mode == 'nfs' %}
  85. - {{ service_name }}_certs:/var/traefik/certs/:rw
  86. {% endif %}
  87. environment:
  88. - TZ={{ container_timezone }}
  89. {% if traefik_tls_enabled %}
  90. {% if traefik_tls_certresolver == 'cloudflare' %}
  91. {% if swarm_enabled %}
  92. - CF_DNS_API_TOKEN_FILE=/run/secrets/{{ service_name }}_token
  93. {% else %}
  94. - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
  95. {% endif %}
  96. {% elif traefik_tls_certresolver == 'porkbun' %}
  97. {% if swarm_enabled %}
  98. - PORKBUN_API_KEY_FILE=/run/secrets/{{ service_name }}_token
  99. - PORKBUN_SECRET_API_KEY_FILE=/run/secrets/{{ service_name }}_token_key
  100. {% else %}
  101. - PORKBUN_API_KEY=${PORKBUN_API_KEY}
  102. - PORKBUN_SECRET_API_KEY=${PORKBUN_SECRET_API_KEY}
  103. {% endif %}
  104. {% elif traefik_tls_certresolver == 'route53' %}
  105. {% if swarm_enabled %}
  106. - AWS_ACCESS_KEY_ID_FILE=/run/secrets/{{ service_name }}_token
  107. - AWS_SECRET_ACCESS_KEY_FILE=/run/secrets/{{ service_name }}_token_key
  108. {% else %}
  109. - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
  110. - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
  111. {% endif %}
  112. - AWS_REGION={{ traefik_tls_acme_region }}
  113. {% elif traefik_tls_certresolver == 'digitalocean' %}
  114. {% if swarm_enabled %}
  115. - DO_AUTH_TOKEN_FILE=/run/secrets/{{ service_name }}_token
  116. {% else %}
  117. - DO_AUTH_TOKEN=${DO_AUTH_TOKEN}
  118. {% endif %}
  119. {% elif traefik_tls_certresolver == 'godaddy' %}
  120. {% if swarm_enabled %}
  121. - GODADDY_API_KEY_FILE=/run/secrets/{{ service_name }}_token
  122. - GODADDY_API_SECRET_FILE=/run/secrets/{{ service_name }}_token_key
  123. {% else %}
  124. - GODADDY_API_KEY=${GODADDY_API_KEY}
  125. - GODADDY_API_SECRET=${GODADDY_API_SECRET}
  126. {% endif %}
  127. {% elif traefik_tls_certresolver == 'azure' %}
  128. {% if swarm_enabled %}
  129. - AZURE_CLIENT_ID_FILE=/run/secrets/{{ service_name }}_token
  130. - AZURE_CLIENT_SECRET_FILE=/run/secrets/{{ service_name }}_token_key
  131. {% else %}
  132. - AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
  133. - AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
  134. {% endif %}
  135. - AZURE_TENANT_ID={{ traefik_tls_acme_tenant_id }}
  136. - AZURE_SUBSCRIPTION_ID={{ traefik_tls_acme_subscription_id }}
  137. - AZURE_RESOURCE_GROUP={{ traefik_tls_acme_resource_group }}
  138. {% elif traefik_tls_certresolver == 'namecheap' %}
  139. {% if swarm_enabled %}
  140. - NAMECHEAP_API_KEY_FILE=/run/secrets/{{ service_name }}_token
  141. {% else %}
  142. - NAMECHEAP_API_KEY=${NAMECHEAP_API_KEY}
  143. {% endif %}
  144. - NAMECHEAP_API_USER={{ traefik_tls_acme_username }}
  145. {% elif traefik_tls_certresolver == 'ovh' %}
  146. - OVH_ENDPOINT={{ traefik_tls_acme_endpoint | default('ovh-eu') }}
  147. {% if swarm_enabled %}
  148. - OVH_APPLICATION_KEY_FILE=/run/secrets/{{ service_name }}_token
  149. - OVH_APPLICATION_SECRET_FILE=/run/secrets/{{ service_name }}_token_key
  150. - OVH_CONSUMER_KEY_FILE=/run/secrets/{{ service_name }}_consumer_key
  151. {% else %}
  152. - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY}
  153. - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET}
  154. - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY}
  155. {% endif %}
  156. {% endif %}
  157. {% endif %}
  158. healthcheck:
  159. test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8082/ping"]
  160. interval: 30s
  161. timeout: 5s
  162. retries: 3
  163. start_period: 10s
  164. networks:
  165. - {{ traefik_network }}
  166. {% if swarm_enabled %}
  167. {% if traefik_tls_enabled %}
  168. secrets:
  169. - {{ service_name }}_token
  170. {% if traefik_tls_acme_secret_key %}
  171. - {{ service_name }}_token_key
  172. {% endif %}
  173. {% if traefik_tls_certresolver == 'ovh' %}
  174. - {{ service_name }}_consumer_key
  175. {% endif %}
  176. {% endif %}
  177. deploy:
  178. mode: {{ swarm_placement_mode }}
  179. {% if swarm_placement_mode == 'replicated' %}
  180. replicas: {{ swarm_replicas }}
  181. {% endif %}
  182. {% if swarm_placement_host %}
  183. placement:
  184. constraints:
  185. - node.hostname == {{ swarm_placement_host }}
  186. {% endif %}
  187. {% else %}
  188. restart: {{ restart_policy }}
  189. {% endif %}
  190. {#
  191. If Traefik TLS is enabled in swarm mode, define the necessary secrets for ACME DNS challenge.
  192. #}
  193. {% if swarm_enabled and traefik_tls_enabled %}
  194. secrets:
  195. {{ service_name }}_token:
  196. file: ./.env.secret.token
  197. {% if traefik_tls_acme_secret_key %}
  198. {{ service_name }}_token_key:
  199. file: ./.env.secret.token_key
  200. {% endif %}
  201. {% if traefik_tls_certresolver == 'ovh' %}
  202. {{ service_name }}_consumer_key:
  203. file: ./.env.secret.consumer_key
  204. {% endif %}
  205. {% endif %}
  206. {#
  207. Always define the traefik network, but if it's not external, set it up according to
  208. swarm mode or bridge mode.
  209. #}
  210. networks:
  211. {{ traefik_network }}:
  212. {% if traefik_network_external %}
  213. external: true
  214. {% else %}
  215. {% if swarm_enabled %}
  216. driver: overlay
  217. attachable: true
  218. {% else %}
  219. driver: bridge
  220. {% endif %}
  221. name: {{ traefik_network }}
  222. {% endif %}
  223. {#
  224. Always define volumes for certs based on volume_mode
  225. #}
  226. {% if volume_mode == 'local' %}
  227. volumes:
  228. {{ service_name }}_certs:
  229. driver: local
  230. {% elif volume_mode == 'nfs' %}
  231. volumes:
  232. {{ service_name }}_certs:
  233. driver: local
  234. driver_opts:
  235. type: nfs
  236. o: addr={{ volume_nfs_server }},nfsvers=4,{{ volume_nfs_options }}
  237. device: ":{{ volume_nfs_path }}"
  238. {% endif %}