Add Docker Compose configuration and environment files for local and production setups

- Created docker-compose.docker-local.yml for local testing of frontend and backend services.
- Added .env.development for development environment configuration.
- Introduced .env.docker-local for local Docker environment settings.
- Added .env.production for production environment configuration for Synology deployment.
This commit is contained in:
2026-01-30 11:29:17 -05:00
parent 4d14f9ba9c
commit fee8fe2551
30 changed files with 899 additions and 304 deletions

View File

@@ -0,0 +1,33 @@
# ====================================================================
# BACKEND DEVELOPMENT ENVIRONMENT (localhost:3001)
# ====================================================================
# Used when running: npm run dev (from server directory)
# Supports Vite dev server at localhost:5173
# ====================================================================
# Deployment Target
DEPLOYMENT_TARGET=dev
# Server Configuration
NODE_ENV=development
PORT=3001
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:5173
# Discord OAuth Configuration
VITE_DISCORD_CLIENT_ID=1466544972059775223
DISCORD_CLIENT_SECRET=dMRPAmWxXKQdWOKzgkPbcdsHNCifqtYV
DISCORD_REDIRECT_URI=http://localhost:5173/oauth/callback
VITE_DISCORD_REDIRECT_URI=http://localhost:5173/oauth/callback
# Challonge OAuth Configuration
CHALLONGE_CLIENT_ID=9d40113bdfd802c6fb01137fa9041b23342ce4f100caedad6dee865a486662df
CHALLONGE_CLIENT_SECRET=5dc805e41001281c2415b5ffd6b85a7855fc08b6019d9be2907fdb85ab2d56fc
CHALLONGE_REDIRECT_URI=http://localhost:5173/oauth/callback
# Discord User Permissions
DISCORD_ADMIN_USERS=.fraggin
# Session Security (dev only - change in production)
SESSION_SECRET=dev-secret-for-local-testing-only

View File

@@ -0,0 +1,33 @@
# ====================================================================
# BACKEND LOCAL DOCKER ENVIRONMENT (localhost:3099)
# ====================================================================
# Used in docker-compose.docker-local.yml for local production testing
# Supports frontend at localhost:8099
# ====================================================================
# Deployment Target
DEPLOYMENT_TARGET=docker-local
# Server Configuration
NODE_ENV=production
PORT=3000
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:8099
# Discord OAuth Configuration
VITE_DISCORD_CLIENT_ID=1466544972059775223
DISCORD_CLIENT_SECRET=dMRPAmWxXKQdWOKzgkPbcdsHNCifqtYV
DISCORD_REDIRECT_URI=http://localhost:8099/oauth/callback
VITE_DISCORD_REDIRECT_URI=http://localhost:8099/oauth/callback
# Challonge OAuth Configuration
CHALLONGE_CLIENT_ID=9d40113bdfd802c6fb01137fa9041b23342ce4f100caedad6dee865a486662df
CHALLONGE_CLIENT_SECRET=5dc805e41001281c2415b5ffd6b85a7855fc08b6019d9be2907fdb85ab2d56fc
CHALLONGE_REDIRECT_URI=http://localhost:8099/oauth/callback
# Discord User Permissions
DISCORD_ADMIN_USERS=.fraggin
# Session Security
SESSION_SECRET=local-docker-session-secret-change-for-production

View File

@@ -0,0 +1,33 @@
# ====================================================================
# BACKEND PRODUCTION ENVIRONMENT (app.pokedex.online)
# ====================================================================
# Used in docker-compose.production.yml for Synology deployment
# Supports frontend at https://app.pokedex.online
# ====================================================================
# Deployment Target
DEPLOYMENT_TARGET=production
# Server Configuration
NODE_ENV=production
PORT=3000
# Frontend URL (for CORS)
FRONTEND_URL=https://app.pokedex.online
# Discord OAuth Configuration
VITE_DISCORD_CLIENT_ID=1466544972059775223
DISCORD_CLIENT_SECRET=dMRPAmWxXKQdWOKzgkPbcdsHNCifqtYV
DISCORD_REDIRECT_URI=https://app.pokedex.online/oauth/callback
VITE_DISCORD_REDIRECT_URI=https://app.pokedex.online/oauth/callback
# Challonge OAuth Configuration
CHALLONGE_CLIENT_ID=9d40113bdfd802c6fb01137fa9041b23342ce4f100caedad6dee865a486662df
CHALLONGE_CLIENT_SECRET=5dc805e41001281c2415b5ffd6b85a7855fc08b6019d9be2907fdb85ab2d56fc
CHALLONGE_REDIRECT_URI=https://app.pokedex.online/oauth/callback
# Discord User Permissions
DISCORD_ADMIN_USERS=.fraggin
# Session Security (IMPORTANT: Set a strong secret in production!)
SESSION_SECRET=production-secret-change-this-to-secure-random-string

View File

@@ -9,6 +9,13 @@
* Required environment variables for production
*/
const REQUIRED_ENV_VARS = {
// Deployment Configuration
DEPLOYMENT_TARGET: {
required: true,
description: 'Deployment environment (dev, docker-local, production)',
validate: val => ['dev', 'docker-local', 'production'].includes(val)
},
// Server Configuration
NODE_ENV: {
required: true,
@@ -22,6 +29,34 @@ const REQUIRED_ENV_VARS = {
!isNaN(parseInt(val)) && parseInt(val) > 0 && parseInt(val) < 65536
},
// Frontend URL for CORS
FRONTEND_URL: {
required: true,
description: 'Frontend URL for CORS',
validate: (val, env) => {
if (!val) return false;
// Validate that FRONTEND_URL matches DEPLOYMENT_TARGET (if set)
const target = env?.DEPLOYMENT_TARGET;
if (!target) return true; // Skip validation if target not set yet
if (target === 'dev' && !val.includes('localhost:5173')) {
console.error('⚠️ FRONTEND_URL should be http://localhost:5173 for dev target');
return false;
}
if (target === 'docker-local' && !val.includes('localhost:8099')) {
console.error('⚠️ FRONTEND_URL should be http://localhost:8099 for docker-local target');
return false;
}
if (target === 'production' && !val.includes('app.pokedex.online')) {
console.error('⚠️ FRONTEND_URL should be https://app.pokedex.online for production target');
return false;
}
return true;
}
},
// Optional but recommended for production
SESSION_SECRET: {
required: false,
@@ -31,14 +66,6 @@ const REQUIRED_ENV_VARS = {
? 'SESSION_SECRET should be at least 32 characters for security'
: null
},
FRONTEND_URL: {
required: false,
description: 'Frontend URL for CORS (required in production)',
warn: (val, env) =>
env.NODE_ENV === 'production' && !val
? 'FRONTEND_URL should be set in production for proper CORS'
: null
},
// Challonge OAuth (optional)
CHALLONGE_CLIENT_ID: {
@@ -110,8 +137,10 @@ export function validateOrExit(exitOnError = true) {
// Print validation results
console.log('\n🔍 Environment Validation:');
console.log(` DEPLOYMENT_TARGET: ${process.env.DEPLOYMENT_TARGET || 'not set'}`);
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`);
console.log(` PORT: ${process.env.PORT || 'not set'}`);
console.log(` FRONTEND_URL: ${process.env.FRONTEND_URL || 'not set'}`);
// Show errors
if (result.errors.length > 0) {
@@ -149,7 +178,11 @@ export function validateOrExit(exitOnError = true) {
* @returns {Object} Configuration object
*/
export function getConfig() {
const deploymentTarget = process.env.DEPLOYMENT_TARGET || 'dev';
const frontendUrl = process.env.FRONTEND_URL;
return {
deploymentTarget,
nodeEnv: process.env.NODE_ENV || 'development',
port: parseInt(process.env.PORT || '3001'),
isProduction: process.env.NODE_ENV === 'production',
@@ -165,16 +198,10 @@ export function getConfig() {
)
},
// CORS
// CORS - Single origin based on deployment target
cors: {
origin:
process.env.NODE_ENV === 'production'
? process.env.FRONTEND_URL
: [
'http://localhost:5173',
'http://localhost:5174',
'http://localhost:5175'
]
origin: frontendUrl,
credentials: true
},
// Security
@@ -192,3 +219,8 @@ export function getConfig() {
}
};
}
// Run validation when executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
validateOrExit();
}