add docker-compose swarm stack (traefik, NFS binds); SPEC/AGENTS docs
This commit is contained in:
1 parent
73eeab7f63
commit
e737cd0b63
3 files changed
+32
-3
No files matched your search
@@ -22,10 +22,11 @@ Project conventions and operational gotchas for agents working in this repo.
|
||||
- Sanity-import: `./venv/bin/python -c "from app import main; print('IMPORT_OK')"`.
|
||||
|
||||
## Docker
|
||||
- `docker build -t idrs-api .`
|
||||
- Run with volumes: `-v idrs-data:/app/data -v idrs-icons:/app/app/static/icons`, env via `--env-file .env`.
|
||||
- `docker build -t idrs-api .` → `docker tag idrs-api:latest git.proit.id/proitlab/idrs-api:latest` → `docker push git.proit.id/proitlab/idrs-api:latest` (registry `git.proit.id`, project `proitlab`).
|
||||
- Deploy (Swarm): `docker stack deploy -c docker-compose.yml idrs` — service `idrs-api`, traefik labels (Host `idrs.databisnis.id`, `entrypoints=websecure`, `certresolver=letsencrypt`), constraint `node.hostname != server2U`, external overlay `traefik-net` (must pre-exist on manager), `env_file: .env`.
|
||||
- NFS bind mounts: `/mnt/nfs/server5.saltis.id/data/idrs/data` → `/app/data` (DB), `/mnt/nfs/server5.saltis.id/data/idrs/static` → `/app/app/static` (icons live at `<static>/icons/`; `icons/` subdir auto-created on first upload).
|
||||
- MUST use a single uvicorn worker (in-memory starlette sessions → `--workers >1` breaks login).
|
||||
- DB + uploaded icons persist in the volumes across container recreate; code changes need an image rebuild.
|
||||
- DB + uploaded icons persist in the volumes across container recreate; code changes need an image rebuild + re-push.
|
||||
|
||||
## Verification
|
||||
- curl login: `POST /admin/login` with `-c/-b` cookie jar; then curl admin endpoints / uploads with the jar.
|
||||
|
||||
@@ -16,6 +16,7 @@ FastAPI + SQLite server mirroring idrs-api live endpoints — `GET /api/getToken
|
||||
- out of scope: multi-user table, roles, 2FA, password reset, on-chain calls, audit trail, change history
|
||||
- data survival: existing `idrs.db` file + schema kept (migration-free); SQLAlchemy reads the same file
|
||||
- run: `./venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000` + `run.sh` wrapper
|
||||
- deploy: `docker-compose.yml` → Docker Swarm stack (`docker stack deploy -c docker-compose.yml`); traefik edge (Host `idrs.databisnis.id`, websecure, letsencrypt); NFS bind mounts for DB (`/app/data`) + static (`/app/app/static`); single uvicorn worker
|
||||
|
||||
## §I — Interfaces
|
||||
api: GET `/api/getTokenInfo` → 200 `{tokenList:[{idfToken:int, position:int, typeBlockchain:string, name:string, symbol:string, contractAddr:string, decimals:int, iconUrl:string, filename:string, is_live:bool}]}` (position ASC)
|
||||
@@ -70,6 +71,7 @@ T19|x|form: hide `idfToken` (auto) + `typeBlockchain` (fixed Vexanium); `positio
|
||||
T20|x|Dockerfile (python:3.12-slim, uvicorn single worker, non-root) + .dockerignore; DB (`/app/data`) and icons (`/app/app/static/icons`) volumes persist|§C
|
||||
T21|x|`tokenList.json`: replace seed iconUrl domain `idrs.kriptoteknologi.io` → `idrs.databisnis.id` (14 rows; existing DBs need manual update)|V5
|
||||
T22|x|icon upload → `token/` subdir + `/img/token/<filename>` route (flat route removed); migrate `ayam-logo.png` into `token/`, backfill token1 iconUrl|V15
|
||||
T23|x|docker-compose.yml: swarm stack — service `idrs-api` (registry image `git.proit.id/proitlab/idrs-api`), traefik labels (Host `idrs.databisnis.id`, websecure, letsencrypt), constraint `node.hostname != server2U`, external `traefik-net`, NFS bind mounts (`data` + `static`)|§C
|
||||
|
||||
## §B — Bug log
|
||||
id|date|cause|fix
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
services:
|
||||
idrs-api:
|
||||
image: git.proit.id/proitlab/idrs-api:latest
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- /mnt/nfs/server5.saltis.id/data/idrs/data:/app/data
|
||||
- /mnt/nfs/server5.saltis.id/data/idrs/static:/app/app/static
|
||||
networks:
|
||||
- traefik-net
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname != server2U
|
||||
restart_policy:
|
||||
condition: any
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.idrs-api.rule=Host(`idrs.databisnis.id`)
|
||||
- traefik.http.routers.idrs-api.entrypoints=websecure
|
||||
- traefik.http.routers.idrs-api.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.idrs-api.loadbalancer.server.port=8000
|
||||
|
||||
networks:
|
||||
traefik-net:
|
||||
external: true
|
||||
Reference in new issue
Block a user