146 lines
4.6 KiB
Markdown
146 lines
4.6 KiB
Markdown
# Docker
|
|
|
|
## How the browser reaches the API
|
|
|
|
The SPA is on **http://127.0.0.1:5173** (nginx → `backend-api` on the Compose
|
|
network). The API is also published on **http://127.0.0.1:8000** for host tools
|
|
and `npm run dev` (`VITE_API_BASE=http://127.0.0.1:8000`).
|
|
|
|
```env
|
|
FRONTEND_PORT=5173
|
|
BACKEND_PORT=8000
|
|
FRONTEND_URL=http://127.0.0.1:5173
|
|
```
|
|
|
|
Sole env file: **`backend/.env`** (no repo-root `.env`). Always pass it for
|
|
Compose variable substitution:
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env up -d --build
|
|
```
|
|
|
|
## Local (host Postgres)
|
|
|
|
In `backend/.env`:
|
|
|
|
```env
|
|
PROD_ENV=false
|
|
DB_USERNAME=...
|
|
DB_PASSWORD=...
|
|
DB_HOST=localhost
|
|
DB_PORT=5432
|
|
DB_NAME=hrms
|
|
DB_SSLMODE=
|
|
FRONTEND_PORT=8080
|
|
```
|
|
|
|
Containers set `IN_DOCKER=1`. With `PROD_ENV=false`, `db_setup` rewrites
|
|
`localhost` / `127.0.0.1` → `host.docker.internal` for the connection URL only
|
|
(SSL off unless `DB_SSLMODE` is set). Host Postgres must accept Docker-bridge
|
|
clients (`listen_addresses`, `pg_hba`).
|
|
|
|
```bash
|
|
cp backend/.env.example backend/.env # set JWT, OpenAI, DB_*, PROD_ENV=false
|
|
docker compose --env-file ./backend/.env up -d --build
|
|
```
|
|
|
|
| Service | Host access |
|
|
|---|---|
|
|
| `frontend` | `${FRONTEND_PORT:-80}` (all interfaces) |
|
|
| `backend-api` | Compose network only (`backend-api:8000`); nginx proxies |
|
|
| `ats-engine` | Compose network only (`ats-engine:8100`) |
|
|
| `redis` | Compose network only (`redis:6379`) |
|
|
| `postgres` | not started (optional `--profile postgres`) |
|
|
|
|
Optional loopback publishes for host tools (curl / redis-cli / Postman):
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env -f docker-compose.yml -f docker-compose.host-ports.yml up -d
|
|
```
|
|
|
|
If bind fails on Windows because Cursor/VS Code still holds `:80` / `:8100` /
|
|
`:6379` after a previous run, clear **Ports** in the IDE or set free values in
|
|
`backend/.env` (`FRONTEND_PORT`, and with the overlay `ATS_PORT` / `REDIS_PORT` /
|
|
`BACKEND_PORT`).
|
|
|
|
Optional live-reload / bind mounts:
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env -f docker-compose.yml -f docker-compose.dev.yml up -d --build
|
|
```
|
|
|
|
Optional Compose Postgres (empty volume — not host data):
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env --profile postgres up -d postgres
|
|
# set DB_HOST=postgres in backend/.env, then recreate backend services
|
|
```
|
|
|
|
## Production (RDS)
|
|
|
|
In `backend/.env`, set `PROD_ENV=true` and point plain `DB_*` at RDS (no
|
|
prefixed credential sets). Blank `DB_SSLMODE` → SSL `require`. Host is never
|
|
rewritten.
|
|
|
|
```bash
|
|
cp backend/.env.example backend/.env
|
|
# Edit backend/.env: PROD_ENV=true, DB_* = RDS, JWT_SECRET_KEY, FRONTEND_PORT=80, …
|
|
docker compose --env-file ./backend/.env up -d --build
|
|
docker compose --env-file ./backend/.env ps
|
|
```
|
|
|
|
Browser → `http://<host>/` → nginx (same-origin) → `backend-api:8000`.
|
|
CV files live in the `attachments-data` named volume (shared by API + workers).
|
|
|
|
### Schema / migrations (automatic)
|
|
|
|
On every `backend-api` start:
|
|
|
|
1. Fresh empty Postgres → create all tables from models and stamp a marker.
|
|
2. Otherwise → `alembic upgrade head` if any revision files exist in the image
|
|
(they normally do not — versions stay gitignored and are excluded from builds).
|
|
3. If `DB_AUTOGENERATE=true` → detect ORM drift and apply DDL **in-memory**.
|
|
4. Apply any pending `backend/migrations/manual/*.sql` (seed/RBAC batches only).
|
|
|
|
Toggle in `backend/.env`: `DB_AUTO_MIGRATE` / `DB_AUTOGENERATE` (default `true`).
|
|
|
|
### Verify
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env config
|
|
curl -sf http://127.0.0.1:${FRONTEND_PORT:-8080}/health
|
|
curl -sf -o /dev/null -w "%{http_code}\n" http://127.0.0.1:${FRONTEND_PORT:-8080}/
|
|
docker compose --env-file ./backend/.env logs -f backend-api
|
|
```
|
|
|
|
### Secrets
|
|
|
|
- Never bake `.env` into images (`.dockerignore` already excludes them).
|
|
- Require a strong `DB_PASSWORD` and `JWT_SECRET_KEY` before any real deploy.
|
|
- Only `backend/.env` holds app + Compose substitution values.
|
|
- Do not put `DB_HOST` under Compose `environment:` (empty override blanks RDS).
|
|
|
|
### TLS
|
|
|
|
This stack serves HTTP on the frontend port. Terminate TLS at a reverse proxy or
|
|
cloud load balancer in front of that port.
|
|
|
|
## Data migration
|
|
|
|
The optional Compose Postgres volume starts empty. To move an existing host database:
|
|
|
|
```bash
|
|
pg_dump -Fc hrms > hrms.dump
|
|
pg_restore -h 127.0.0.1 -p 5433 -U postgres -d hrms --clean --if-exists hrms.dump
|
|
```
|
|
|
|
## Useful commands
|
|
|
|
```bash
|
|
docker compose --env-file ./backend/.env logs -f backend-api
|
|
docker compose --env-file ./backend/.env logs -f taskiq-worker
|
|
docker compose --env-file ./backend/.env restart backend-api
|
|
docker compose --env-file ./backend/.env down # keep volumes
|
|
docker compose --env-file ./backend/.env down -v # wipe volumes
|
|
```
|