Repository navigation
Expand file tree
/
Copy pathzerops.yaml
More file actions
113 lines (95 loc) · 3.75 KB
/
Copy pathzerops.yaml
File metadata and controls
113 lines (95 loc) · 3.75 KB
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
zerops:
# Production setup — install deps to ./vendor, compile nothing,
# deploy minimal artifact. Flask + Gunicorn serve production traffic.
- setup: prod
build:
base: python@3.11
buildCommands:
# Install all dependencies into ./vendor so they travel
# with the application artifact to the runtime container.
# --target keeps packages inside the project tree (no
# system-Python pollution) — matches cache and deployFiles.
- pip install --target=./vendor -r requirements.txt
deployFiles:
- ./src # Flask application package
- ./vendor # All pip-installed packages
- ./migrate.py # DB migration script (runs in initCommands)
# Reuse ./vendor across builds — pip skips packages already
# present, cutting subsequent build times significantly.
cache:
- vendor
# Readiness check: Zerops probes GET / before adding the new
# container to the project balancer — guarantees zero-downtime
# deploys only route traffic to fully-started containers.
deploy:
readinessCheck:
httpGet:
port: 8000
path: /
run:
base: python@3.11
# Run DB migration once per deploy version. initCommands —
# not buildCommands — ensures migration and code are deployed
# atomically. zsc execOnce prevents race conditions when
# multiple containers start simultaneously.
initCommands:
- zsc execOnce ${appVersionId} --retryUntilSuccessful -- python migrate.py
ports:
- port: 8000
httpSupport: true
envVariables:
# Point Python's module search to the deployed vendor dir.
PYTHONPATH: /var/www/vendor
DB_NAME: db
# Zerops generates these from the 'db' service hostname:
# ${hostname_key} syntax references generated env variables.
DB_HOST: ${db_hostname}
DB_PORT: ${db_port}
DB_USER: ${db_user}
DB_PASS: ${db_password}
# Gunicorn is the production WSGI server. Two workers handle
# concurrent requests; Flask's built-in server is single-threaded
# and not suitable for production traffic.
start: >-
/var/www/vendor/bin/gunicorn
--bind 0.0.0.0:8000
--workers 2
src.app:app
# Development setup — deploy full source for SSH-based iteration.
# The developer SSHs in, runs the app manually, and edits files
# in place. Zerops prepares the workspace; the developer drives.
- setup: dev
build:
base: python@3.11
buildCommands:
# Same vendoring as prod — ./vendor ships with deployFiles: ./
# so the developer has all dependencies ready after SSH without
# running pip manually.
- pip install --target=./vendor -r requirements.txt
# Deploy the entire working directory — source, vendor, and
# zerops.yaml (needed if the developer runs zcli push from SSH).
deployFiles:
- ./
cache:
- vendor
run:
base: python@3.11
# Migration runs on deploy — database is ready when developer
# SSHs in, no manual setup needed.
initCommands:
- zsc execOnce ${appVersionId} --retryUntilSuccessful -- python migrate.py
ports:
- port: 8000
httpSupport: true
envVariables:
PYTHONPATH: /var/www/vendor
DB_NAME: db
DB_HOST: ${db_hostname}
DB_PORT: ${db_port}
DB_USER: ${db_user}
DB_PASS: ${db_password}
# zsc noop keeps the container alive without starting the app —
# the developer starts Flask or Gunicorn manually after SSH.
# Example: /var/www/vendor/bin/gunicorn --bind 0.0.0.0:8000
# --workers 2 src.app:app
start: zsc noop --silent