Initial deployment-only branch with production deployment files
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
# SerpentRace Production Server Environment Variables
|
||||||
|
# IMPORTANT: Change all placeholder values before deployment!
|
||||||
|
|
||||||
|
# Production settings
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
DB_HOST=postgres
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=serpentrace
|
||||||
|
DB_USERNAME=postgres
|
||||||
|
# CHANGE THIS: Use a strong password
|
||||||
|
POSTGRES_PASSWORD=CHANGE_THIS_STRONG_DATABASE_PASSWORD_123!
|
||||||
|
|
||||||
|
# Redis Configuration
|
||||||
|
REDIS_URL=redis://redis:6379
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PORT=6379
|
||||||
|
# CHANGE THIS: Set a Redis password for security
|
||||||
|
REDIS_PASSWORD=CHANGE_THIS_REDIS_PASSWORD_123!
|
||||||
|
|
||||||
|
# JWT Configuration
|
||||||
|
# CHANGE THIS: Use a strong secret key (minimum 32 characters)
|
||||||
|
JWT_SECRET=CHANGE_THIS_JWT_SECRET_KEY_MINIMUM_32_CHARACTERS_FOR_PRODUCTION_SECURITY
|
||||||
|
JWT_EXPIRY=86400
|
||||||
|
JWT_EXPIRATION=24h
|
||||||
|
JWT_REFRESH_EXPIRATION=7d
|
||||||
|
|
||||||
|
# Email Configuration (SMTP)
|
||||||
|
# CHANGE THESE: Configure your email provider
|
||||||
|
EMAIL_HOST=smtp.yourmailprovider.com
|
||||||
|
EMAIL_PORT=587
|
||||||
|
EMAIL_SECURE=false
|
||||||
|
EMAIL_USER=your_email@yourdomain.com
|
||||||
|
EMAIL_PASS=your_email_password
|
||||||
|
EMAIL_FROM="SerpentRace <noreply@yourdomain.com>"
|
||||||
|
|
||||||
|
# MinIO Object Storage
|
||||||
|
MINIO_ENDPOINT=minio
|
||||||
|
MINIO_PORT=9000
|
||||||
|
MINIO_USE_SSL=false
|
||||||
|
# CHANGE THESE: Use strong credentials
|
||||||
|
MINIO_ACCESS_KEY=serpentrace_admin
|
||||||
|
MINIO_SECRET_KEY=CHANGE_THIS_MINIO_SECRET_KEY_123!
|
||||||
|
MINIO_BUCKET_NAME=serpentrace-logs
|
||||||
|
|
||||||
|
# Application Settings
|
||||||
|
APP_BASE_URL=http://your-domain.com
|
||||||
|
PORT=3000
|
||||||
|
|
||||||
|
# Chat System Limits
|
||||||
|
CHAT_INACTIVITY_TIMEOUT_MINUTES=30
|
||||||
|
CHAT_MAX_MESSAGES_PER_USER=100
|
||||||
|
CHAT_MESSAGE_CLEANUP_WEEKS=4
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
MAX_LOGS_PER_FILE=10000
|
||||||
|
|
||||||
|
# SSL/TLS Configuration (if using HTTPS)
|
||||||
|
# Uncomment and configure if you have SSL certificates
|
||||||
|
# SSL_CERT_PATH=/path/to/certificate.crt
|
||||||
|
# SSL_KEY_PATH=/path/to/private.key
|
||||||
|
# SSL_CA_PATH=/path/to/ca-bundle.crt
|
||||||
|
|
||||||
|
# Security Headers (already configured in nginx)
|
||||||
|
# These are handled by the nginx configuration
|
||||||
|
|
||||||
|
# Backup Configuration (optional)
|
||||||
|
# BACKUP_ENABLED=true
|
||||||
|
# BACKUP_SCHEDULE=0 2 * * *
|
||||||
|
# BACKUP_RETENTION_DAYS=30
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
# SerpentRace Production Deployment Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This package contains everything needed to deploy SerpentRace in a production environment using pre-built Docker images.
|
||||||
|
|
||||||
|
## Package Contents
|
||||||
|
- `serpentRaceDocker.tar` - All Docker images packed for deployment
|
||||||
|
- `docker-compose.deploy.yml` - Production Docker Compose configuration
|
||||||
|
- `.env.server` - Environment variables template for production
|
||||||
|
- `load-images.bat` - Automated deployment script for Windows servers
|
||||||
|
- `README.md` - This deployment guide
|
||||||
|
|
||||||
|
## System Requirements
|
||||||
|
- Windows Server 2016+ or Windows 10/11
|
||||||
|
- Docker Desktop or Docker Engine
|
||||||
|
- Docker Compose
|
||||||
|
- Minimum 4GB RAM, 20GB free disk space
|
||||||
|
- Network ports: 80, 443, 3000, 5432, 6379, 9000, 9001
|
||||||
|
|
||||||
|
## Pre-Deployment Configuration
|
||||||
|
|
||||||
|
### 1. Environment Variables
|
||||||
|
Edit `.env.server` and update the following **REQUIRED** settings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Database - Use a strong password
|
||||||
|
POSTGRES_PASSWORD=your_strong_database_password
|
||||||
|
|
||||||
|
# JWT Security - Use a random 32+ character string
|
||||||
|
JWT_SECRET=your_super_secret_jwt_key_32_chars_minimum
|
||||||
|
|
||||||
|
# Redis Security
|
||||||
|
REDIS_PASSWORD=your_redis_password
|
||||||
|
|
||||||
|
# MinIO Storage
|
||||||
|
MINIO_ACCESS_KEY=your_minio_admin_user
|
||||||
|
MINIO_SECRET_KEY=your_minio_secret_key
|
||||||
|
|
||||||
|
# Email Configuration (for notifications)
|
||||||
|
EMAIL_HOST=smtp.yourmailprovider.com
|
||||||
|
EMAIL_USER=your_email@yourdomain.com
|
||||||
|
EMAIL_PASS=your_email_password
|
||||||
|
EMAIL_FROM="SerpentRace <noreply@yourdomain.com>"
|
||||||
|
|
||||||
|
# Application URL
|
||||||
|
APP_BASE_URL=http://your-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Security Checklist
|
||||||
|
- [ ] Changed all default passwords
|
||||||
|
- [ ] Generated strong JWT secret (32+ characters)
|
||||||
|
- [ ] Configured email settings
|
||||||
|
- [ ] Updated domain name in APP_BASE_URL
|
||||||
|
- [ ] Configured firewall rules
|
||||||
|
- [ ] Planned SSL certificate setup
|
||||||
|
|
||||||
|
## Deployment Steps
|
||||||
|
|
||||||
|
### Automatic Deployment (Recommended)
|
||||||
|
1. Extract all files to your server directory
|
||||||
|
2. Edit `.env.server` with your configuration
|
||||||
|
3. Run `load-images.bat`
|
||||||
|
4. Follow the prompts
|
||||||
|
|
||||||
|
### Manual Deployment
|
||||||
|
1. Load Docker images:
|
||||||
|
```cmd
|
||||||
|
docker load -i serpentRaceDocker.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start services:
|
||||||
|
```cmd
|
||||||
|
docker-compose -f docker-compose.deploy.yml --env-file .env.server up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Post-Deployment
|
||||||
|
|
||||||
|
### Verify Services
|
||||||
|
Check that all services are running:
|
||||||
|
```cmd
|
||||||
|
docker-compose -f docker-compose.deploy.yml ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access Points
|
||||||
|
- **Frontend Application**: http://localhost (or your domain)
|
||||||
|
- **Backend API**: http://localhost:3000
|
||||||
|
- **MinIO Console**: http://localhost:9001
|
||||||
|
- **Database**: localhost:5432 (internal access only)
|
||||||
|
|
||||||
|
### Initial Setup
|
||||||
|
1. Access the frontend and verify it loads
|
||||||
|
2. Test user registration and login
|
||||||
|
3. Check backend API health: http://localhost:3000/health
|
||||||
|
4. Access MinIO console to verify storage
|
||||||
|
|
||||||
|
### Security Hardening
|
||||||
|
|
||||||
|
#### Firewall Configuration
|
||||||
|
Open only necessary ports:
|
||||||
|
- Port 80 (HTTP) - Public
|
||||||
|
- Port 443 (HTTPS) - Public (when SSL configured)
|
||||||
|
- Ports 3000, 5432, 6379, 9000, 9001 - Internal/VPN only
|
||||||
|
|
||||||
|
#### SSL/TLS Setup
|
||||||
|
1. Obtain SSL certificates (Let's Encrypt, commercial CA)
|
||||||
|
2. Configure nginx for HTTPS in the frontend container
|
||||||
|
3. Update APP_BASE_URL to use https://
|
||||||
|
|
||||||
|
#### Regular Maintenance
|
||||||
|
- Monitor logs: `docker-compose -f docker-compose.deploy.yml logs -f`
|
||||||
|
- Update images periodically
|
||||||
|
- Backup database and MinIO data
|
||||||
|
- Monitor disk space and performance
|
||||||
|
|
||||||
|
## Management Commands
|
||||||
|
|
||||||
|
### View Logs
|
||||||
|
```cmd
|
||||||
|
# All services
|
||||||
|
docker-compose -f docker-compose.deploy.yml logs -f
|
||||||
|
|
||||||
|
# Specific service
|
||||||
|
docker-compose -f docker-compose.deploy.yml logs -f backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restart Services
|
||||||
|
```cmd
|
||||||
|
# Restart all
|
||||||
|
docker-compose -f docker-compose.deploy.yml restart
|
||||||
|
|
||||||
|
# Restart specific service
|
||||||
|
docker-compose -f docker-compose.deploy.yml restart backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stop Services
|
||||||
|
```cmd
|
||||||
|
docker-compose -f docker-compose.deploy.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update Deployment
|
||||||
|
1. Stop current services
|
||||||
|
2. Load new images
|
||||||
|
3. Start services with new configuration
|
||||||
|
|
||||||
|
## Backup Strategy
|
||||||
|
|
||||||
|
### Database Backup
|
||||||
|
```cmd
|
||||||
|
docker exec serpentrace-postgres pg_dump -U postgres serpentrace > backup_$(date +%Y%m%d).sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete Backup
|
||||||
|
```cmd
|
||||||
|
# Stop services
|
||||||
|
docker-compose -f docker-compose.deploy.yml down
|
||||||
|
|
||||||
|
# Backup volumes
|
||||||
|
docker run --rm -v postgres_data:/data -v %cd%:/backup ubuntu tar czf /backup/postgres_backup.tar.gz -C /data .
|
||||||
|
docker run --rm -v minio_data:/data -v %cd%:/backup ubuntu tar czf /backup/minio_backup.tar.gz -C /data .
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
docker-compose -f docker-compose.deploy.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Services Not Starting
|
||||||
|
1. Check Docker is running
|
||||||
|
2. Verify port availability
|
||||||
|
3. Check environment variables
|
||||||
|
4. Review logs for specific errors
|
||||||
|
|
||||||
|
#### Database Connection Issues
|
||||||
|
1. Verify POSTGRES_PASSWORD matches in .env.server
|
||||||
|
2. Check database container is healthy
|
||||||
|
3. Ensure network connectivity
|
||||||
|
|
||||||
|
#### Frontend Not Loading
|
||||||
|
1. Check nginx container status
|
||||||
|
2. Verify backend API is responding
|
||||||
|
3. Check browser console for errors
|
||||||
|
|
||||||
|
#### Performance Issues
|
||||||
|
1. Monitor resource usage: `docker stats`
|
||||||
|
2. Check available disk space
|
||||||
|
3. Review application logs
|
||||||
|
4. Consider scaling if needed
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
- Check application logs for specific error messages
|
||||||
|
- Verify all environment variables are set correctly
|
||||||
|
- Ensure all required ports are available
|
||||||
|
- Contact support with log files and configuration details
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
- SerpentRace Backend: Latest
|
||||||
|
- Frontend: Latest
|
||||||
|
- PostgreSQL: 15-alpine
|
||||||
|
- Redis: 7-alpine
|
||||||
|
- MinIO: Latest
|
||||||
|
- Nginx: Alpine
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Backend service using pre-built image
|
||||||
|
backend:
|
||||||
|
image: serpentrace-backend:latest
|
||||||
|
container_name: serpentrace-backend
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
- DB_HOST=postgres
|
||||||
|
- DB_PORT=5432
|
||||||
|
- DB_NAME=serpentrace
|
||||||
|
- DB_USERNAME=postgres
|
||||||
|
- DB_PASSWORD=${POSTGRES_PASSWORD}
|
||||||
|
- REDIS_URL=redis://redis:6379
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- JWT_SECRET=${JWT_SECRET}
|
||||||
|
- JWT_EXPIRATION=${JWT_EXPIRATION:-24h}
|
||||||
|
- JWT_REFRESH_EXPIRATION=${JWT_REFRESH_EXPIRATION:-7d}
|
||||||
|
- MINIO_ENDPOINT=minio
|
||||||
|
- MINIO_PORT=9000
|
||||||
|
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||||
|
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
|
||||||
|
- MINIO_USE_SSL=false
|
||||||
|
- EMAIL_HOST=${EMAIL_HOST}
|
||||||
|
- EMAIL_PORT=${EMAIL_PORT}
|
||||||
|
- EMAIL_SECURE=${EMAIL_SECURE}
|
||||||
|
- EMAIL_USER=${EMAIL_USER}
|
||||||
|
- EMAIL_PASS=${EMAIL_PASS}
|
||||||
|
- EMAIL_FROM=${EMAIL_FROM}
|
||||||
|
volumes:
|
||||||
|
- backend_logs:/app/logs
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
minio:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- serpentrace-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# Frontend service using pre-built image
|
||||||
|
frontend:
|
||||||
|
image: serpentrace-frontend:latest
|
||||||
|
container_name: serpentrace-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
networks:
|
||||||
|
- serpentrace-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
# PostgreSQL Database
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: serpentrace-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: serpentrace
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
- ./sql_schema_only.sql:/docker-entrypoint-initdb.d/init.sql
|
||||||
|
networks:
|
||||||
|
- serpentrace-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
# Redis Cache
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: serpentrace-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
||||||
|
networks:
|
||||||
|
- serpentrace-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
# MinIO Object Storage
|
||||||
|
minio:
|
||||||
|
image: minio/minio:latest
|
||||||
|
container_name: serpentrace-minio
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
- "9001:9001"
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
|
||||||
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
|
||||||
|
volumes:
|
||||||
|
- minio_data:/data
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
networks:
|
||||||
|
- serpentrace-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
driver: local
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
|
minio_data:
|
||||||
|
driver: local
|
||||||
|
backend_logs:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
serpentrace-network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
@echo off
|
||||||
|
REM SerpentRace Production Deployment Script
|
||||||
|
REM This script loads Docker images and starts the production environment
|
||||||
|
|
||||||
|
setlocal EnableDelayedExpansion
|
||||||
|
|
||||||
|
echo ===============================================
|
||||||
|
echo SerpentRace Production Deployment
|
||||||
|
echo ===============================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Check if Docker is installed
|
||||||
|
where docker >nul 2>nul
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [ERROR] Docker is not installed. Please install Docker first.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
where docker-compose >nul 2>nul
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [ERROR] Docker Compose is not installed. Please install Docker Compose first.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if serpentRaceDocker.tar exists
|
||||||
|
if not exist "serpentRaceDocker.tar" (
|
||||||
|
echo [ERROR] serpentRaceDocker.tar not found!
|
||||||
|
echo Please ensure the tar file is in the same directory as this script.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if environment file exists
|
||||||
|
if not exist ".env.server" (
|
||||||
|
echo [ERROR] .env.server file not found!
|
||||||
|
echo Please ensure the environment file is configured.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo [INFO] Loading Docker images from serpentRaceDocker.tar...
|
||||||
|
docker load -i serpentRaceDocker.tar
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [ERROR] Failed to load Docker images!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo [INFO] Images loaded successfully!
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Show loaded images
|
||||||
|
echo [INFO] Loaded images:
|
||||||
|
docker images | findstr serpentrace
|
||||||
|
docker images | findstr postgres
|
||||||
|
docker images | findstr redis
|
||||||
|
docker images | findstr minio
|
||||||
|
echo.
|
||||||
|
|
||||||
|
echo [WARNING] Before starting the services, please review and update .env.server:
|
||||||
|
echo - Change all placeholder passwords
|
||||||
|
echo - Configure email settings
|
||||||
|
echo - Update domain names
|
||||||
|
echo - Set strong JWT secret
|
||||||
|
echo.
|
||||||
|
echo Press any key to continue with deployment or Ctrl+C to exit...
|
||||||
|
pause >nul
|
||||||
|
|
||||||
|
echo [INFO] Starting production services...
|
||||||
|
docker-compose -f docker-compose.deploy.yml --env-file .env.server up -d
|
||||||
|
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [ERROR] Failed to start services!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ===============================================
|
||||||
|
echo Deployment Complete!
|
||||||
|
echo ===============================================
|
||||||
|
echo.
|
||||||
|
echo Services are starting up. Please wait a few moments for all services to be ready.
|
||||||
|
echo.
|
||||||
|
echo Available services:
|
||||||
|
echo - Frontend: http://localhost (or your domain)
|
||||||
|
echo - Backend API: http://localhost:3000
|
||||||
|
echo - MinIO Console: http://localhost:9001
|
||||||
|
echo.
|
||||||
|
echo To check service status: docker-compose -f docker-compose.deploy.yml ps
|
||||||
|
echo To view logs: docker-compose -f docker-compose.deploy.yml logs -f [service_name]
|
||||||
|
echo To stop services: docker-compose -f docker-compose.deploy.yml down
|
||||||
|
echo.
|
||||||
|
echo IMPORTANT SECURITY NOTES:
|
||||||
|
echo 1. Change all default passwords in .env.server
|
||||||
|
echo 2. Configure firewall rules for your server
|
||||||
|
echo 3. Set up SSL/TLS certificates for HTTPS
|
||||||
|
echo 4. Configure regular backups
|
||||||
|
echo 5. Monitor logs and system resources
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SerpentRace Production Deployment Script for Linux
|
||||||
|
# This script loads Docker images and starts the production environment
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "==============================================="
|
||||||
|
echo "SerpentRace Production Deployment"
|
||||||
|
echo "==============================================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Check if Docker is installed
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "[ERROR] Docker is not installed. Please install Docker first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v docker-compose &> /dev/null; then
|
||||||
|
echo "[ERROR] Docker Compose is not installed. Please install Docker Compose first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if serpentRaceDocker.tar exists
|
||||||
|
if [ ! -f "serpentRaceDocker.tar" ]; then
|
||||||
|
echo "[ERROR] serpentRaceDocker.tar not found!"
|
||||||
|
echo "Please ensure the tar file is in the same directory as this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if environment file exists
|
||||||
|
if [ ! -f ".env.server" ]; then
|
||||||
|
echo "[ERROR] .env.server file not found!"
|
||||||
|
echo "Please ensure the environment file is configured."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] Loading Docker images from serpentRaceDocker.tar..."
|
||||||
|
docker load -i serpentRaceDocker.tar
|
||||||
|
|
||||||
|
echo "[INFO] Images loaded successfully!"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Show loaded images
|
||||||
|
echo "[INFO] Loaded images:"
|
||||||
|
docker images | grep -E "(serpentrace|postgres|redis|minio)"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "[WARNING] Before starting the services, please review and update .env.server:"
|
||||||
|
echo " - Change all placeholder passwords"
|
||||||
|
echo " - Configure email settings"
|
||||||
|
echo " - Update domain names"
|
||||||
|
echo " - Set strong JWT secret"
|
||||||
|
echo
|
||||||
|
read -p "Press Enter to continue with deployment or Ctrl+C to exit..."
|
||||||
|
|
||||||
|
echo "[INFO] Starting production services..."
|
||||||
|
docker-compose -f docker-compose.deploy.yml --env-file .env.server up -d
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "==============================================="
|
||||||
|
echo "Deployment Complete!"
|
||||||
|
echo "==============================================="
|
||||||
|
echo
|
||||||
|
echo "Services are starting up. Please wait a few moments for all services to be ready."
|
||||||
|
echo
|
||||||
|
echo "Available services:"
|
||||||
|
echo " - Frontend: http://localhost (or your domain)"
|
||||||
|
echo " - Backend API: http://localhost:3000"
|
||||||
|
echo " - MinIO Console: http://localhost:9001"
|
||||||
|
echo
|
||||||
|
echo "To check service status: docker-compose -f docker-compose.deploy.yml ps"
|
||||||
|
echo "To view logs: docker-compose -f docker-compose.deploy.yml logs -f [service_name]"
|
||||||
|
echo "To stop services: docker-compose -f docker-compose.deploy.yml down"
|
||||||
|
echo
|
||||||
|
echo "IMPORTANT SECURITY NOTES:"
|
||||||
|
echo "1. Change all default passwords in .env.server"
|
||||||
|
echo "2. Configure firewall rules for your server"
|
||||||
|
echo "3. Set up SSL/TLS certificates for HTTPS"
|
||||||
|
echo "4. Configure regular backups"
|
||||||
|
echo "5. Monitor logs and system resources"
|
||||||
|
echo
|
||||||
Binary file not shown.
@@ -0,0 +1,236 @@
|
|||||||
|
-- SerpentRace Database Schema
|
||||||
|
-- Generated from TypeORM Entity Aggregates
|
||||||
|
-- This file creates the complete database schema without initial data
|
||||||
|
|
||||||
|
-- Enable UUID extension
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||||
|
|
||||||
|
-- Create Users table
|
||||||
|
CREATE TABLE "Users" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"orgid" UUID NULL,
|
||||||
|
"username" VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
"password" VARCHAR(255) NOT NULL,
|
||||||
|
"email" VARCHAR(255) UNIQUE NOT NULL,
|
||||||
|
"fname" VARCHAR(100) NOT NULL,
|
||||||
|
"lname" VARCHAR(100) NOT NULL,
|
||||||
|
"token" VARCHAR(255) NULL,
|
||||||
|
"TokenExpires" TIMESTAMP NULL,
|
||||||
|
"phone" VARCHAR(20) NULL,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"Orglogindate" TIMESTAMP NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create Organizations table
|
||||||
|
CREATE TABLE "Organizations" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"contactfname" VARCHAR(100) NOT NULL,
|
||||||
|
"contactlname" VARCHAR(100) NOT NULL,
|
||||||
|
"contactphone" VARCHAR(20) NOT NULL,
|
||||||
|
"contactemail" VARCHAR(255) NOT NULL,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"url" VARCHAR(500) NULL,
|
||||||
|
"userinorg" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"maxOrganizationalDecks" INTEGER NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create Decks table
|
||||||
|
CREATE TABLE "Decks" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"type" INTEGER NOT NULL,
|
||||||
|
"user_id" UUID NOT NULL,
|
||||||
|
"creation_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"cards" JSONB NOT NULL DEFAULT '[]',
|
||||||
|
"played_number" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"ctype" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"update_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"organization_id" UUID NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create Chats table
|
||||||
|
CREATE TABLE "Chats" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"type" VARCHAR(50) NOT NULL DEFAULT 'direct',
|
||||||
|
"name" VARCHAR(255) NULL,
|
||||||
|
"gameId" UUID NULL,
|
||||||
|
"createdBy" UUID NULL,
|
||||||
|
"users" UUID[] NOT NULL,
|
||||||
|
"messages" JSONB NOT NULL DEFAULT '[]',
|
||||||
|
"lastActivity" TIMESTAMP NULL,
|
||||||
|
"createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"archiveDate" TIMESTAMP NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create Contacts table
|
||||||
|
CREATE TABLE "Contacts" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"email" VARCHAR(255) NOT NULL,
|
||||||
|
"userid" UUID NULL,
|
||||||
|
"type" INTEGER NOT NULL,
|
||||||
|
"txt" TEXT NOT NULL,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"adminResponse" TEXT NULL,
|
||||||
|
"responseDate" TIMESTAMP NULL,
|
||||||
|
"respondedBy" UUID NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create Games table
|
||||||
|
CREATE TABLE "Games" (
|
||||||
|
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
"gamecode" VARCHAR(10) UNIQUE NOT NULL,
|
||||||
|
"maxplayers" INTEGER NOT NULL,
|
||||||
|
"logintype" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"state" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"playerids" UUID[] NOT NULL DEFAULT '{}',
|
||||||
|
"decks" JSONB NOT NULL DEFAULT '[]',
|
||||||
|
"boardsize" INTEGER NOT NULL DEFAULT 50,
|
||||||
|
"createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"finishDate" TIMESTAMP NULL,
|
||||||
|
"winnerid" UUID NULL,
|
||||||
|
"createdBy" UUID NOT NULL,
|
||||||
|
"organizationid" UUID NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Add Foreign Key Constraints
|
||||||
|
ALTER TABLE "Users"
|
||||||
|
ADD CONSTRAINT "FK_Users_Organizations"
|
||||||
|
FOREIGN KEY ("orgid") REFERENCES "Organizations"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Decks"
|
||||||
|
ADD CONSTRAINT "FK_Decks_Users"
|
||||||
|
FOREIGN KEY ("user_id") REFERENCES "Users"("id") ON DELETE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE "Decks"
|
||||||
|
ADD CONSTRAINT "FK_Decks_Organizations"
|
||||||
|
FOREIGN KEY ("organization_id") REFERENCES "Organizations"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Contacts"
|
||||||
|
ADD CONSTRAINT "FK_Contacts_Users"
|
||||||
|
FOREIGN KEY ("userid") REFERENCES "Users"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Contacts"
|
||||||
|
ADD CONSTRAINT "FK_Contacts_RespondedBy"
|
||||||
|
FOREIGN KEY ("respondedBy") REFERENCES "Users"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Chats"
|
||||||
|
ADD CONSTRAINT "FK_Chats_CreatedBy"
|
||||||
|
FOREIGN KEY ("createdBy") REFERENCES "Users"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Chats"
|
||||||
|
ADD CONSTRAINT "FK_Chats_Games"
|
||||||
|
FOREIGN KEY ("gameId") REFERENCES "Games"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Games"
|
||||||
|
ADD CONSTRAINT "FK_Games_CreatedBy"
|
||||||
|
FOREIGN KEY ("createdBy") REFERENCES "Users"("id") ON DELETE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE "Games"
|
||||||
|
ADD CONSTRAINT "FK_Games_Organizations"
|
||||||
|
FOREIGN KEY ("organizationid") REFERENCES "Organizations"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
ALTER TABLE "Games"
|
||||||
|
ADD CONSTRAINT "FK_Games_Winner"
|
||||||
|
FOREIGN KEY ("winnerid") REFERENCES "Users"("id") ON DELETE SET NULL;
|
||||||
|
|
||||||
|
-- Create Indexes for Performance
|
||||||
|
CREATE INDEX "IDX_Users_Username" ON "Users" ("username");
|
||||||
|
CREATE INDEX "IDX_Users_Email" ON "Users" ("email");
|
||||||
|
CREATE INDEX "IDX_Users_OrgId" ON "Users" ("orgid");
|
||||||
|
CREATE INDEX "IDX_Users_State" ON "Users" ("state");
|
||||||
|
|
||||||
|
CREATE INDEX "IDX_Organizations_Name" ON "Organizations" ("name");
|
||||||
|
CREATE INDEX "IDX_Organizations_State" ON "Organizations" ("state");
|
||||||
|
|
||||||
|
CREATE INDEX "IDX_Decks_UserId" ON "Decks" ("user_id");
|
||||||
|
CREATE INDEX "IDX_Decks_Type" ON "Decks" ("type");
|
||||||
|
CREATE INDEX "IDX_Decks_CType" ON "Decks" ("ctype");
|
||||||
|
CREATE INDEX "IDX_Decks_State" ON "Decks" ("state");
|
||||||
|
CREATE INDEX "IDX_Decks_OrganizationId" ON "Decks" ("organization_id");
|
||||||
|
|
||||||
|
CREATE INDEX "IDX_Chats_Type" ON "Chats" ("type");
|
||||||
|
CREATE INDEX "IDX_Chats_State" ON "Chats" ("state");
|
||||||
|
CREATE INDEX "IDX_Chats_GameId" ON "Chats" ("gameId");
|
||||||
|
CREATE INDEX "IDX_Chats_CreatedBy" ON "Chats" ("createdBy");
|
||||||
|
|
||||||
|
CREATE INDEX "IDX_Contacts_Type" ON "Contacts" ("type");
|
||||||
|
CREATE INDEX "IDX_Contacts_State" ON "Contacts" ("state");
|
||||||
|
CREATE INDEX "IDX_Contacts_UserId" ON "Contacts" ("userid");
|
||||||
|
|
||||||
|
CREATE INDEX "IDX_Games_GameCode" ON "Games" ("gamecode");
|
||||||
|
CREATE INDEX "IDX_Games_State" ON "Games" ("state");
|
||||||
|
CREATE INDEX "IDX_Games_CreatedBy" ON "Games" ("createdBy");
|
||||||
|
CREATE INDEX "IDX_Games_OrganizationId" ON "Games" ("organizationid");
|
||||||
|
|
||||||
|
-- Create update trigger for updatedate columns
|
||||||
|
CREATE OR REPLACE FUNCTION update_updatedate_column()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW.updatedate = CURRENT_TIMESTAMP;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ language 'plpgsql';
|
||||||
|
|
||||||
|
-- Apply update triggers
|
||||||
|
CREATE TRIGGER update_users_updatedate
|
||||||
|
BEFORE UPDATE ON "Users"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_organizations_updatedate
|
||||||
|
BEFORE UPDATE ON "Organizations"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_decks_updatedate
|
||||||
|
BEFORE UPDATE ON "Decks"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_chats_updatedate
|
||||||
|
BEFORE UPDATE ON "Chats"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_contacts_updatedate
|
||||||
|
BEFORE UPDATE ON "Contacts"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_games_updatedate
|
||||||
|
BEFORE UPDATE ON "Games"
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION update_updatedate_column();
|
||||||
|
|
||||||
|
-- Comments for documentation
|
||||||
|
COMMENT ON TABLE "Users" IS 'User accounts with authentication and profile information';
|
||||||
|
COMMENT ON TABLE "Organizations" IS 'Organizations that can have multiple users and premium features';
|
||||||
|
COMMENT ON TABLE "Decks" IS 'Card decks for the game, can be public, private, or organizational';
|
||||||
|
COMMENT ON TABLE "Chats" IS 'Chat system supporting direct messages, groups, and game chats';
|
||||||
|
COMMENT ON TABLE "Contacts" IS 'Contact form submissions and support tickets';
|
||||||
|
COMMENT ON TABLE "Games" IS 'Game sessions with players, decks, and game state';
|
||||||
|
|
||||||
|
-- Enum value comments
|
||||||
|
COMMENT ON COLUMN "Users"."state" IS '0=REGISTERED_NOT_VERIFIED, 1=VERIFIED_REGULAR, 2=VERIFIED_PREMIUM, 3=SOFT_DELETE, 4=DEACTIVATED, 5=ADMIN';
|
||||||
|
COMMENT ON COLUMN "Organizations"."state" IS '0=REGISTERED, 1=ACTIVE, 2=SOFT_DELETE';
|
||||||
|
COMMENT ON COLUMN "Decks"."type" IS '0=LUCK, 1=JOKER, 2=QUESTION';
|
||||||
|
COMMENT ON COLUMN "Decks"."ctype" IS '0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION';
|
||||||
|
COMMENT ON COLUMN "Decks"."state" IS '0=ACTIVE, 1=SOFT_DELETE';
|
||||||
|
COMMENT ON COLUMN "Chats"."type" IS 'direct, group, game';
|
||||||
|
COMMENT ON COLUMN "Chats"."state" IS '0=ACTIVE, 1=ARCHIVE, 2=SOFT_DELETE';
|
||||||
|
COMMENT ON COLUMN "Contacts"."type" IS '0=BUG, 1=PROBLEM, 2=QUESTION, 3=SALES, 4=OTHER';
|
||||||
|
COMMENT ON COLUMN "Contacts"."state" IS '0=ACTIVE, 1=RESOLVED, 2=SOFT_DELETE';
|
||||||
|
COMMENT ON COLUMN "Games"."state" IS '0=WAITING, 1=ACTIVE, 2=FINISHED, 3=CANCELLED';
|
||||||
|
COMMENT ON COLUMN "Games"."logintype" IS '0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION';
|
||||||
|
|
||||||
|
-- Grant permissions for application user
|
||||||
|
-- Note: Replace 'serpentrace_app' with your actual application database user
|
||||||
|
-- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO serpentrace_app;
|
||||||
|
-- GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO serpentrace_app;
|
||||||
|
-- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO serpentrace_app;
|
||||||
Reference in New Issue
Block a user