Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ POSTGRES_USER=routeforge
POSTGRES_PASSWORD=change-me
DATABASE_URL=postgresql+psycopg://routeforge:change-me@postgres:5432/routeforge

# CORS (comma-separated list)
CORS_ORIGINS=http://localhost:3000
# CORS (comma-separated list; mainly needed for split frontend/backend deployments)
CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000

# Frontend runtime/build API target
VITE_API_URL=http://localhost:8000
# Optional. Leave empty for same-origin /api proxy via frontend nginx.
VITE_API_URL=

# RIPEstat
RIPESTAT_BASE_URL=https://stat.ripe.net/data
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ URLs:
- Frontend: http://localhost:3000
- Backend: http://localhost:8000
- Health: http://localhost:8000/health
- System Info: http://localhost:8000/api/system/info
- System Info (via frontend proxy): http://localhost:3000/api/system/info
- Direct System Info (backend): http://localhost:8000/api/system/info

## Demo Mode

Expand Down Expand Up @@ -157,10 +158,17 @@ docker compose up --build
### Production Start
```bash
cp .env.example .env
# edit .env (especially POSTGRES_PASSWORD, DATABASE_URL, CORS_ORIGINS, VITE_API_URL)
# edit .env (especially POSTGRES_PASSWORD, DATABASE_URL, CORS_ORIGINS)
docker compose -f docker-compose.prod.yml up -d --build
```

### Selfhosting Networking Default
- Frontend UI: `http://<host>:3000`
- API via same host (proxied by frontend nginx): `http://<host>:3000/api/...`
- Direct backend access (optional/diagnostics): `http://<host>:8000`

In the standard setup, RouteForge does **not** require a hardcoded host IP in the frontend build. The frontend nginx proxies `/api` internally to the backend service (`backend:8000`).

### Environment
- `.env.example` documents required production variables.
- Keep RouteForge read-only (no write operations to RIPE DB, RPKI, or routers).
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ services:
frontend:
build:
context: ./frontend
args:
VITE_API_URL: ${VITE_API_URL}
restart: unless-stopped
depends_on:
backend:
Expand Down
7 changes: 3 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ services:
- routeforge_data:/app/data
environment:
- DATABASE_URL=sqlite:////app/data/routeforge.db
- CORS_ORIGINS=http://192.168.58.167:3000,http://127.0.0.1:3000
- CORS_ORIGINS=${CORS_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
frontend:
build: ./frontend
build:
context: ./frontend
ports: ["3000:80"]
environment:
- VITE_API_URL=http://192.168.58.167:8000
depends_on: [backend]
volumes:
routeforge_data:
64 changes: 49 additions & 15 deletions docs/operations/reverse-proxy.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
# Reverse Proxy

## Recommended patterns
1. **Simple port exposure**: publish `3000` (frontend) and optionally `8000` (backend) on trusted networks.
2. **Domain + reverse proxy**: expose only proxy, keep backend internal where possible.
## Empfehlung
Für einfaches Selfhosting wird **Variante A** empfohlen. Dabei zeigt Ihr externer Reverse Proxy nur auf den Frontend-Service. API-Aufrufe unter `/api` funktionieren automatisch über den internen Frontend-Nginx-Proxy.

## Nginx Proxy Manager example
- Proxy Host domain `routeforge.example.com` -> `frontend:80`.
- Add advanced location `/api` -> `backend:8000`.
- Optional `/health` -> `backend:8000/health`.
- Enable HTTPS certificate (Let's Encrypt recommended).
## Variante A: Externer Proxy -> `frontend:80` (empfohlen)
- Externer Reverse Proxy leitet `/` an `frontend:80` weiter.
- Frontend-Nginx liefert SPA-Dateien aus.
- Frontend-Nginx proxied `/api/` intern an `backend:8000/api/`.
- Frontend-Nginx proxied `/health` intern an `backend:8000/health`.

## Classic Nginx example
Vorteile:
- Einfachste Konfiguration
- Kein separates externes `/api`-Routing nötig
- Keine hardcodierte Host-IP im Frontend-Build erforderlich

## Variante B: Externer Proxy split-routed `/` und `/api`
- Externer Reverse Proxy leitet `/` an `frontend:80` weiter.
- Externer Reverse Proxy leitet `/api/` direkt an `backend:8000/api/` weiter.
- Optional `/health` direkt an `backend:8000/health`.

Diese Variante ist nur für spezielle Setups nötig (z. B. wenn API-Traffic getrennt behandelt werden soll).

## Nginx Proxy Manager Beispiel
- Proxy Host Domain `routeforge.example.com` -> `frontend:80`.
- Bei Variante B zusätzliche Advanced Locations für `/api` und optional `/health` auf `backend:8000`.
- HTTPS-Zertifikat aktivieren (Let's Encrypt empfohlen).

## Classic Nginx Beispiele

### Variante A (empfohlen)
```nginx
server {
listen 443 ssl;
server_name routeforge.example.com;

location / {
proxy_pass http://frontend:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```

### Variante B (nur bei Bedarf)
```nginx
server {
listen 443 ssl;
Expand All @@ -32,10 +65,11 @@ server {
}
```

## HTTPS and CORS
- Prefer HTTPS termination at proxy.
- Set `CORS_ORIGINS` to the public frontend origin(s).
- RouteForge currently does not require websocket proxy settings.
## HTTPS und CORS
- HTTPS-Termination bevorzugt im externen Proxy.
- Bei Standard-Setup mit Variante A sind Browser-API-Calls same-origin (`/api` über denselben Host).
- `CORS_ORIGINS` ist primär relevant für getrennte Frontend/Backend-Deployments.

## Security note
- Avoid exposing backend directly to the internet if frontend is already proxied.
## Security-Hinweis
- Backend-Port `8000` nur exponieren, wenn benötigt (z. B. Diagnose).
- Wenn Frontend bereits sauber über Proxy bereitgestellt wird, Backend nach Möglichkeit intern halten.
3 changes: 2 additions & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ARG VITE_API_URL=http://localhost:8000
ARG VITE_API_URL=
ENV VITE_API_URL=${VITE_API_URL}
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
29 changes: 29 additions & 0 deletions frontend/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
server {
listen 80;
server_name _;

root /usr/share/nginx/html;
index index.html;

location /api/ {
proxy_pass http://backend:8000/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /health {
proxy_pass http://backend:8000/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location / {
try_files $uri $uri/ /index.html;
}
}
Loading