# How apps with their own server run on Toupas

| Aspect | Contract |
|---|---|
| Listening | Listen on `0.0.0.0:$PORT`. `PORT` is always 8080 |
| Files | The app's folder is `/app`, read-only. Only `/tmp` is writable (64 MB, emptied on every restart and update) |
| Data | Keep data in the Toupas database (`DATABASE_URL`, Postgres 17 with pgvector) or Toupas file storage (S3 settings). Never in files next to the code |
| Start | `/bin/sh -c "exec <start>"` as a non-root user, after preparing the app in Toupas's builder image (Linux x86-64), so native dependencies match |
| Health check | `GET healthCheck.path` (default `/`): any answer below 500 within 60 s (up to 300) means it started. Then every 30 s; 3 failures in a row restart it |
| Restarts | On a crash or failed health check, with growing waits. A new version only replaces the live one once it passes its health check |
| Memory | `memoryMb` (default 128). Going over stops the app (reported in logs and status) |
| CPU | Up to half a CPU, shared |
| Network | Outgoing internet is allowed. Other Toupas apps and private addresses aren't reachable |
| Stopping | `SIGTERM`, then `SIGKILL` after 10 s |

## Settings the app gets
- `PORT`, `NODE_ENV=production` / `PYTHONUNBUFFERED=1`, `TOUPAS_URL` (the app's main link), `TOUPAS_PROJECT_ID`, `TOUPAS_DEPLOYMENT_ID`, `TOUPAS_RELEASE_ID`.
- With a database: `DATABASE_URL` and `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE`.
- With file storage: `S3_ENDPOINT`, `S3_REGION=auto`, `S3_BUCKET`, `S3_PREFIX`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_SESSION_TOKEN`. The key is temporary: always pass the session token to the S3 client, and start every key with `S3_PREFIX`. With public files, also `S3_PUBLIC_BUCKET`, `S3_PUBLIC_URL` and `S3_PUBLIC_*` keys. `toupas_set_storage_names` renames them to what the app already reads (e.g. the `aws` preset).
- The user's own settings and secrets (`toupas_set_env`). The `TOUPAS_*` ones can't be overridden.

## On the user's computer
`toupas dev db` and `toupas dev storage` (in a shell) start a local database and file storage that match the live ones, and write their settings to `.env`.

## Static sites
No server: the prepared folder (e.g. `dist`) is served as it is. Hashed asset files are cached for a long time; HTML is always checked for a newer version.
