HR-ATS-Portal/DOCKER.md

127 lines
3.2 KiB
Markdown

# Docker
```bash
docker compose up -d --build
```
Root `.env` is a **pointer only** (`COMPOSE_ENV_FILES=./backend/.env`) so Compose
interpolates `${FRONTEND_PORT}`, `${BACKEND_PORT}`, … from **`backend/.env`**.
All secrets and app config live in `backend/.env` (also injected into containers
via `env_file`).
## How the browser reaches the API
| Surface | URL |
|---|---|
| SPA | http://127.0.0.1:5173 |
| API (host) | http://127.0.0.1:8000 |
nginx on `:5173` also proxies API paths to `backend-api` (same-origin when
`VITE_API_BASE` is empty).
In `backend/.env`:
```env
FRONTEND_PORT=5173
BACKEND_PORT=8000
FRONTEND_URL=http://127.0.0.1:5173
```
## Local (host Postgres)
```env
PROD_ENV=false
DB_USERNAME=...
DB_PASSWORD=...
DB_HOST=localhost
DB_PORT=5432
DB_NAME=hrms
DB_SSLMODE=
FRONTEND_PORT=5173
BACKEND_PORT=8000
FRONTEND_URL=http://127.0.0.1:5173
```
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).
```bash
cp backend/.env.example backend/.env # set JWT, OpenAI, DB_*, PROD_ENV=false
docker compose up -d --build
```
| Service | Host access |
|---|---|
| `frontend` | `${FRONTEND_PORT:-5173}` |
| `backend-api` | `${BACKEND_PORT:-8000}` |
| `ats-engine` / `redis` | Compose network (optional host-ports overlay) |
| `postgres` | not started (optional `--profile postgres`) |
Optional loopback publishes for ATS / Redis:
```bash
docker compose -f docker-compose.yml -f docker-compose.host-ports.yml up -d
```
Optional live-reload / bind mounts:
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
```
Optional Compose Postgres (empty volume — not host data):
```bash
docker compose --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. Blank
`DB_SSLMODE` → SSL `require` (or set `DB_SSLMODE=require` explicitly).
```bash
docker compose up -d --build
docker compose ps
```
First boot against RDS can take a few minutes while Alembic applies drift; the
API healthcheck `start_period` is 180s so Compose does not mark it unhealthy too early.
### 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.
3. If `DB_AUTOGENERATE=true` → detect ORM drift and apply DDL **in-memory**.
4. Apply any pending `backend/migrations/manual/*.sql`.
Toggle in `backend/.env`: `DB_AUTO_MIGRATE` / `DB_AUTOGENERATE`.
### Verify
```bash
docker compose config
curl -sf http://127.0.0.1:5173/health
curl -sf http://127.0.0.1:8000/health
docker compose logs -f backend-api
```
### Secrets
- Never bake `backend/.env` into images.
- Root `.env` must stay a pointer (`COMPOSE_ENV_FILES`) — no passwords there.
- Do not put `DB_HOST` under Compose `environment:` (empty override blanks RDS).
## Useful commands
```bash
docker compose logs -f backend-api
docker compose restart backend-api
docker compose down
docker compose down -v
```