compose.yaml.j2 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. {% endif %}
  146. {% endif %}
  147. healthcheck:
  148. test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8082/ping"]
  149. interval: 30s
  150. timeout: 5s
  151. retries: 3
  152. start_period: 10s
  153. networks:
  154. - {{ traefik_network }}
  155. {% if swarm_enabled %}
  156. {% if traefik_tls_enabled %}
  157. secrets:
  158. - {{ service_name }}_token
  159. {% if traefik_tls_acme_secret_key %}
  160. - {{ service_name }}_token_key
  161. {% endif %}
  162. {% endif %}
  163. deploy:
  164. mode: {{ swarm_placement_mode }}
  165. {% if swarm_placement_mode == 'replicated' %}
  166. replicas: {{ swarm_replicas }}
  167. {% endif %}
  168. {% if swarm_placement_host %}
  169. placement:
  170. constraints:
  171. - node.hostname == {{ swarm_placement_host }}
  172. {% endif %}
  173. {% else %}
  174. restart: {{ restart_policy }}
  175. {% endif %}
  176. {#
  177. If Traefik TLS is enabled in swarm mode, define the necessary secrets for ACME DNS challenge.
  178. #}
  179. {% if swarm_enabled and traefik_tls_enabled %}
  180. secrets:
  181. {{ service_name }}_token:
  182. file: ./.env.secret.token
  183. {% if traefik_tls_acme_secret_key %}
  184. {{ service_name }}_token_key:
  185. file: ./.env.secret.token_key
  186. {% endif %}
  187. {% endif %}
  188. {#
  189. Always define the traefik network, but if it's not external, set it up according to
  190. swarm mode or bridge mode.
  191. #}
  192. networks:
  193. {{ traefik_network }}:
  194. {% if traefik_network_external %}
  195. external: true
  196. {% else %}
  197. {% if swarm_enabled %}
  198. driver: overlay
  199. attachable: true
  200. {% else %}
  201. driver: bridge
  202. {% endif %}
  203. name: {{ traefik_network }}
  204. {% endif %}
  205. {#
  206. Always define volumes for certs based on volume_mode
  207. #}
  208. {% if volume_mode == 'local' %}
  209. volumes:
  210. {{ service_name }}_certs:
  211. driver: local
  212. {% elif volume_mode == 'nfs' %}
  213. volumes:
  214. {{ service_name }}_certs:
  215. driver: local
  216. driver_opts:
  217. type: nfs
  218. o: addr={{ volume_nfs_server }},nfsvers=4,{{ volume_nfs_options }}
  219. device: ":{{ volume_nfs_path }}"
  220. {% endif %}