Test
This commit is contained in:
94
docker/.dockerignore
Normal file
94
docker/.dockerignore
Normal file
@@ -0,0 +1,94 @@
|
||||
# Dependencies
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Production builds
|
||||
tournament-frontend/build
|
||||
tournament-frontend/dist
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# IDE files
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Dependency directories
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
43
docker/Dockerfile
Normal file
43
docker/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# Use Node.js 20 as base image
|
||||
FROM node:20-alpine
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tournament-frontend/package*.json ./tournament-frontend/
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
RUN cd tournament-frontend && npm ci
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Build the frontend
|
||||
RUN cd tournament-frontend && npm run build
|
||||
|
||||
# Copy built frontend to backend public directory
|
||||
RUN mkdir -p public && cp -r tournament-frontend/build/* public/
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nodejs -u 1001
|
||||
|
||||
# Change ownership of the app directory
|
||||
RUN chown -R nodejs:nodejs /app
|
||||
USER nodejs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 4000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:4000/', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
||||
|
||||
# Start the application
|
||||
CMD ["node", "index.js"]
|
||||
137
docker/ENVIRONMENT.md
Normal file
137
docker/ENVIRONMENT.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Environment Configuration Guide
|
||||
|
||||
## Development Environment
|
||||
|
||||
For development, use the default `docker-compose.yml`:
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Default Credentials (Development)
|
||||
- **Admin Username**: `admin`
|
||||
- **Admin Password**: `admin123`
|
||||
- **Database**: `tournament`
|
||||
- **Database User**: `tournament_user`
|
||||
- **Database Password**: `tournament_password`
|
||||
|
||||
## Production Environment
|
||||
|
||||
For production deployment, use `docker-compose.prod.yml`:
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### Environment Variables (Production)
|
||||
|
||||
Create a `.env` file in the docker directory with the following variables:
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
POSTGRES_PASSWORD=your_secure_postgres_password_here
|
||||
|
||||
# Application Configuration
|
||||
JWT_SECRET=your_super_secure_jwt_secret_here_make_it_long_and_random
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=your_secure_admin_password_here
|
||||
ADMIN_EMAIL=admin@yourdomain.com
|
||||
|
||||
# Optional: Custom domain for SSL
|
||||
DOMAIN=yourdomain.com
|
||||
```
|
||||
|
||||
### Security Checklist for Production
|
||||
|
||||
- [ ] Change `POSTGRES_PASSWORD` to a strong password
|
||||
- [ ] Change `JWT_SECRET` to a long, random string
|
||||
- [ ] Change `ADMIN_PASSWORD` to a secure password
|
||||
- [ ] Update `ADMIN_EMAIL` to a valid email address
|
||||
- [ ] Configure SSL certificates (optional)
|
||||
- [ ] Set up proper firewall rules
|
||||
- [ ] Configure backup strategy
|
||||
- [ ] Set up monitoring and logging
|
||||
|
||||
### SSL Configuration
|
||||
|
||||
To enable HTTPS:
|
||||
|
||||
1. Create an `ssl` directory in the docker folder
|
||||
2. Add your SSL certificates:
|
||||
- `ssl/cert.pem` - SSL certificate
|
||||
- `ssl/key.pem` - Private key
|
||||
3. Uncomment the HTTPS section in `nginx.conf`
|
||||
4. Update the domain name in `nginx.conf`
|
||||
|
||||
### Backup and Restore
|
||||
|
||||
#### Database Backup
|
||||
```bash
|
||||
docker-compose exec postgres pg_dump -U tournament_user tournament > backup.sql
|
||||
```
|
||||
|
||||
#### Database Restore
|
||||
```bash
|
||||
docker-compose exec -T postgres psql -U tournament_user tournament < backup.sql
|
||||
```
|
||||
|
||||
#### Full Application Backup
|
||||
```bash
|
||||
# Backup volumes
|
||||
docker run --rm -v tournament_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres_backup.tar.gz -C /data .
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
#### Health Checks
|
||||
- Application: `http://localhost/health`
|
||||
- Database: Built into docker-compose
|
||||
- Nginx: Built into docker-compose
|
||||
|
||||
#### Logs
|
||||
```bash
|
||||
# View all logs
|
||||
docker-compose logs -f
|
||||
|
||||
# View specific service logs
|
||||
docker-compose logs -f tournament-app
|
||||
docker-compose logs -f postgres
|
||||
docker-compose logs -f nginx
|
||||
```
|
||||
|
||||
### Scaling
|
||||
|
||||
The application can be scaled horizontally:
|
||||
|
||||
```bash
|
||||
docker-compose up -d --scale tournament-app=3
|
||||
```
|
||||
|
||||
Note: You'll need to configure a load balancer (like nginx) to distribute traffic across multiple instances.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Common Issues
|
||||
|
||||
1. **Port conflicts**: Change ports in docker-compose.yml
|
||||
2. **Database connection issues**: Check if PostgreSQL is running and healthy
|
||||
3. **Build failures**: Ensure all dependencies are properly installed
|
||||
4. **Permission issues**: Check file permissions and ownership
|
||||
|
||||
#### Debug Commands
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker-compose ps
|
||||
|
||||
# Access application shell
|
||||
docker-compose exec tournament-app sh
|
||||
|
||||
# Check database connection
|
||||
docker-compose exec postgres psql -U tournament_user -d tournament
|
||||
|
||||
# View nginx configuration
|
||||
docker-compose exec nginx nginx -t
|
||||
```
|
||||
165
docker/README.md
Normal file
165
docker/README.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Tournament Application Docker Setup
|
||||
|
||||
This directory contains the Docker configuration for the Tournament Application.
|
||||
|
||||
## Files
|
||||
|
||||
- `Dockerfile` - Multi-stage build for the application
|
||||
- `docker-compose.yml` - Complete stack with PostgreSQL and Nginx
|
||||
- `nginx.conf` - Nginx reverse proxy configuration
|
||||
- `.dockerignore` - Excludes unnecessary files from build context
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose
|
||||
|
||||
### Running the Application
|
||||
|
||||
1. **Start the complete stack:**
|
||||
```bash
|
||||
cd docker
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
2. **Access the application:**
|
||||
- Frontend: http://localhost:80
|
||||
- API: http://localhost:4000
|
||||
- Database: localhost:5432
|
||||
|
||||
3. **View logs:**
|
||||
```bash
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
4. **Stop the application:**
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
## Services
|
||||
|
||||
### Tournament App (Port 4000)
|
||||
- Node.js backend with Express
|
||||
- React frontend (built and served by backend)
|
||||
- Prisma ORM for database operations
|
||||
- Socket.IO for real-time updates
|
||||
|
||||
### PostgreSQL (Port 5432)
|
||||
- Database: `tournament`
|
||||
- User: `tournament_user`
|
||||
- Password: `tournament_password`
|
||||
|
||||
### Nginx (Port 80/443)
|
||||
- Reverse proxy for the application
|
||||
- Static file serving
|
||||
- SSL termination (configured but disabled by default)
|
||||
|
||||
## Environment Variables
|
||||
|
||||
The application uses the following environment variables:
|
||||
|
||||
```env
|
||||
DATABASE_URL=postgresql://tournament_user:tournament_password@postgres:5432/tournament
|
||||
PORT=4000
|
||||
JWT_SECRET=your-super-secret-jwt-key-change-in-production
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=admin123
|
||||
ADMIN_EMAIL=admin@tournament.com
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Building the Image
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker build -t tournament-app -f Dockerfile ..
|
||||
```
|
||||
|
||||
### Running with Custom Environment
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose.yml -f docker-compose.override.yml up
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### Security Considerations
|
||||
|
||||
1. **Change default passwords:**
|
||||
- Update `ADMIN_PASSWORD` in docker-compose.yml
|
||||
- Update `JWT_SECRET` to a strong random string
|
||||
- Update PostgreSQL password
|
||||
|
||||
2. **Enable HTTPS:**
|
||||
- Uncomment HTTPS section in nginx.conf
|
||||
- Add SSL certificates to `./ssl/` directory
|
||||
- Update domain name in nginx.conf
|
||||
|
||||
3. **Database Security:**
|
||||
- Use external PostgreSQL instance in production
|
||||
- Implement proper backup strategy
|
||||
- Use connection pooling
|
||||
|
||||
### Scaling
|
||||
|
||||
The application can be scaled horizontally:
|
||||
|
||||
```bash
|
||||
docker-compose up -d --scale tournament-app=3
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Database Connection Issues
|
||||
|
||||
1. Check if PostgreSQL is running:
|
||||
```bash
|
||||
docker-compose ps postgres
|
||||
```
|
||||
|
||||
2. Check database logs:
|
||||
```bash
|
||||
docker-compose logs postgres
|
||||
```
|
||||
|
||||
### Application Issues
|
||||
|
||||
1. Check application logs:
|
||||
```bash
|
||||
docker-compose logs tournament-app
|
||||
```
|
||||
|
||||
2. Access application shell:
|
||||
```bash
|
||||
docker-compose exec tournament-app sh
|
||||
```
|
||||
|
||||
### Nginx Issues
|
||||
|
||||
1. Check nginx logs:
|
||||
```bash
|
||||
docker-compose logs nginx
|
||||
```
|
||||
|
||||
2. Test nginx configuration:
|
||||
```bash
|
||||
docker-compose exec nginx nginx -t
|
||||
```
|
||||
|
||||
## Data Persistence
|
||||
|
||||
The PostgreSQL data is persisted in a Docker volume named `postgres_data`. To backup:
|
||||
|
||||
```bash
|
||||
docker-compose exec postgres pg_dump -U tournament_user tournament > backup.sql
|
||||
```
|
||||
|
||||
To restore:
|
||||
|
||||
```bash
|
||||
docker-compose exec -T postgres psql -U tournament_user tournament < backup.sql
|
||||
```
|
||||
36
docker/build.sh
Executable file
36
docker/build.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Tournament Application Docker Build Script
|
||||
|
||||
set -e
|
||||
|
||||
echo "🏗️ Building Tournament Application Docker Image..."
|
||||
|
||||
# Check if we're in the docker directory
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
echo "❌ Error: Please run this script from the docker directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build the application image
|
||||
echo "📦 Building application image..."
|
||||
docker build -t tournament-app -f Dockerfile ..
|
||||
|
||||
# Check if build was successful
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Application image built successfully!"
|
||||
else
|
||||
echo "❌ Failed to build application image"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🎉 Build completed successfully!"
|
||||
echo ""
|
||||
echo "To run the application:"
|
||||
echo " docker-compose up -d"
|
||||
echo ""
|
||||
echo "To view logs:"
|
||||
echo " docker-compose logs -f"
|
||||
echo ""
|
||||
echo "To stop the application:"
|
||||
echo " docker-compose down"
|
||||
55
docker/deploy.sh
Executable file
55
docker/deploy.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Tournament Application Production Deployment Script
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Tournament Application to Production..."
|
||||
|
||||
# Check if we're in the docker directory
|
||||
if [ ! -f "docker-compose.prod.yml" ]; then
|
||||
echo "❌ Error: Please run this script from the docker directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "⚠️ Warning: No .env file found. Using default values."
|
||||
echo " Create a .env file with production values for security."
|
||||
fi
|
||||
|
||||
# Stop existing containers
|
||||
echo "🛑 Stopping existing containers..."
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
|
||||
# Build and start the application
|
||||
echo "🏗️ Building and starting application..."
|
||||
docker-compose -f docker-compose.prod.yml up -d --build
|
||||
|
||||
# Wait for services to be healthy
|
||||
echo "⏳ Waiting for services to be ready..."
|
||||
sleep 10
|
||||
|
||||
# Check if services are running
|
||||
echo "🔍 Checking service status..."
|
||||
docker-compose -f docker-compose.prod.yml ps
|
||||
|
||||
# Check application health
|
||||
echo "🏥 Checking application health..."
|
||||
if curl -f http://localhost/health > /dev/null 2>&1; then
|
||||
echo "✅ Application is healthy!"
|
||||
else
|
||||
echo "⚠️ Application health check failed, but it might still be starting up..."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 Deployment completed!"
|
||||
echo ""
|
||||
echo "Application URLs:"
|
||||
echo " Frontend: http://localhost"
|
||||
echo " API: http://localhost:4000"
|
||||
echo ""
|
||||
echo "Useful commands:"
|
||||
echo " View logs: docker-compose -f docker-compose.prod.yml logs -f"
|
||||
echo " Stop app: docker-compose -f docker-compose.prod.yml down"
|
||||
echo " Restart: docker-compose -f docker-compose.prod.yml restart"
|
||||
95
docker/docker-compose.prod.yml
Normal file
95
docker/docker-compose.prod.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL Database
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: tournament-postgres-prod
|
||||
environment:
|
||||
POSTGRES_DB: tournament
|
||||
POSTGRES_USER: tournament_user
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me_in_production}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ../prisma/migrations:/docker-entrypoint-initdb.d
|
||||
ports:
|
||||
- "127.0.0.1:5432:5432" # Only accessible from localhost
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U tournament_user -d tournament"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- tournament-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Tournament Application
|
||||
tournament-app:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
container_name: tournament-app-prod
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://tournament_user:${POSTGRES_PASSWORD:-change_me_in_production}@postgres:5432/tournament
|
||||
- PORT=4000
|
||||
- JWT_SECRET=${JWT_SECRET:-change_me_in_production}
|
||||
- ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
|
||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-change_me_in_production}
|
||||
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@tournament.com}
|
||||
- NODE_ENV=production
|
||||
ports:
|
||||
- "127.0.0.1:4000:4000" # Only accessible from localhost
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ../prisma:/app/prisma
|
||||
networks:
|
||||
- tournament-network
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '0.5'
|
||||
reservations:
|
||||
memory: 256M
|
||||
cpus: '0.25'
|
||||
|
||||
# Nginx Reverse Proxy
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: tournament-nginx-prod
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./ssl:/etc/nginx/ssl:ro
|
||||
- nginx_logs:/var/log/nginx
|
||||
depends_on:
|
||||
- tournament-app
|
||||
networks:
|
||||
- tournament-network
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
reservations:
|
||||
memory: 64M
|
||||
cpus: '0.1'
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
nginx_logs:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
tournament-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
70
docker/docker-compose.yml
Normal file
70
docker/docker-compose.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL Database
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: tournament-postgres
|
||||
environment:
|
||||
POSTGRES_DB: tournament
|
||||
POSTGRES_USER: tournament_user
|
||||
POSTGRES_PASSWORD: tournament_password
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./prisma/migrations:/docker-entrypoint-initdb.d
|
||||
ports:
|
||||
- "5432:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U tournament_user -d tournament"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- tournament-network
|
||||
|
||||
# Tournament Application
|
||||
tournament-app:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
container_name: tournament-app
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://tournament_user:tournament_password@postgres:5432/tournament
|
||||
- PORT=4000
|
||||
- JWT_SECRET=your-super-secret-jwt-key-change-in-production
|
||||
- ADMIN_USERNAME=admin
|
||||
- ADMIN_PASSWORD=admin123
|
||||
- ADMIN_EMAIL=admin@tournament.com
|
||||
ports:
|
||||
- "4000:4000"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ../prisma:/app/prisma
|
||||
networks:
|
||||
- tournament-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Nginx Reverse Proxy (Optional)
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: tournament-nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./ssl:/etc/nginx/ssl:ro
|
||||
depends_on:
|
||||
- tournament-app
|
||||
networks:
|
||||
- tournament-network
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
tournament-network:
|
||||
driver: bridge
|
||||
85
docker/nginx.conf
Normal file
85
docker/nginx.conf
Normal file
@@ -0,0 +1,85 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream tournament_backend {
|
||||
server tournament-app:4000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
||||
|
||||
# API routes
|
||||
location /api/ {
|
||||
proxy_pass http://tournament_backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
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;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
# WebSocket support for Socket.IO
|
||||
location /socket.io/ {
|
||||
proxy_pass http://tournament_backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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;
|
||||
}
|
||||
|
||||
# Serve static files (React build)
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS configuration (uncomment and configure SSL certificates)
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name localhost;
|
||||
#
|
||||
# ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
# ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||
#
|
||||
# # SSL configuration
|
||||
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
|
||||
# ssl_prefer_server_ciphers off;
|
||||
#
|
||||
# # Same location blocks as above
|
||||
# location /api/ {
|
||||
# proxy_pass http://tournament_backend;
|
||||
# # ... same proxy settings
|
||||
# }
|
||||
# }
|
||||
}
|
||||
Reference in New Issue
Block a user