compose.yaml.j2 7.9 KB

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