CLAUDE: Add multi-domain environment configuration support
- Create frontend-sba/.env.example and frontend-pd/.env.example templates - Fix hardcoded allowedHosts in nuxt.config.ts (now reads NUXT_ALLOWED_HOSTS) - Add NUXT_ALLOWED_HOSTS support to frontend-pd/nuxt.config.ts - Update docker-compose.yml with missing env vars: - FRONTEND_URL, DISCORD_SERVER_REDIRECT_URI - ALLOWED_DISCORD_IDS, WS_HEARTBEAT_INTERVAL, WS_CONNECTION_TIMEOUT - NUXT_ALLOWED_HOSTS for both frontends - Create docker-compose.prod.yml for production overrides - Update root .env.example with new variables - Add "Multi-Domain Deployment" section to README.md with checklist - Update all CLAUDE.md files with environment configuration docs - Remove obsolete 'version' attribute from docker-compose files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
db667965e6
commit
7d28eebd24
23
.env.example
23
.env.example
@ -22,6 +22,8 @@ DATABASE_URL=postgresql+asyncpg://paperdynasty:your-password@your-db-server:5432
|
||||
DISCORD_CLIENT_ID=your-discord-client-id
|
||||
DISCORD_CLIENT_SECRET=your-discord-client-secret
|
||||
DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
DISCORD_SERVER_REDIRECT_URI=http://localhost:8000/api/auth/discord/callback/server
|
||||
FRONTEND_URL=http://localhost:3000
|
||||
|
||||
# ============================================================================
|
||||
# League REST APIs
|
||||
@ -39,9 +41,28 @@ PD_API_KEY=your-pd-api-key
|
||||
# ============================================================================
|
||||
CORS_ORIGINS=http://localhost:3000,http://localhost:3001
|
||||
|
||||
# ============================================================================
|
||||
# Access Control
|
||||
# ============================================================================
|
||||
# Comma-separated Discord user IDs allowed access
|
||||
# Leave empty or use * for all users (dev only!)
|
||||
ALLOWED_DISCORD_IDS=
|
||||
|
||||
# ============================================================================
|
||||
# WebSocket Settings
|
||||
# ============================================================================
|
||||
WS_HEARTBEAT_INTERVAL=30
|
||||
WS_CONNECTION_TIMEOUT=60
|
||||
|
||||
# ============================================================================
|
||||
# Redis (optional - for caching)
|
||||
# ============================================================================
|
||||
# When using Docker Compose, Redis is automatically available at redis://redis:6379
|
||||
# When running locally, use redis://localhost:6379
|
||||
# REDIS_URL=redis://localhost:6379
|
||||
# REDIS_URL=redis://localhost:6379
|
||||
|
||||
# ============================================================================
|
||||
# Frontend Dev Server
|
||||
# ============================================================================
|
||||
# Comma-separated hostnames for Vite dev server external access
|
||||
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
45
CLAUDE.md
45
CLAUDE.md
@ -81,9 +81,52 @@ strat-gameplay-webapp/
|
||||
│ └── tests/
|
||||
├── frontend-sba/ # SBA League Nuxt app
|
||||
├── frontend-pd/ # PD League Nuxt app
|
||||
└── shared-components/ # Shared Vue components (optional)
|
||||
├── docker-compose.yml # Dev orchestration (all services)
|
||||
├── docker-compose.prod.yml # Production overrides
|
||||
└── .env.example # Root environment template
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
### Multi-Domain Support
|
||||
The project is fully environment-driven for deployment to different domains. All URLs and credentials are externalized.
|
||||
|
||||
### Environment Files
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `.env.example` | Root template - copy to `.env` |
|
||||
| `backend/.env.example` | Backend-specific template |
|
||||
| `frontend-sba/.env.example` | SBA frontend template |
|
||||
| `frontend-pd/.env.example` | PD frontend template |
|
||||
|
||||
### Key Environment Variables
|
||||
|
||||
**Backend** (in `backend/.env`):
|
||||
- `DATABASE_URL` - PostgreSQL connection string
|
||||
- `DISCORD_CLIENT_ID/SECRET` - OAuth credentials
|
||||
- `DISCORD_SERVER_REDIRECT_URI` - Server-side OAuth callback
|
||||
- `FRONTEND_URL` - Frontend base URL for redirects
|
||||
- `CORS_ORIGINS` - Allowed origins (comma-separated)
|
||||
- `ALLOWED_DISCORD_IDS` - User whitelist (comma-separated, empty = all)
|
||||
|
||||
**Frontend** (in `frontend-*/env`):
|
||||
- `NUXT_PUBLIC_API_URL` - Backend API URL
|
||||
- `NUXT_PUBLIC_WS_URL` - WebSocket URL
|
||||
- `NUXT_PUBLIC_DISCORD_CLIENT_ID` - OAuth client ID (public)
|
||||
- `NUXT_PUBLIC_DISCORD_REDIRECT_URI` - OAuth callback URL
|
||||
- `NUXT_ALLOWED_HOSTS` - Vite dev server allowed hosts (comma-separated)
|
||||
|
||||
### Docker Deployment
|
||||
```bash
|
||||
# Development
|
||||
docker compose up
|
||||
|
||||
# Production
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
See `README.md` "Multi-Domain Deployment" section for full checklist.
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Code Quality
|
||||
|
||||
41
README.md
41
README.md
@ -208,6 +208,47 @@ Copy `.env.example` to `.env` and configure:
|
||||
- `REDIS_URL` - Redis connection (auto-configured in Docker)
|
||||
- `CORS_ORIGINS` - Allowed origins (defaults to localhost:3000,3001)
|
||||
|
||||
---
|
||||
|
||||
## Multi-Domain Deployment
|
||||
|
||||
This project supports deployment to multiple domains. Key environment variables to configure:
|
||||
|
||||
### Backend Variables
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `FRONTEND_URL` | Frontend base URL for OAuth redirects | `https://yourdomain.com` |
|
||||
| `DISCORD_REDIRECT_URI` | Legacy Discord callback | `https://yourdomain.com/auth/callback` |
|
||||
| `DISCORD_SERVER_REDIRECT_URI` | Server-side Discord callback | `https://yourdomain.com/api/auth/discord/callback/server` |
|
||||
| `CORS_ORIGINS` | Allowed CORS origins (comma-separated) | `https://yourdomain.com,https://api.yourdomain.com` |
|
||||
| `ALLOWED_DISCORD_IDS` | Whitelist of Discord user IDs | `123456,789012` or empty for all |
|
||||
|
||||
### Frontend Variables
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `NUXT_PUBLIC_API_URL` | Backend API base URL | `https://yourdomain.com` |
|
||||
| `NUXT_PUBLIC_WS_URL` | WebSocket base URL | `https://yourdomain.com` |
|
||||
| `NUXT_PUBLIC_DISCORD_REDIRECT_URI` | OAuth callback URL | `https://yourdomain.com/auth/callback` |
|
||||
| `NUXT_ALLOWED_HOSTS` | Vite dev server allowed hosts (comma-separated) | `yourdomain.com,localhost` |
|
||||
|
||||
### Production Deployment
|
||||
|
||||
```bash
|
||||
# Using Docker Compose with production overrides
|
||||
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### Domain Deployment Checklist
|
||||
|
||||
When deploying to a new domain:
|
||||
1. [ ] Update Discord OAuth redirect URIs in [Discord Developer Portal](https://discord.com/developers/applications)
|
||||
2. [ ] Copy `.env.example` files to `.env` and configure all URLs
|
||||
3. [ ] Update `CORS_ORIGINS` to include new domain
|
||||
4. [ ] Add domain to `NUXT_ALLOWED_HOSTS` (if using dev server externally)
|
||||
5. [ ] Configure reverse proxy (Nginx/NPM) to route traffic
|
||||
|
||||
---
|
||||
|
||||
## Available Services
|
||||
|
||||
When running, the following services are available:
|
||||
|
||||
@ -75,14 +75,36 @@ now = pendulum.now('UTC')
|
||||
- **Database**: paperdynasty_dev
|
||||
- **Connection**: `postgresql+asyncpg://...`
|
||||
|
||||
### Required .env Variables
|
||||
### Environment Variables
|
||||
Copy `.env.example` to `.env` and configure. Key variables:
|
||||
|
||||
```bash
|
||||
DATABASE_URL=postgresql+asyncpg://...
|
||||
SECRET_KEY=your-secret-key
|
||||
DISCORD_CLIENT_ID=...
|
||||
DISCORD_CLIENT_SECRET=...
|
||||
# Required
|
||||
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db
|
||||
SECRET_KEY=your-secret-key-min-32-chars
|
||||
DISCORD_CLIENT_ID=your-discord-client-id
|
||||
DISCORD_CLIENT_SECRET=your-discord-client-secret
|
||||
|
||||
# OAuth URLs (update for your domain)
|
||||
DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
DISCORD_SERVER_REDIRECT_URI=http://localhost:8000/api/auth/discord/callback/server
|
||||
FRONTEND_URL=http://localhost:3000
|
||||
|
||||
# Access Control
|
||||
ALLOWED_DISCORD_IDS= # Comma-separated user IDs, empty = all users
|
||||
|
||||
# CORS (JSON array format)
|
||||
CORS_ORIGINS=["http://localhost:3000","http://localhost:3001"]
|
||||
|
||||
# League APIs
|
||||
SBA_API_URL=https://api.sba.manticorum.com
|
||||
SBA_API_KEY=your-sba-api-key
|
||||
PD_API_URL=https://pd-api.example.com
|
||||
PD_API_KEY=your-pd-api-key
|
||||
```
|
||||
|
||||
**Multi-Domain Deployment**: When deploying to a new domain, update `FRONTEND_URL`, `DISCORD_*_REDIRECT_URI`, and `CORS_ORIGINS`. See root `README.md` for full checklist.
|
||||
|
||||
### Python Environment
|
||||
- **Version**: Python 3.13.3
|
||||
- **Package Manager**: UV (fast, reliable)
|
||||
|
||||
28
docker-compose.prod.yml
Normal file
28
docker-compose.prod.yml
Normal file
@ -0,0 +1,28 @@
|
||||
# Production overrides for Paper Dynasty Game Engine
|
||||
# Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
target: production
|
||||
environment:
|
||||
- APP_ENV=production
|
||||
- DEBUG=false
|
||||
restart: always
|
||||
|
||||
frontend-sba:
|
||||
build:
|
||||
target: production
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
restart: always
|
||||
|
||||
frontend-pd:
|
||||
build:
|
||||
target: production
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
restart: always
|
||||
|
||||
redis:
|
||||
restart: always
|
||||
@ -2,8 +2,6 @@
|
||||
# Use this for integration testing, demos, or when you want everything containerized
|
||||
# For daily dev, see README.md for local development workflow
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Redis cache (shared dependency)
|
||||
redis:
|
||||
@ -51,6 +49,17 @@ services:
|
||||
|
||||
# CORS
|
||||
- CORS_ORIGINS=http://localhost:3000,http://localhost:3001
|
||||
|
||||
# Server-side OAuth
|
||||
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
|
||||
- DISCORD_SERVER_REDIRECT_URI=${DISCORD_SERVER_REDIRECT_URI:-http://localhost:8000/api/auth/discord/callback/server}
|
||||
|
||||
# Access Control
|
||||
- ALLOWED_DISCORD_IDS=${ALLOWED_DISCORD_IDS:-}
|
||||
|
||||
# WebSocket Settings
|
||||
- WS_HEARTBEAT_INTERVAL=${WS_HEARTBEAT_INTERVAL:-30}
|
||||
- WS_CONNECTION_TIMEOUT=${WS_CONNECTION_TIMEOUT:-60}
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
@ -79,6 +88,7 @@ services:
|
||||
- NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
- NUXT_PUBLIC_DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID}
|
||||
- NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
- NUXT_ALLOWED_HOSTS=${NUXT_ALLOWED_HOSTS:-localhost,127.0.0.1}
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
@ -103,6 +113,7 @@ services:
|
||||
- NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
- NUXT_PUBLIC_DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID}
|
||||
- NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3001/auth/callback
|
||||
- NUXT_ALLOWED_HOSTS=${NUXT_ALLOWED_HOSTS:-localhost,127.0.0.1}
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
|
||||
14
frontend-pd/.env.example
Normal file
14
frontend-pd/.env.example
Normal file
@ -0,0 +1,14 @@
|
||||
# PD League Frontend Configuration
|
||||
# Copy to .env and update with your values
|
||||
|
||||
# API Configuration
|
||||
NUXT_PUBLIC_API_URL=http://localhost:8000
|
||||
NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
|
||||
# Discord OAuth (public client ID only - safe to expose)
|
||||
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-discord-client-id
|
||||
NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3001/auth/callback
|
||||
|
||||
# Vite Dev Server - Allowed external hosts (comma-separated)
|
||||
# Add your domain here for external access during development
|
||||
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
@ -257,16 +257,24 @@ export const useGameStore = defineStore('game', () => {
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
Create `.env` file with:
|
||||
Copy `.env.example` to `.env` and configure:
|
||||
|
||||
```bash
|
||||
NUXT_PUBLIC_LEAGUE_ID=pd
|
||||
NUXT_PUBLIC_LEAGUE_NAME=Paper Dynasty
|
||||
# API endpoints
|
||||
NUXT_PUBLIC_API_URL=http://localhost:8000
|
||||
NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
|
||||
# Discord OAuth (public client ID - safe to expose)
|
||||
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-client-id
|
||||
NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3001/auth/callback
|
||||
|
||||
# Vite dev server allowed hosts (comma-separated)
|
||||
# Add your domain for external access
|
||||
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
```
|
||||
|
||||
**Note**: `NUXT_ALLOWED_HOSTS` is read in `nuxt.config.ts` to configure Vite's `allowedHosts`. Required when accessing dev server through a reverse proxy or external domain.
|
||||
|
||||
### Nuxt Config
|
||||
```typescript
|
||||
// nuxt.config.ts
|
||||
|
||||
@ -16,6 +16,14 @@ export default defineNuxtConfig({
|
||||
|
||||
devtools: { enabled: true },
|
||||
|
||||
// Vite config for external hostname access
|
||||
// Configure NUXT_ALLOWED_HOSTS env var for your domains (comma-separated)
|
||||
vite: {
|
||||
server: {
|
||||
allowedHosts: process.env.NUXT_ALLOWED_HOSTS?.split(',') || ['localhost', '127.0.0.1']
|
||||
}
|
||||
},
|
||||
|
||||
typescript: {
|
||||
strict: true,
|
||||
typeCheck: true
|
||||
|
||||
14
frontend-sba/.env.example
Normal file
14
frontend-sba/.env.example
Normal file
@ -0,0 +1,14 @@
|
||||
# SBA League Frontend Configuration
|
||||
# Copy to .env and update with your values
|
||||
|
||||
# API Configuration
|
||||
NUXT_PUBLIC_API_URL=http://localhost:8000
|
||||
NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
|
||||
# Discord OAuth (public client ID only - safe to expose)
|
||||
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-discord-client-id
|
||||
NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
|
||||
# Vite Dev Server - Allowed external hosts (comma-separated)
|
||||
# Add your domain here for external access during development
|
||||
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
@ -58,14 +58,25 @@ npm run lint # Lint code
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables (.env)
|
||||
### Environment Variables
|
||||
Copy `.env.example` to `.env` and configure:
|
||||
|
||||
```bash
|
||||
NUXT_PUBLIC_LEAGUE_ID=sba
|
||||
# API endpoints
|
||||
NUXT_PUBLIC_API_URL=http://localhost:8000
|
||||
NUXT_PUBLIC_WS_URL=http://localhost:8000
|
||||
|
||||
# Discord OAuth (public client ID - safe to expose)
|
||||
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-client-id
|
||||
NUXT_PUBLIC_DISCORD_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
|
||||
# Vite dev server allowed hosts (comma-separated)
|
||||
# Add your domain for external access
|
||||
NUXT_ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
```
|
||||
|
||||
**Note**: `NUXT_ALLOWED_HOSTS` is read in `nuxt.config.ts` to configure Vite's `allowedHosts`. Required when accessing dev server through a reverse proxy or external domain.
|
||||
|
||||
### League Theme
|
||||
- Primary: #1e40af (SBA Blue)
|
||||
- Secondary: #dc2626 (SBA Red)
|
||||
|
||||
@ -31,9 +31,10 @@ export default defineNuxtConfig({
|
||||
},
|
||||
|
||||
// Vite config for external hostname access
|
||||
// Configure NUXT_ALLOWED_HOSTS env var for your domains (comma-separated)
|
||||
vite: {
|
||||
server: {
|
||||
allowedHosts: ['gameplay-demo.manticorum.com', 'localhost', '127.0.0.1']
|
||||
allowedHosts: process.env.NUXT_ALLOWED_HOSTS?.split(',') || ['localhost', '127.0.0.1']
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user