|
| 1 | +# Deploying Serge |
| 2 | + |
| 3 | +This directory packages Serge's web app (`reviewbot-web`) for Kubernetes. |
| 4 | +The Helm chart is intentionally self-contained and values-driven so a team can |
| 5 | +deploy it into its own cluster without changing application code. |
| 6 | + |
| 7 | +## Contents |
| 8 | + |
| 9 | +- `helm/` contains the Helm chart for the web app: Deployment, Service, |
| 10 | + ConfigMap, optional Ingress, optional ServiceAccount, and a PersistentVolumeClaim. |
| 11 | +- `helm/env/prod.yaml` contains the production values used for |
| 12 | + `serge.huggingface.tech` on the open-source EKS cluster. |
| 13 | +- `helm/serge-secrets.example.yaml` is a template for the sensitive runtime env. |
| 14 | + Copy it to `helm/serge-secrets.yaml`, fill it locally, and never commit it. |
| 15 | +- `scripts/deploy.sh` checks the current Kubernetes context, creates the namespace |
| 16 | + when needed, optionally applies a local Secret file, and runs Helm. |
| 17 | +- `scripts/logs.sh` finds the current running Serge pod and prints recent logs. |
| 18 | + |
| 19 | +## Chart Behavior |
| 20 | + |
| 21 | +Serge uses embedded SQLite for review/task history. The chart therefore runs a |
| 22 | +single replica with a `Recreate` rollout strategy and mounts a PVC at |
| 23 | +`persistence.mountPath` (`/var/lib/reviewbot` by default). `WEB_STORE_PATH` is |
| 24 | +set to `<mountPath>/jobs.db`, so the database survives pod restarts. |
| 25 | + |
| 26 | +The container runs as a non-root user, drops Linux capabilities, uses |
| 27 | +`RuntimeDefault` seccomp, and sets `fsGroup` so the app user can write the |
| 28 | +volume. Sensitive values are loaded from a pre-created Secret via |
| 29 | +`existingSecret`; non-secret runtime config lives in `envVars`. |
| 30 | + |
| 31 | +## Deploy |
| 32 | + |
| 33 | +Create or update the Secret in the target namespace: |
| 34 | + |
| 35 | +```bash |
| 36 | +cp deploy/helm/serge-secrets.example.yaml deploy/helm/serge-secrets.yaml |
| 37 | +$EDITOR deploy/helm/serge-secrets.yaml |
| 38 | +deploy/scripts/deploy.sh -n serge --secret-file deploy/helm/serge-secrets.yaml |
| 39 | +``` |
| 40 | + |
| 41 | +Deploy without applying a Secret file, assuming `serge-secrets` already exists: |
| 42 | + |
| 43 | +```bash |
| 44 | +deploy/scripts/deploy.sh -n serge -f deploy/helm/env/prod.yaml |
| 45 | +``` |
| 46 | + |
| 47 | +Use `--context` when you want the script to refuse any other kube context: |
| 48 | + |
| 49 | +```bash |
| 50 | +deploy/scripts/deploy.sh \ |
| 51 | + --context infra:opensource-aws-use1-prod-54 \ |
| 52 | + -n serge \ |
| 53 | + -f deploy/helm/env/prod.yaml |
| 54 | +``` |
| 55 | + |
| 56 | +Fetch recent logs: |
| 57 | + |
| 58 | +```bash |
| 59 | +deploy/scripts/logs.sh \ |
| 60 | + --context infra:opensource-aws-use1-prod-54 \ |
| 61 | + -n serge \ |
| 62 | + --since 2h \ |
| 63 | + --grep 'error|traceback|crashed|HTTPError' |
| 64 | +``` |
| 65 | + |
| 66 | +Print only the latest error block: |
| 67 | + |
| 68 | +```bash |
| 69 | +deploy/scripts/logs.sh \ |
| 70 | + --context infra:opensource-aws-use1-prod-54 \ |
| 71 | + -n serge \ |
| 72 | + --since 2h \ |
| 73 | + --last-error |
| 74 | +``` |
| 75 | + |
| 76 | +## Notes |
| 77 | + |
| 78 | +- The production image is published to GHCR as `ghcr.io/huggingface/serge`. |
| 79 | +- `HELPER_SANDBOX=require` needs nodes that allow unprivileged user namespaces. |
| 80 | + Set it to `auto` or `off` in `envVars` if the cluster cannot support that. |
| 81 | +- Avoid `kubectl apply` for filled Secret manifests long-term: it can store |
| 82 | + plaintext Secret values in the `last-applied-configuration` annotation. The |
| 83 | + helper strips that annotation after applying a Secret file. |
0 commit comments