Add hostname configuration for production deployment
Add environment variable configuration to support deployment on custom domains like https://awards.dj7nt.de ## Changes - Add .env.example with configuration template - Update API client to use VITE_API_BASE_URL with fallback to /api - Update SvelteKit config to use VITE_APP_URL for CSRF trusted origins - Update backend CORS to use configurable allowed origins - Add ALLOWED_ORIGINS environment variable for production - Add build and preview scripts to package.json - Update README with production deployment guide and nginx example ## Environment Variables - VITE_APP_URL: Application hostname (e.g., https://awards.dj7nt.de) - VITE_API_BASE_URL: API base URL (empty = relative paths) - ALLOWED_ORIGINS: Comma-separated CORS origins - JWT_SECRET: Strong secret for production - NODE_ENV: development/production Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
22
.env.example
Normal file
22
.env.example
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Application Configuration
|
||||||
|
# Copy this file to .env and update with your values
|
||||||
|
|
||||||
|
# Hostname for the application (e.g., https://awards.dj7nt.de)
|
||||||
|
# Leave empty for development (uses localhost)
|
||||||
|
VITE_APP_URL=
|
||||||
|
|
||||||
|
# API Base URL (in production, can be same domain or separate)
|
||||||
|
# Leave empty to use relative paths (recommended for same-domain deployment)
|
||||||
|
VITE_API_BASE_URL=
|
||||||
|
|
||||||
|
# Allowed CORS origins for backend (comma-separated)
|
||||||
|
# Only needed for production if not using same domain
|
||||||
|
# Example: https://awards.dj7nt.de,https://www.awards.dj7nt.de
|
||||||
|
ALLOWED_ORIGINS=
|
||||||
|
|
||||||
|
# JWT Secret (for production, use a strong random string)
|
||||||
|
# Generate with: openssl rand -base64 32
|
||||||
|
JWT_SECRET=change-this-in-production
|
||||||
|
|
||||||
|
# Node Environment
|
||||||
|
NODE_ENV=development
|
||||||
93
README.md
93
README.md
@@ -87,13 +87,28 @@ cd award
|
|||||||
bun install
|
bun install
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Set up environment variables (optional):
|
3. Set up environment variables:
|
||||||
Create a `.env` file in the project root:
|
Create a `.env` file in the project root (copy from `.env.example`):
|
||||||
```env
|
```bash
|
||||||
JWT_SECRET=your-secret-key-here
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
If not provided, a default secret will be used.
|
Edit `.env` with your configuration:
|
||||||
|
```env
|
||||||
|
# Application URL (for production deployment)
|
||||||
|
VITE_APP_URL=https://awards.dj7nt.de
|
||||||
|
|
||||||
|
# API Base URL (leave empty for same-domain deployment)
|
||||||
|
VITE_API_BASE_URL=
|
||||||
|
|
||||||
|
# JWT Secret (generate with: openssl rand -base64 32)
|
||||||
|
JWT_SECRET=your-generated-secret-here
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
NODE_ENV=production
|
||||||
|
```
|
||||||
|
|
||||||
|
**For development**: You can leave `.env` empty or use defaults.
|
||||||
|
|
||||||
4. Initialize the database:
|
4. Initialize the database:
|
||||||
```bash
|
```bash
|
||||||
@@ -217,6 +232,74 @@ In production, you can either:
|
|||||||
2. **Keep the proxy setup** with a proper reverse proxy (nginx, caddy)
|
2. **Keep the proxy setup** with a proper reverse proxy (nginx, caddy)
|
||||||
3. **Use SvelteKit adapter** for Node/Bun to serve everything from one process
|
3. **Use SvelteKit adapter** for Node/Bun to serve everything from one process
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Building for Production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the frontend
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
# Preview the production build locally
|
||||||
|
bun run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deployment Options
|
||||||
|
|
||||||
|
#### Option 1: Static Site + Backend Server
|
||||||
|
|
||||||
|
1. Build the frontend: `bun run build`
|
||||||
|
2. Serve `src/frontend/build/` with Elysia using `@elysiajs/static`
|
||||||
|
3. Backend runs on one port serving both frontend and API
|
||||||
|
|
||||||
|
#### Option 2: Reverse Proxy (Recommended)
|
||||||
|
|
||||||
|
Use nginx or Caddy to proxy:
|
||||||
|
- `/` → SvelteKit frontend (port 5173 or static files)
|
||||||
|
- `/api` → Elysia backend (port 3001)
|
||||||
|
|
||||||
|
**Example nginx configuration:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
server_name awards.dj7nt.de;
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:5173;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backend API
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://localhost:3001;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option 3: Single Process with SvelteKit Node Adapter
|
||||||
|
|
||||||
|
Use `@sveltejs/adapter-node` to build for Node/Bun:
|
||||||
|
- Everything runs in one process
|
||||||
|
- API routes handled by SvelteKit (need to migrate from Elysia)
|
||||||
|
|
||||||
|
### Environment Variables for Production
|
||||||
|
|
||||||
|
Make sure to set these in your production environment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VITE_APP_URL=https://awards.dj7nt.de
|
||||||
|
VITE_API_BASE_URL= # Leave empty for same-domain
|
||||||
|
JWT_SECRET=<strong-random-string>
|
||||||
|
NODE_ENV=production
|
||||||
|
```
|
||||||
|
|
||||||
## Features in Detail
|
## Features in Detail
|
||||||
|
|
||||||
### Background Job Queue
|
### Background Job Queue
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
"dev": "bun run src/backend/index.js & cd src/frontend && bun run dev",
|
"dev": "bun run src/backend/index.js & cd src/frontend && bun run dev",
|
||||||
"dev:backend": "bun run src/backend/index.js",
|
"dev:backend": "bun run src/backend/index.js",
|
||||||
"dev:frontend": "cd src/frontend && bun run dev",
|
"dev:frontend": "cd src/frontend && bun run dev",
|
||||||
|
"build": "cd src/frontend && bun run build",
|
||||||
|
"preview": "cd src/frontend && bun run preview",
|
||||||
"db:generate": "drizzle-kit generate",
|
"db:generate": "drizzle-kit generate",
|
||||||
"db:push": "drizzle-kit push",
|
"db:push": "drizzle-kit push",
|
||||||
"db:migrate": "drizzle-kit migrate"
|
"db:migrate": "drizzle-kit migrate"
|
||||||
|
|||||||
@@ -25,10 +25,18 @@ import {
|
|||||||
* Main backend application
|
* Main backend application
|
||||||
* Serves API routes
|
* Serves API routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Get allowed origins from environment or allow all in development
|
||||||
|
const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS
|
||||||
|
? process.env.ALLOWED_ORIGINS.split(',')
|
||||||
|
: process.env.NODE_ENV === 'production'
|
||||||
|
? [process.env.VITE_APP_URL || 'https://awards.dj7nt.de']
|
||||||
|
: true; // Allow all in development
|
||||||
|
|
||||||
const app = new Elysia()
|
const app = new Elysia()
|
||||||
// Enable CORS for frontend communication
|
// Enable CORS for frontend communication
|
||||||
.use(cors({
|
.use(cors({
|
||||||
origin: true, // Allow all origins in development
|
origin: ALLOWED_ORIGINS,
|
||||||
credentials: true,
|
credentials: true,
|
||||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API base URL - proxied through SvelteKit dev server
|
* API base URL - configurable via environment variable
|
||||||
* In production, this will be relative to the same origin
|
* Falls back to relative path for same-domain deployment
|
||||||
*/
|
*/
|
||||||
const API_BASE = '/api';
|
const API_BASE = import.meta.env.VITE_API_BASE_URL || '/api';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an API request
|
* Make an API request
|
||||||
|
|||||||
@@ -4,9 +4,14 @@ import adapter from '@sveltejs/adapter-auto';
|
|||||||
const config = {
|
const config = {
|
||||||
kit: {
|
kit: {
|
||||||
adapter: adapter(),
|
adapter: adapter(),
|
||||||
|
// Get app URL from environment or default to localhost
|
||||||
|
// This is used for production builds and CSRF configuration
|
||||||
|
// Set via VITE_APP_URL environment variable
|
||||||
// Disable origin checks in dev to prevent issues with browser extensions
|
// Disable origin checks in dev to prevent issues with browser extensions
|
||||||
csrf: {
|
csrf: {
|
||||||
trustedOrigins: process.env.NODE_ENV === 'production' ? undefined : ['http://localhost:5173', 'http://127.0.0.1:5173']
|
trustedOrigins: process.env.NODE_ENV === 'production'
|
||||||
|
? (process.env.VITE_APP_URL ? [new URL(process.env.VITE_APP_URL).origin] : undefined)
|
||||||
|
: ['http://localhost:5173', 'http://127.0.0.1:5173']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user