Describe the restore, migrate and start order in the Kubernetes steps

This commit is contained in:
sajeyks 2026-10-09 20:45:57 +03:00
commit fcac609728

27
K8S.md
View file

@ -4,7 +4,8 @@
Redis, a volume for uploaded media, and an Ingress. PostgreSQL 18 is **not** included: use your
own database and point the app at it.
> Not tested on a cluster. The image itself is tested with `docker compose` (see [DOCKER.md](DOCKER.md)).
> Tested on a local `kind` cluster with a scratch Postgres (migrate Job, then web and the admin
> answer 200). Not tested on your cluster, ingress controller or real data.
## Steps
@ -29,26 +30,30 @@ own database and point the app at it.
```sh
kubectl create secret generic dynamicweb --from-env-file=<your env file>
```
4. **Edit the manifest:** your image name (it appears twice) and the Ingress hosts (one rule for
each domain, with `www.` variants). Set `ingressClassName` to your controller.
5. **Deploy:**
4. **Edit the manifest:** your image name (it appears three times) and the Ingress hosts (one rule
for each domain, with `www.` variants). Set `ingressClassName` to your controller.
5. **Migrate, then start.** If you have old data, restore it into the empty database first (for
example `psql -h <host> -U <user> <db> < dump.sql`). Then:
```sh
kubectl apply -f k8s/dynamicweb.yaml
kubectl logs -f job/dynamicweb-migrate # takes a few minutes; ends when the Job completes
kubectl rollout restart deploy/dynamicweb-web
kubectl logs -f deploy/dynamicweb-web # ready at "Listening at"
```
The first start runs the database migrations, so it takes a few minutes.
The `dynamicweb-migrate` Job runs the migrations once. The web pods don't migrate, so restart
them after the Job completes (a web pod that started earlier serves errors until you do).
6. **Check:** `curl -I -H 'Host: ungleich.ch' http://<ingress-address>/en-us/` returns 200. Admin
is at `/en-us/admin/login/` on any site's address.
## Good to know
- **Run one web replica first.** Each web pod migrates the database when it starts. After the first
start you can scale (`kubectl scale deploy/dynamicweb-web --replicas=2`), with the media volume
changed to `ReadWriteMany` so every pod sees the same uploads.
- **Scaling:** `kubectl scale deploy/dynamicweb-web --replicas=2`, with the media volume changed
to `ReadWriteMany` so every pod sees the same uploads.
- **Ingress must keep the original `Host` header** (the default). The site is chosen from the
host, and every domain must be in `UNGLEICH_SITE_CONFIGS` and in `ALLOWED_HOSTS`
(`dynamicweb/settings/prod.py` lists the current ones).
- **Updating:** push a new image tag, change the image in the manifest and apply it again.
- **Updating:** push a new image tag, change the image in the manifest, delete the old Job
(`kubectl delete job dynamicweb-migrate`) and apply again, then restart web.
- **Logs:** `kubectl logs deploy/dynamicweb-web` and `kubectl logs deploy/dynamicweb-celery`.
- **Optional hardening:** run the migrations once as a Job instead of in every pod. Use a Job with
`env: ROLE=migrate`, and add `RUN_MIGRATIONS=False` to the web Deployment.
- **Don't name a Service `postgres` without `enableServiceLinks: false`.** Kubernetes would inject
`POSTGRES_PORT=tcp://...` and the app crashes. The manifest already sets it on every pod.