Container-ready via docker/ compose (frontend nginx + backend Node). Compose adjusted for Coolify on the prod server: frontend uses expose:80 (no host binding — host 8080 is taken by the Coolify proxy; Traefik routes visigine.de), backend ALLOWED_ORIGINS=https://visigine.de. Secrets stay in server/.env (git-ignored); see server/.env.example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
75 lines
2.5 KiB
Markdown
75 lines
2.5 KiB
Markdown
# Visigine — Docker
|
|
|
|
Single-stack compose: nginx serves the built React app on port `8080` and
|
|
reverse-proxies `/api/*` to the backend container over the internal docker
|
|
network. The browser sees one origin — no CORS dance.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker Desktop / Docker Engine
|
|
- `docker compose` v2 plugin (bundled with current Docker Desktop)
|
|
|
|
## First run
|
|
|
|
```bash
|
|
# 1. Make sure server/.env exists with MISTRAL_KEY and ADMIN_TOKEN.
|
|
# If you only used the dev flow so far, server/.env is already populated.
|
|
cat server/.env
|
|
|
|
# 2. Build + start (from repo root)
|
|
docker compose -f docker/docker-compose.yml up -d --build
|
|
|
|
# 3. Open
|
|
# UI: http://localhost:8080
|
|
# Admin: http://localhost:8080/admin
|
|
# Health: http://localhost:8080/health
|
|
```
|
|
|
|
## Daily ops
|
|
|
|
```bash
|
|
# Logs (follow)
|
|
docker compose -f docker/docker-compose.yml logs -f
|
|
|
|
# Restart after backend code change
|
|
docker compose -f docker/docker-compose.yml up -d --build backend
|
|
|
|
# Restart after frontend code change
|
|
docker compose -f docker/docker-compose.yml up -d --build frontend
|
|
|
|
# Stop everything
|
|
docker compose -f docker/docker-compose.yml down
|
|
|
|
# Stop + remove built images
|
|
docker compose -f docker/docker-compose.yml down --rmi local
|
|
```
|
|
|
|
## What runs where
|
|
|
|
| Container | Image | Port | Role |
|
|
|--------------------|--------------|---------|-----------------------------------|
|
|
| `visigine-frontend`| nginx:alpine | `8080` | Serves `dist/` + proxies `/api/*` |
|
|
| `visigine-backend` | node:20 | `3001`* | Express API, Mistral, checks |
|
|
|
|
*Backend port is **internal-only**. It is `expose:`d, not `ports:`d — nothing
|
|
on your host can hit `:3001` directly. The frontend reaches it via the
|
|
docker network DNS name `backend:3001`.
|
|
|
|
## Configuration
|
|
|
|
- **Secrets** (`MISTRAL_KEY`, `ADMIN_TOKEN`): loaded from `../server/.env`.
|
|
- **Deployment vars**: hard-set in `docker-compose.yml`. To run on a
|
|
different host port or domain:
|
|
- Change `ports: "8080:80"` to whatever you want on the host side.
|
|
- Update `ALLOWED_ORIGINS` to match the public URL the browser uses.
|
|
|
|
## Notes
|
|
|
|
- `NODE_ENV=production` → `?debug=1` is unconditionally stripped from
|
|
responses. The admin dashboard still gets full debug data through
|
|
`/api/admin/analyze` (gated by `ADMIN_TOKEN`).
|
|
- `ALLOW_PRIVATE_HOSTS=0` → SSRF guard is fully on. Don't flip this in prod.
|
|
- Nginx strips the browser `Origin` header before forwarding, so the
|
|
backend's CORS allow-list only governs cross-origin browsers hitting
|
|
`:3001` directly — which can only happen if you manually `-p 3001:3001`.
|