docker-compose.yml 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. version: '3.7'
  2. # Environment variables are replaced with definitions in .env, when run with:
  3. #
  4. # env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy --compose-file docker-compose.yml server
  5. networks:
  6. default:
  7. driver: overlay
  8. volumes:
  9. traefik-certs: {}
  10. services:
  11. traefik:
  12. image: traefik:v2.5.4
  13. ports:
  14. - 80:80
  15. - 443:443
  16. deploy:
  17. #replicas: 2 # https://youtu.be/btHpHjabRcc
  18. placement:
  19. constraints:
  20. - node.role == manager
  21. labels:
  22. - traefik.enable=true
  23. # Enable the dashboard UI
  24. - traefik.http.routers.api.rule=Host(`board.${DOMAIN}`)
  25. - traefik.http.routers.api.service=api@internal
  26. - traefik.http.routers.api.middlewares=auth
  27. - traefik.http.routers.api.tls=true
  28. - "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_API_USERS}"
  29. # Dummy service for Swarm port detection. The port can be any valid integer value.
  30. - traefik.http.services.dummy-svc.loadbalancer.server.port=9999
  31. - traefik.http.routers.traefik.tls=true
  32. # Use LS to get/renew certs for the TLD & subdomains
  33. - traefik.http.routers.traefik.tls.certresolver=le
  34. - traefik.http.routers.traefik.tls.domains[0].main=${DOMAIN}
  35. - traefik.http.routers.traefik.tls.domains[0].sans=*.${DOMAIN}
  36. volumes:
  37. - /var/run/docker.sock:/var/run/docker.sock:ro
  38. - ${CONTAINERS_DIR}/traefik/static.toml:/static.toml
  39. # cert storage can't be shared: https://doc.traefik.io/traefik/https/acme/#storage
  40. - traefik-certs:/certificates
  41. command:
  42. # Require a "traefik.enable=true" label
  43. - --providers.docker.exposedbydefault=false
  44. - --providers.docker.swarmmode=true
  45. # HTTP redirects to HTTPS
  46. - --entrypoints.web.address=:80
  47. - --entrypoints.web.http.redirections.entrypoint.permanent=false
  48. - --entrypoints.web.http.redirections.entryPoint.to=websecure
  49. - --entrypoints.web.http.redirections.entryPoint.scheme=https
  50. - --entrypoints.websecure.address=:443
  51. # Auto cert renewal via cloudflare
  52. - --certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL}
  53. - --certificatesresolvers.le.acme.storage=/certificates/acme.json
  54. - --certificatesresolvers.le.acme.dnschallenge.provider=cloudflare
  55. - --certificatesresolvers.le.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
  56. # debug, uncomment for testing
  57. #- --certificatesresolvers.le.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
  58. #- --log.level=DEBUG
  59. - --accesslog=true
  60. - --log=true
  61. # Enable the traefik dashboard
  62. - --api=true
  63. - --providers.file.filename=/static.toml
  64. environment:
  65. - CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL}
  66. - CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY}
  67. jekyll:
  68. image: jibby0/docker-jekyll-webhook
  69. deploy:
  70. replicas: 2
  71. labels:
  72. - traefik.enable=true
  73. - traefik.http.routers.jekyll.tls=true
  74. - traefik.http.routers.jekyll.rule=Host(`${DOMAIN}`)
  75. - traefik.http.services.jekyll.loadbalancer.server.port=80
  76. environment:
  77. - TZ=America/New_York
  78. - WEBHOOK_SECRET=${WEBHOOK_SECRET}
  79. - REPO=https://github.com/jibby0/blog.git
  80. restart: always
  81. volumes:
  82. - ${CONTAINERS_DIR}/jekyll/vendor_cache:/vendor
  83. postgres:
  84. image: postgres:13.2
  85. volumes:
  86. - ${CONTAINERS_DIR}/postgres/data:/var/lib/postgresql/data
  87. - ${CONTAINERS_DIR}/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
  88. environment:
  89. - POSTGRES_USER=${POSTGRES_USER}
  90. - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
  91. restart: always
  92. nextcloud:
  93. image: nextcloud:20.0.9
  94. deploy:
  95. labels:
  96. - traefik.enable=true
  97. - traefik.http.routers.nextcloud.tls=true
  98. - traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`)
  99. - traefik.http.services.nextcloud.loadbalancer.server.port=80
  100. expose:
  101. - "80"
  102. links:
  103. - postgres
  104. volumes:
  105. - ${CONTAINERS_DIR}/nextcloud:/var/www/html
  106. restart: always
  107. gogs:
  108. image: gogs/gogs:0.12.0
  109. deploy:
  110. labels:
  111. - traefik.enable=true
  112. - traefik.http.routers.gogs.tls=true
  113. - traefik.http.routers.gogs.rule=Host(`gogs.${DOMAIN}`)
  114. - traefik.http.services.gogs.loadbalancer.server.port=3000
  115. expose:
  116. - "3000"
  117. volumes:
  118. - ${CONTAINERS_DIR}/gogs:/data
  119. # NOTE: My gogs instance isn't happy with postgres. For now, it's a small server
  120. # and sqlite is fine, but I should fix this eventually.
  121. #links:
  122. # - postgres
  123. restart: always
  124. matrix:
  125. image: matrixdotorg/synapse:v1.46.0
  126. deploy:
  127. labels:
  128. - traefik.enable=true
  129. - traefik.http.routers.matrix.tls=true
  130. - traefik.http.routers.matrix.rule=Host(`matrix.${DOMAIN}`)
  131. - traefik.http.services.matrix.loadbalancer.server.port=8008
  132. expose:
  133. - "8008"
  134. links:
  135. - postgres
  136. # NOTE: These don't directly configure anything anymore.
  137. # They can be used with `migrate_config` to build
  138. # homeserver.yaml
  139. # environment:
  140. # - SYNAPSE_SERVER_NAME=matrix.${DOMAIN}
  141. # - SYNAPSE_REPORT_STATS=no
  142. # - SYNAPSE_NO_TLS=true
  143. # - SYNAPSE_ENABLE_REGISTRATION=no
  144. # - SYNAPSE_LOG_LEVEL=INFO
  145. # - SYNAPSE_REGISTRATION_SHARED_SECRET=${POSTGRES_PASSWORD}
  146. # - POSTGRES_DB=synapse
  147. # - POSTGRES_HOST=postgres
  148. # - POSTGRES_USER=synapse
  149. # - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
  150. volumes:
  151. - ${CONTAINERS_DIR}/matrix:/data
  152. restart: always
  153. matrix_wellknown:
  154. image: adrianrudnik/matrix-wellknown-server:1.0.1
  155. volumes:
  156. - ${CONTAINERS_DIR}/matrix/wellknown:/var/schema
  157. deploy:
  158. labels:
  159. - traefik.enable=true
  160. - traefik.http.routers.matrix-wellknown.tls=true
  161. - traefik.http.routers.matrix-wellknown.rule=Host(`matrix.${DOMAIN}`) && PathPrefix(`/.well-known/matrix/`)
  162. - traefik.http.services.matrix-wellknown.loadbalancer.server.port=8080
  163. expose:
  164. - "8080"
  165. selfoss:
  166. image: jibby0/selfoss:2.18
  167. deploy:
  168. labels:
  169. - traefik.enable=true
  170. - traefik.http.routers.selfoss.tls=true
  171. - traefik.http.routers.selfoss.rule=Host(`selfoss.${DOMAIN}`)
  172. - traefik.http.services.selfoss.loadbalancer.server.port=8888
  173. expose:
  174. - "8888"
  175. links:
  176. - postgres
  177. volumes:
  178. - ${CONTAINERS_DIR}/selfoss:/selfoss/data
  179. environment:
  180. - CRON_PERIOD=5m
  181. restart: always
  182. plex:
  183. image: ghcr.io/linuxserver/plex:version-1.25.1.5286-34f965be8
  184. deploy:
  185. labels:
  186. - traefik.enable=true
  187. - traefik.http.routers.plex.tls=true
  188. - traefik.http.routers.plex.rule=Host(`plex.${DOMAIN}`)
  189. - traefik.http.services.plex.loadbalancer.server.port=32400
  190. expose:
  191. - "32400"
  192. volumes:
  193. - ${CONTAINERS_DIR}/plex:/config
  194. - ${MEDIA_DIR}/Video/Movies:/movies:ro
  195. - ${MEDIA_DIR}/Video/Shows:/tv:ro
  196. - ${MEDIA_DIR}/Video/Anime:/Anime:ro
  197. - type: tmpfs
  198. target: /transcodes
  199. tmpfs:
  200. size: 12000000000 # ~12gb
  201. restart: always
  202. jellyfin:
  203. # 10.6.4 can't use Chromecasts properly: https://github.com/jellyfin/jellyfin/issues/3852
  204. # The "jellyfixer" service below fixes that for now. Assumes jellyfin's
  205. # baseURL is set to the default of `/jellyfin`
  206. image: jellyfin/jellyfin:10.6.4
  207. deploy:
  208. placement:
  209. constraints:
  210. - node.labels.media-encoding == true
  211. labels:
  212. - traefik.enable=true
  213. - traefik.http.routers.jellyfin.tls=true
  214. - traefik.http.routers.jellyfin.rule=Host(`jellyfin.${DOMAIN}`)
  215. - traefik.http.services.jellyfin.loadbalancer.server.port=8096
  216. expose:
  217. - "8096"
  218. volumes:
  219. - ${CONTAINERS_DIR}/jellyfin:/config
  220. - ${MEDIA_DIR}:/media
  221. restart: always
  222. jellyfixer:
  223. image: quay.io/xsteadfastx/jellyfixer:latest
  224. deploy:
  225. labels:
  226. - traefik.enable=true
  227. - traefik.http.routers.jellyfixer-secured.tls=true
  228. - traefik.http.routers.jellyfixer-secured.rule=Host(`jellyfin.${DOMAIN}`) && Path(`/jellyfin/System/Info/Public`)
  229. - traefik.http.services.jellyfixer-secured.loadbalancer.server.port=8088
  230. command: http://jellyfin:8096/jellyfin
  231. environment:
  232. - JELLYFIXER_INTERNAL_URL=http://jellyfin:8096/jellyfin
  233. - JELLYFIXER_EXTERNAL_URL=https://jellyfin.${DOMAIN}/jellyfin