Add /api/version and bin/wait-deploy so deploys are observable from any machine
This commit is contained in:
parent
3cc682d63a
commit
49b180e797
3 changed files with 73 additions and 3 deletions
23
README.md
23
README.md
|
|
@ -33,17 +33,34 @@ uvicorn main:app --reload
|
|||
| `static/` | `index.html`, `app.js`, `style.css` — Vue 3 loaded from unpkg |
|
||||
| `requirements.txt` | Python deps |
|
||||
| `Procfile` | Start command; **nixpacks needs this** or the deploy has nothing to run |
|
||||
| `bin/wait-deploy` | Blocks until the live site serves your latest commit |
|
||||
| `Dockerfile.dev`, `docker-compose.yml` | Local dev only — production does not use them |
|
||||
|
||||
## Deployment
|
||||
|
||||
Push to `main` → Forgejo webhook → Coolify rebuilds with nixpacks → live in
|
||||
roughly 25 seconds.
|
||||
Push to `main` → Forgejo webhook → Coolify rebuilds with nixpacks → live.
|
||||
A nixpacks rebuild takes **90 seconds to 2 minutes** — longer than the static
|
||||
sites, which go in ~25s. Nothing changes on the site until the new container
|
||||
swaps in at the very end.
|
||||
|
||||
To know when your commit is actually live, rather than guessing:
|
||||
|
||||
```bash
|
||||
git push
|
||||
git push && bin/wait-deploy
|
||||
```
|
||||
|
||||
It polls `/api/version` (which returns the `SOURCE_COMMIT` Coolify bakes into
|
||||
the container) until it matches your local `HEAD`, then exits. Runs from any
|
||||
machine — no Coolify token, no SSH tunnel. Check by hand any time with:
|
||||
|
||||
```bash
|
||||
curl -s https://chart.amow.com/api/version
|
||||
```
|
||||
|
||||
One more trap worth naming: if your change only touches an `/api` endpoint, the
|
||||
HTML is byte-identical and a browser refresh looks like nothing happened even
|
||||
after a successful deploy. Verify the endpoint, not the page.
|
||||
|
||||
Two things to know before changing the deploy config:
|
||||
|
||||
- The Coolify domain is registered as `https://chart.amow.com:8000`. The port
|
||||
|
|
|
|||
43
bin/wait-deploy
Executable file
43
bin/wait-deploy
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env bash
|
||||
# Block until the deployed site is serving the commit at local HEAD.
|
||||
#
|
||||
# git push && bin/wait-deploy
|
||||
#
|
||||
# Works from any machine — it only reads the public /api/version endpoint, so
|
||||
# no Coolify token and no SSH tunnel are needed.
|
||||
set -uo pipefail
|
||||
|
||||
URL=${URL:-https://chart.amow.com}
|
||||
TIMEOUT=${TIMEOUT:-300}
|
||||
|
||||
want=$(git rev-parse HEAD) || exit 1
|
||||
short=${want:0:8}
|
||||
|
||||
echo "waiting for $URL to serve $short (timeout ${TIMEOUT}s)"
|
||||
|
||||
start=$(date +%s)
|
||||
last=""
|
||||
while :; do
|
||||
now=$(date +%s)
|
||||
elapsed=$(( now - start ))
|
||||
if [ "$elapsed" -ge "$TIMEOUT" ]; then
|
||||
echo "TIMEOUT after ${elapsed}s — still serving ${last:-unknown}"
|
||||
echo "check the build log: https://chart.amow.com is fine but Coolify may have failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 502 during the rolling container swap is normal; keep polling.
|
||||
got=$(curl -fsS -m 5 "$URL/api/version" 2>/dev/null \
|
||||
| sed -n 's/.*"commit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
||||
|
||||
if [ "$got" = "$want" ]; then
|
||||
echo "deployed ${short} after ${elapsed}s"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$got" != "$last" ]; then
|
||||
echo " ${elapsed}s: serving ${got:-unreachable}"
|
||||
last="$got"
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
10
main.py
10
main.py
|
|
@ -4,6 +4,7 @@ Placeholder app: serves the Vue 3 single-page frontend from static/ and a
|
|||
couple of JSON endpoints under /api. Replace the endpoints as the real app
|
||||
takes shape; the serving/deploy wiring below does not need to change.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
|
@ -13,6 +14,9 @@ from fastapi.staticfiles import StaticFiles
|
|||
BASE_DIR = Path(__file__).parent
|
||||
STATIC_DIR = BASE_DIR / "static"
|
||||
|
||||
# Coolify injects the deployed commit; absent when running locally.
|
||||
SOURCE_COMMIT = os.environ.get("SOURCE_COMMIT", "dev")
|
||||
|
||||
app = FastAPI(title="chart")
|
||||
|
||||
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
||||
|
|
@ -23,6 +27,12 @@ def health():
|
|||
return {"status": "ok", "service": "chart"}
|
||||
|
||||
|
||||
@app.get("/api/version")
|
||||
def version():
|
||||
"""Which commit is actually serving. `bin/wait-deploy` polls this."""
|
||||
return {"commit": SOURCE_COMMIT}
|
||||
|
||||
|
||||
@app.get("/api/hello")
|
||||
def hello():
|
||||
return {"msg": "this is fing awesome"}
|
||||
|
|
|
|||
Loading…
Reference in a new issue