compose.yaml.j2 8.1 KB

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