-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdocker-compose.prod.yml
153 lines (144 loc) · 5.95 KB
/
docker-compose.prod.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# The aim of this docker compose file is to provide a good known
# way to build your docker-compose file for Anomaly projects
#
# This file provides you a template for your development environment
# ENTRYPOINT ["gunicorn", "--worker-tmp-dir=/dev/shm", "--worker-class=uvicorn.workers.UvicornWorker", "--bind=0.0.0.0:80", "wattle.mm.api:app"]
# https://docs.docker.com/compose/compose-file/compose-versioning/
version: "3.8"
services:
reverse-proxy:
image: traefik:v2.8
command:
# Remove this for production, this exposes the web UI
- "--providers.docker"
- "--log.level=DEBUG"
- "--providers.docker.exposedbydefault=false"
# Listen to port 80 solely to redirect it
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# Listen to https for all other
- "--entrypoints.websecure.address=:443"
# This allows us to use the staging server for development
# We could potentially move this to a variable name
#- "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesResolvers.letsencrypt.acme.email=${SOA_EMAIL}"
- "--certificatesResolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesResolvers.letsencrypt.acme.httpChallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
labels:
- "traefik.enable"
# We start off the TLS configuration
# Ensure that the SSL version is set to a minimum of 1.2
- "traefik.tls.options.default.minVersion=VersionTLS12"
# Send X-Frame-Options to DENY
- "traefik.http.middlewares.header-security.headers.frameDeny=true"
# HSTS security headers
# the time has been set to one non-leap year
- "traefik.http.middlewares.header-security.headers.stsSeconds=315360000"
- "traefik.http.middlewares.header-security.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.header-security.headers.stsPreload=true"
# set the hsts header even in http - see if this required
- "traefik.http.middlewares.header-security.headers.forceSTSHeader=true"
# Proxy the bucket or another container for the web client
- "traefik.http.middlewares.header-bucket.headers.customrequestheaders.host=${BUCKET_FQDN}"
# Declare a service to reverer proxy
- "traefik.http.services.service-bucket.loadbalancer.servers.url=${BUCKET_FQDN}"
- "traefik.http.services.service-bucket.loadbalancer.passhostheaders=false"
- "traefik.http.routers.${PROJ_NAME}-root.entrypoints=websecure"
- "traefik.http.routers.${PROJ_NAME}-root.rule=Host(`${PROJ_FQDN}`)"
- "traefik.http.routers.${PROJ_NAME}-root.tls"
- "traefik.http.routers.${PROJ_NAME}-root.tls.certResolver=letsencrypt"
- "traefik.http.routers.${PROJ_NAME}-root.priority=1"
- "traefik.http.routers.${PROJ_NAME}-root.services=service-bucket"
- "traefik.http.routers.${PROJ_NAME}-root.middlewares=header-bucket"
- "traefik.http.routers.${PROJ_NAME}-root.middlewares=header-security"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/anomaly-lab/data/letsencrypt:/letsencrypt
- /opt/anomaly-lab/traefik-dynamic.toml:/opt/traefik/traefik-dynamic.toml
restart: unless-stopped
# Postgres:
# - In development we read secrets from .env
# refer to the production config to see how to use secrets
# via Kubernetes
#
# Note that the volume is mounted so that the data is
# preserved when the containers are brought down
db:
image: postgres:14-bullseye
container_name: ${PROJ_NAME}-postgres
restart: unless-stopped
env_file:
- .env
volumes:
- /opt/data/postgres:/var/lib/postgresql/data/
# Redis:
# - In development we read secrets from .env
# used by Clerey to broker tasks between the api endpoints
# and worker tasks
redis:
image: redis:7-bullseye
container_name: ${PROJ_NAME}-redis
restart: unless-stopped
env_file:
- .env
volumes:
- /opt/data/redis:/data
# Applicaiton API:
# - In development we read secrets from .env
# - Provides a FastAPI based API that runs using uvicorn in development
api:
container_name: ${PROJ_NAME}-api
image: anomalyhq/${PROJ_NAME}-server:${VERSION}
command:
[
"gunicorn",
"--worker-tmp-dir=/dev/shm",
"--worker-class=uvicorn.workers.UvicornWorker",
"--bind=0.0.0.0:80",
"${PROJ_NAME}.api:app"
]
cap_drop:
- "all"
env_file:
- .env
restart: unless-stopped
labels:
# Explicitly tell Traefik to expose this container
- "traefik.enable=true"
# Declare a middleware that strips the api prefix, this
# is required for FastaPI to mount on the root and for us
# to proxy the urls on the /api endpoint
- "traefik.http.middlewares.strip-api-prefix.stripprefix.prefixes=/api/"
# The router for this container is going to respond to the host
# of the project and root level url
- "traefik.http.routers.${PROJ_NAME}-api.entrypoints=websecure"
- "traefik.http.routers.${PROJ_NAME}-api.rule=Host(`${PROJ_FQDN}`) && PathPrefix(`/api`)"
- "traefik.http.routers.${PROJ_NAME}-api.middlewares=strip-api-prefix"
- "traefik.http.routers.${PROJ_NAME}-api.tls"
- "traefik.http.routers.${PROJ_NAME}-api.tls.certResolver=letsencrypt"
depends_on:
- redis
- db
# TaskIQ worker
worker:
container_name: ${PROJ_NAME}-worker
build:
context: .
dockerfile: Dockerfile
command: [ "taskiq", "worker", "${PROJ_NAME}.broker:broker" ]
env_file:
- .env.development
restart: unless-stopped
volumes:
- ./src/${PROJ_NAME}:/opt/${PROJ_NAME}
depends_on:
- db
- redis
networks:
default:
name: ${PROJ_NAME}-network