This commit is contained in:
Matthias Hochmeister
2026-02-27 14:02:03 +01:00
parent 04d4f89834
commit 1c6c59c199
10 changed files with 76 additions and 66 deletions

View File

@@ -87,9 +87,9 @@ JWT_SECRET=your_jwt_secret_here
# The frontend URL that is allowed to make requests to the backend # The frontend URL that is allowed to make requests to the backend
# IMPORTANT: Must match your frontend URL exactly! # IMPORTANT: Must match your frontend URL exactly!
# Development: http://localhost:5173 (Vite dev server) # Development: http://localhost:5173 (Vite dev server)
# Production: https://dashboard.yourdomain.com # Production: https://start.feuerwehr-rems.at
# Multiple origins: Use comma-separated values (if supported by your setup) # Multiple origins: Use comma-separated values (if supported by your setup)
CORS_ORIGIN=http://localhost:80 CORS_ORIGIN=https://start.feuerwehr-rems.at
# ============================================================================ # ============================================================================
# FRONTEND CONFIGURATION # FRONTEND CONFIGURATION
@@ -103,16 +103,16 @@ FRONTEND_PORT=80
# API URL for frontend # API URL for frontend
# The URL where the frontend will send API requests # The URL where the frontend will send API requests
# Development: http://localhost:3000 # Development: http://localhost:3000
# Production: https://api.yourdomain.com # Production: https://start.feuerwehr-rems.at (proxied via nginx /api/)
# IMPORTANT: Must be accessible from the user's browser! # IMPORTANT: Must be accessible from the user's browser!
VITE_API_URL=http://localhost:3000 VITE_API_URL=https://start.feuerwehr-rems.at
# Authentik URL for frontend # Authentik URL for frontend
# The base URL of your Authentik instance (without application path) # The base URL of your Authentik instance (without application path)
# Development: http://localhost:9000 # Development: http://localhost:9000
# Production: https://auth.yourdomain.com # Production: https://auth.firesuite.feuerwehr-rems.at
# IMPORTANT: Used for OAuth redirect URL construction # IMPORTANT: Used for OAuth redirect URL construction
VITE_AUTHENTIK_URL=https://auth.yourdomain.com VITE_AUTHENTIK_URL=https://auth.firesuite.feuerwehr-rems.at
# ============================================================================ # ============================================================================
# AUTHENTIK OAUTH CONFIGURATION # AUTHENTIK OAUTH CONFIGURATION
@@ -133,18 +133,18 @@ AUTHENTIK_CLIENT_SECRET=your_client_secret_here
# OAuth Issuer URL # OAuth Issuer URL
# From Authentik: Applications → Providers → Your Provider → OpenID Configuration # From Authentik: Applications → Providers → Your Provider → OpenID Configuration
# Format: https://auth.yourdomain.com/application/o/your-app-slug/ # Format: https://auth.firesuite.feuerwehr-rems.at/application/o/your-app-slug/
# IMPORTANT: Must end with a trailing slash (/) # IMPORTANT: Must end with a trailing slash (/)
# Development: http://localhost:9000/application/o/feuerwehr-dashboard/ # Development: http://localhost:9000/application/o/feuerwehr-dashboard/
# Production: https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ # Production: https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ AUTHENTIK_ISSUER=https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/
# OAuth Redirect URI # OAuth Redirect URI
# The URL where Authentik will redirect after successful authentication # The URL where Authentik will redirect after successful authentication
# Must match EXACTLY what you configured in Authentik # Must match EXACTLY what you configured in Authentik
# Development: http://localhost:5173/auth/callback # Development: http://localhost:5173/auth/callback
# Production: https://dashboard.yourdomain.com/auth/callback # Production: https://start.feuerwehr-rems.at/auth/callback
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback AUTHENTIK_REDIRECT_URI=https://start.feuerwehr-rems.at/auth/callback
# OAuth Scopes (optional, has defaults) # OAuth Scopes (optional, has defaults)
# Default: openid profile email # Default: openid profile email
@@ -227,13 +227,13 @@ AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback
# BACKEND_PORT=3000 # BACKEND_PORT=3000
# NODE_ENV=production # NODE_ENV=production
# JWT_SECRET=<generated-with-openssl-rand-base64-32> # JWT_SECRET=<generated-with-openssl-rand-base64-32>
# CORS_ORIGIN=https://dashboard.yourdomain.com # CORS_ORIGIN=https://start.feuerwehr-rems.at
# FRONTEND_PORT=80 # FRONTEND_PORT=80
# VITE_API_URL=https://api.yourdomain.com # VITE_API_URL=https://start.feuerwehr-rems.at
# AUTHENTIK_CLIENT_ID=<from-authentik> # AUTHENTIK_CLIENT_ID=<from-authentik>
# AUTHENTIK_CLIENT_SECRET=<from-authentik> # AUTHENTIK_CLIENT_SECRET=<from-authentik>
# AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ # AUTHENTIK_ISSUER=https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/
# AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback # AUTHENTIK_REDIRECT_URI=https://start.feuerwehr-rems.at/auth/callback
# LOG_LEVEL=info # LOG_LEVEL=info
# #
# ============================================================================ # ============================================================================

View File

@@ -23,7 +23,7 @@ http://localhost:3000
### Production ### Production
``` ```
https://api.yourdomain.com https://start.feuerwehr-rems.at
``` ```
## Authentication ## Authentication
@@ -155,7 +155,7 @@ Check if the API is running and healthy.
**Request**: **Request**:
```http ```http
GET /health HTTP/1.1 GET /health HTTP/1.1
Host: api.yourdomain.com Host: start.feuerwehr-rems.at
``` ```
**Response**: **Response**:
@@ -197,7 +197,7 @@ Handle OAuth callback and exchange authorization code for tokens.
**Request Example**: **Request Example**:
```http ```http
POST /api/auth/callback HTTP/1.1 POST /api/auth/callback HTTP/1.1
Host: api.yourdomain.com Host: start.feuerwehr-rems.at
Content-Type: application/json Content-Type: application/json
``` ```
@@ -295,7 +295,7 @@ Refresh an expired access token using a refresh token.
Host: start.feuerwehr-rems.at Host: start.feuerwehr-rems.at
Content-Type: application/json Content-Type: application/json
``` ```
**Success Response**: **Success Response**:
```http ```http
@@ -370,7 +370,7 @@ Authorization: Bearer <access-token>
**Success Response**: **Success Response**:
```http ```http
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
``` ```
@@ -407,7 +407,7 @@ Authorization: Bearer <access-token>
**Success Response**: **Success Response**:
```http ```http
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
``` ```
@@ -479,10 +479,10 @@ HTTP/1.1 404 Not Found
redirect_uri: 'https://start.feuerwehr-rems.at/auth/callback', redirect_uri: 'https://start.feuerwehr-rems.at/auth/callback',
response_type: 'code', response_type: 'code',
scope: 'openid profile email' scope: 'openid profile email'
}); });
window.location.href = `${authentikAuthUrl}?${params}`; window.location.href = `${authentikAuthUrl}?${params}`;
``` ```
#### Step 2: Authentik Redirects Back #### Step 2: Authentik Redirects Back
@@ -494,13 +494,13 @@ window.location.href = `${authentikAuthUrl}?${params}`;
#### Step 3: Exchange Code for Tokens #### Step 3: Exchange Code for Tokens
```bash ```bash
curl -X POST https://api.yourdomain.com/api/auth/callback \ curl -X POST https://start.feuerwehr-rems.at/api/auth/callback \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"code": "abc123def456" "code": "abc123def456"
}' }'
``` ```
Response: Response:
```json ```json
{ {
@@ -532,14 +532,14 @@ Response:
#### Step 5: Refresh Token When Expired #### Step 5: Refresh Token When Expired
```bash ```bash
curl -X POST https://start.feuerwehr-rems.at/api/auth/refresh \ curl -X POST https://start.feuerwehr-rems.at/api/auth/refresh \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}' }'
``` ```
### JavaScript/TypeScript Examples ### JavaScript/TypeScript Examples
#### Using Axios #### Using Axios
@@ -553,7 +553,7 @@ curl -X POST https://api.yourdomain.com/api/auth/refresh \
const api = axios.create({ const api = axios.create({
baseURL: API_URL, baseURL: API_URL,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
}); });
@@ -612,32 +612,32 @@ export const logout = async () => {
#### Login Callback #### Login Callback
```bash ```bash
curl -X POST https://start.feuerwehr-rems.at/api/auth/callback \ curl -X POST https://start.feuerwehr-rems.at/api/auth/callback \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"code":"your_auth_code"}' -d '{"code":"your_auth_code"}'
``` ```
#### Get Current User #### Get Current User
```bash ```bash
curl -X GET https://start.feuerwehr-rems.at/api/user/me \ curl -X GET https://start.feuerwehr-rems.at/api/user/me \
-H "Authorization: Bearer your_access_token" -H "Authorization: Bearer your_access_token"
``` ```
#### Refresh Token #### Refresh Token
```bash ```bash
curl -X POST https://api.yourdomain.com/api/auth/refresh \ curl -X POST https://start.feuerwehr-rems.at/api/auth/refresh \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"refreshToken":"your_refresh_token"}' -d '{"refreshToken":"your_refresh_token"}'
``` ```
#### Logout #### Logout
```bash ```bash
curl -X POST https://start.feuerwehr-rems.at/api/auth/logout \ curl -X POST https://start.feuerwehr-rems.at/api/auth/logout \
-H "Authorization: Bearer your_access_token" -H "Authorization: Bearer your_access_token"
``` ```
## Security Considerations ## Security Considerations
### HTTPS Required in Production ### HTTPS Required in Production
Always use HTTPS for API requests in production to protect tokens and sensitive data. Always use HTTPS for API requests in production to protect tokens and sensitive data.
@@ -660,7 +660,7 @@ The API is configured to only accept requests from allowed origins:
``` ```
Ensure `CORS_ORIGIN` environment variable matches your frontend URL exactly. Ensure `CORS_ORIGIN` environment variable matches your frontend URL exactly.
### Rate Limiting ### Rate Limiting
Respect rate limits to avoid being temporarily blocked. Implement exponential backoff for failed requests. Respect rate limits to avoid being temporarily blocked. Implement exponential backoff for failed requests.

View File

@@ -21,8 +21,8 @@ Before you begin, you need:
- An Authentik instance (self-hosted or cloud) - An Authentik instance (self-hosted or cloud)
- Admin access to Authentik - Admin access to Authentik
- Your Feuerwehr Dashboard URL (e.g., `https://dashboard.yourdomain.com`) - Your Feuerwehr Dashboard URL (e.g., `https://start.feuerwehr-rems.at`)
- Your backend API URL (e.g., `https://api.yourdomain.com`) - Your backend API URL (e.g., `https://start.feuerwehr-rems.at`)
## Authentik Installation ## Authentik Installation
@@ -146,7 +146,7 @@ Protocol Settings:
``` ```
http://localhost:5173/auth/callback http://localhost:5173/auth/callback
http://localhost/auth/callback http://localhost/auth/callback
https://dashboard.yourdomain.com/auth/callback https://start.feuerwehr-rems.at/auth/callback
``` ```
Add one URI per line. Include all environments (development, staging, production). Add one URI per line. Include all environments (development, staging, production).
@@ -173,7 +173,7 @@ Configure the application:
Name: Feuerwehr Dashboard Name: Feuerwehr Dashboard
Slug: feuerwehr-dashboard Slug: feuerwehr-dashboard
Provider: Feuerwehr Dashboard Provider (select from dropdown) Provider: Feuerwehr Dashboard Provider (select from dropdown)
Launch URL: https://dashboard.yourdomain.com Launch URL: https://start.feuerwehr-rems.at
``` ```
**UI Settings** (optional): **UI Settings** (optional):
@@ -256,10 +256,10 @@ This is the Vite dev server URL.
### Production Environment ### Production Environment
``` ```
https://dashboard.yourdomain.com/auth/callback https://start.feuerwehr-rems.at/auth/callback
``` ```
Replace `yourdomain.com` with your actual domain. Replace `feuerwehr-rems.at` with your actual domain.
### Docker Local Testing ### Docker Local Testing
@@ -317,11 +317,11 @@ const scopes = 'openid profile email';
1. In the provider details, find **OpenID Configuration URL**: 1. In the provider details, find **OpenID Configuration URL**:
``` ```
https://auth.yourdomain.com/application/o/feuerwehr-dashboard/.well-known/openid-configuration https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/.well-known/openid-configuration
``` ```
2. Important URLs from this configuration: 2. Important URLs from this configuration:
- **Issuer**: `https://auth.yourdomain.com/application/o/feuerwehr-dashboard/` - **Issuer**: `https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/`
- **Authorization Endpoint**: Auto-discovered - **Authorization Endpoint**: Auto-discovered
- **Token Endpoint**: Auto-discovered - **Token Endpoint**: Auto-discovered
- **Userinfo Endpoint**: Auto-discovered - **Userinfo Endpoint**: Auto-discovered
@@ -334,8 +334,8 @@ Update your Feuerwehr Dashboard `.env` file:
# Authentik OAuth Configuration # Authentik OAuth Configuration
AUTHENTIK_CLIENT_ID=<your-client-id> AUTHENTIK_CLIENT_ID=<your-client-id>
AUTHENTIK_CLIENT_SECRET=<your-client-secret> AUTHENTIK_CLIENT_SECRET=<your-client-secret>
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ AUTHENTIK_ISSUER=https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback AUTHENTIK_REDIRECT_URI=https://start.feuerwehr-rems.at/auth/callback
# For development, use: # For development, use:
# AUTHENTIK_ISSUER=http://localhost:9000/application/o/feuerwehr-dashboard/ # AUTHENTIK_ISSUER=http://localhost:9000/application/o/feuerwehr-dashboard/
@@ -361,7 +361,7 @@ AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback
2. **Open the dashboard** in your browser: 2. **Open the dashboard** in your browser:
``` ```
Development: http://localhost:5173 Development: http://localhost:5173
Production: https://dashboard.yourdomain.com Production: https://start.feuerwehr-rems.at
``` ```
3. **Click "Login" button** 3. **Click "Login" button**
@@ -441,7 +441,7 @@ In the dashboard:
**Solution**: **Solution**:
1. Ensure `CORS_ORIGIN` in backend `.env` matches frontend URL 1. Ensure `CORS_ORIGIN` in backend `.env` matches frontend URL
2. For development: `CORS_ORIGIN=http://localhost:5173` 2. For development: `CORS_ORIGIN=http://localhost:5173`
3. For production: `CORS_ORIGIN=https://dashboard.yourdomain.com` 3. For production: `CORS_ORIGIN=https://start.feuerwehr-rems.at`
4. Restart backend after changing CORS settings 4. Restart backend after changing CORS settings
### Issue 4: Token Validation Failed ### Issue 4: Token Validation Failed
@@ -561,7 +561,7 @@ After configuration, verify:
Client Type: Confidential Client Type: Confidential
Client ID: <auto-generated> Client ID: <auto-generated>
Client Secret: <auto-generated> Client Secret: <auto-generated>
Redirect URIs: https://dashboard.yourdomain.com/auth/callback Redirect URIs: https://start.feuerwehr-rems.at/auth/callback
Scopes: openid, profile, email Scopes: openid, profile, email
Access Token Validity: 3600 Access Token Validity: 3600
Refresh Token Validity: 86400 Refresh Token Validity: 86400
@@ -571,8 +571,8 @@ Refresh Token Validity: 86400
```bash ```bash
AUTHENTIK_CLIENT_ID=<from-authentik> AUTHENTIK_CLIENT_ID=<from-authentik>
AUTHENTIK_CLIENT_SECRET=<from-authentik> AUTHENTIK_CLIENT_SECRET=<from-authentik>
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ AUTHENTIK_ISSUER=https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback AUTHENTIK_REDIRECT_URI=https://start.feuerwehr-rems.at/auth/callback
``` ```
## Security Best Practices ## Security Best Practices

View File

@@ -154,19 +154,19 @@ NODE_ENV=production
JWT_SECRET=<generated-jwt-secret> JWT_SECRET=<generated-jwt-secret>
# CORS - Set to your domain! # CORS - Set to your domain!
CORS_ORIGIN=https://dashboard.yourdomain.com CORS_ORIGIN=https://start.feuerwehr-rems.at
# Frontend # Frontend
FRONTEND_PORT=80 FRONTEND_PORT=80
# API URL - Set to your backend URL # API URL - Set to your backend URL
VITE_API_URL=https://api.yourdomain.com VITE_API_URL=https://start.feuerwehr-rems.at
# Authentik OAuth (from Authentik setup) # Authentik OAuth (from Authentik setup)
AUTHENTIK_CLIENT_ID=<your-client-id> AUTHENTIK_CLIENT_ID=<your-client-id>
AUTHENTIK_CLIENT_SECRET=<your-client-secret> AUTHENTIK_CLIENT_SECRET=<your-client-secret>
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr/ AUTHENTIK_ISSUER=https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr/
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback AUTHENTIK_REDIRECT_URI=https://start.feuerwehr-rems.at/auth/callback
``` ```
Secure the .env file: Secure the .env file:
@@ -253,7 +253,7 @@ Key points for production:
Create `Caddyfile`: Create `Caddyfile`:
```caddy ```caddy
dashboard.yourdomain.com { start.feuerwehr-rems.at {
reverse_proxy localhost:80 reverse_proxy localhost:80
encode gzip encode gzip
@@ -265,7 +265,7 @@ dashboard.yourdomain.com {
} }
} }
api.yourdomain.com { start.feuerwehr-rems.at {
reverse_proxy localhost:3000 reverse_proxy localhost:3000
encode gzip encode gzip
} }
@@ -299,7 +299,7 @@ Create Nginx configuration (`/etc/nginx/sites-available/feuerwehr`):
```nginx ```nginx
server { server {
listen 80; listen 80;
server_name dashboard.yourdomain.com; server_name start.feuerwehr-rems.at;
location / { location / {
proxy_pass http://localhost:80; proxy_pass http://localhost:80;
@@ -312,7 +312,7 @@ server {
server { server {
listen 80; listen 80;
server_name api.yourdomain.com; server_name start.feuerwehr-rems.at;
location / { location / {
proxy_pass http://localhost:3000; proxy_pass http://localhost:3000;
@@ -330,7 +330,7 @@ Enable and obtain SSL:
sudo ln -s /etc/nginx/sites-available/feuerwehr /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/feuerwehr /etc/nginx/sites-enabled/
sudo nginx -t sudo nginx -t
sudo systemctl reload nginx sudo systemctl reload nginx
sudo certbot --nginx -d dashboard.yourdomain.com -d api.yourdomain.com sudo certbot --nginx -d start.feuerwehr-rems.at -d start.feuerwehr-rems.at
``` ```
### Option 3: Using Docker with Traefik ### Option 3: Using Docker with Traefik

View File

@@ -217,8 +217,8 @@ docker run -p 80:80 feuerwehr-frontend:latest
# 1. Set production environment variables # 1. Set production environment variables
export POSTGRES_PASSWORD="secure_production_password" export POSTGRES_PASSWORD="secure_production_password"
export JWT_SECRET="secure_jwt_secret_min_32_chars" export JWT_SECRET="secure_jwt_secret_min_32_chars"
export CORS_ORIGIN="https://yourdomain.com" export CORS_ORIGIN="https://feuerwehr-rems.at"
export VITE_API_URL="https://api.yourdomain.com" export VITE_API_URL="https://start.feuerwehr-rems.at"
# 2. Build and start # 2. Build and start
docker-compose up -d docker-compose up -d

View File

@@ -59,7 +59,7 @@ const environment: EnvironmentConfig = {
max: parseInt(process.env.RATE_LIMIT_MAX || '100', 10), max: parseInt(process.env.RATE_LIMIT_MAX || '100', 10),
}, },
authentik: { authentik: {
issuer: process.env.AUTHENTIK_ISSUER || 'https://authentik.yourdomain.com/application/o/your-app/', issuer: process.env.AUTHENTIK_ISSUER || 'https://auth.firesuite.feuerwehr-rems.at/application/o/feuerwehr-dashboard/',
clientId: process.env.AUTHENTIK_CLIENT_ID || 'your_client_id_here', clientId: process.env.AUTHENTIK_CLIENT_ID || 'your_client_id_here',
clientSecret: process.env.AUTHENTIK_CLIENT_SECRET || 'your_client_secret_here', clientSecret: process.env.AUTHENTIK_CLIENT_SECRET || 'your_client_secret_here',
redirectUri: process.env.AUTHENTIK_REDIRECT_URI || 'http://localhost:5173/auth/callback', redirectUri: process.env.AUTHENTIK_REDIRECT_URI || 'http://localhost:5173/auth/callback',

View File

@@ -36,11 +36,11 @@ services:
DB_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} DB_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required} JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h} JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h}
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:80} CORS_ORIGIN: ${CORS_ORIGIN:-https://start.feuerwehr-rems.at}
AUTHENTIK_ISSUER: ${AUTHENTIK_ISSUER:?AUTHENTIK_ISSUER is required} AUTHENTIK_ISSUER: ${AUTHENTIK_ISSUER:?AUTHENTIK_ISSUER is required}
AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:?AUTHENTIK_CLIENT_ID is required} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:?AUTHENTIK_CLIENT_ID is required}
AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET:?AUTHENTIK_CLIENT_SECRET is required} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET:?AUTHENTIK_CLIENT_SECRET is required}
AUTHENTIK_REDIRECT_URI: ${AUTHENTIK_REDIRECT_URI:-http://localhost/auth/callback} AUTHENTIK_REDIRECT_URI: ${AUTHENTIK_REDIRECT_URI:-https://start.feuerwehr-rems.at/auth/callback}
ports: ports:
- "${BACKEND_PORT:-3000}:3000" - "${BACKEND_PORT:-3000}:3000"
depends_on: depends_on:
@@ -61,7 +61,7 @@ services:
context: ./frontend context: ./frontend
dockerfile: Dockerfile dockerfile: Dockerfile
args: args:
VITE_API_URL: ${VITE_API_URL:-http://localhost:3000} VITE_API_URL: ${VITE_API_URL:-https://start.feuerwehr-rems.at}
VITE_AUTHENTIK_URL: ${VITE_AUTHENTIK_URL:?VITE_AUTHENTIK_URL is required} VITE_AUTHENTIK_URL: ${VITE_AUTHENTIK_URL:?VITE_AUTHENTIK_URL is required}
VITE_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:?AUTHENTIK_CLIENT_ID is required} VITE_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:?AUTHENTIK_CLIENT_ID is required}
container_name: feuerwehr_frontend_prod container_name: feuerwehr_frontend_prod

View File

@@ -1,3 +1,3 @@
VITE_API_URL=http://localhost:3000 VITE_API_URL=http://localhost:3000
VITE_AUTHENTIK_URL=https://authentik.yourdomain.com VITE_AUTHENTIK_URL=https://auth.firesuite.feuerwehr-rems.at
VITE_CLIENT_ID=your_client_id_here VITE_CLIENT_ID=your_client_id_here

View File

@@ -65,6 +65,16 @@ http {
add_header Content-Type text/plain; add_header Content-Type text/plain;
} }
# Proxy API requests to backend
location /api/ {
proxy_pass http://backend:3000;
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;
}
# Cache static assets # Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y; expires 1y;

View File

@@ -1,6 +1,6 @@
export const config = { export const config = {
apiUrl: import.meta.env.VITE_API_URL || 'http://localhost:3000', apiUrl: import.meta.env.VITE_API_URL || 'http://localhost:3000',
authentikUrl: import.meta.env.VITE_AUTHENTIK_URL || 'https://authentik.yourdomain.com', authentikUrl: import.meta.env.VITE_AUTHENTIK_URL || 'https://auth.firesuite.feuerwehr-rems.at',
clientId: import.meta.env.VITE_CLIENT_ID || 'your_client_id_here', clientId: import.meta.env.VITE_CLIENT_ID || 'your_client_id_here',
}; };