Deploy Docker app to VPS with SSL #3
5 changed files with 807 additions and 50 deletions
90
.env.production
Normal file
90
.env.production
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# GeoGuessr MCP Server - Production Configuration
|
||||
# This file is for VPS deployment with nginx-proxy-manager and SSL
|
||||
|
||||
# =============================================================================
|
||||
# Docker Image Configuration (REQUIRED for production)
|
||||
# =============================================================================
|
||||
# Your Docker Hub username - MUST match your pushed image
|
||||
DOCKER_USERNAME=yourusername
|
||||
|
||||
# Docker image tag to use
|
||||
# Options: latest, v1.0.0, v1.1.0, etc.
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# =============================================================================
|
||||
# GeoGuessr Authentication (REQUIRED for most features)
|
||||
# =============================================================================
|
||||
# Your GeoGuessr _ncfa cookie for API authentication
|
||||
#
|
||||
# How to get your _ncfa cookie:
|
||||
# 1. Log in to GeoGuessr in your browser
|
||||
# 2. Open Developer Tools (F12 or Ctrl+Shift+I)
|
||||
# 3. Go to the "Application" or "Storage" tab
|
||||
# 4. Under "Cookies", find www.geoguessr.com
|
||||
# 5. Look for the cookie named "_ncfa"
|
||||
# 6. Copy its value and paste it below
|
||||
#
|
||||
# SECURITY WARNING: Keep this secret! Never commit to git.
|
||||
# Anyone with this cookie can access your GeoGuessr account.
|
||||
|
||||
GEOGUESSR_NCFA_COOKIE=your_actual_ncfa_cookie_value_here
|
||||
|
||||
# =============================================================================
|
||||
# MCP Server Configuration
|
||||
# =============================================================================
|
||||
# Transport protocol - keep as streamable-http for production
|
||||
MCP_TRANSPORT=streamable-http
|
||||
|
||||
# Host - keep as 0.0.0.0 to accept connections from nginx-proxy-manager
|
||||
MCP_HOST=0.0.0.0
|
||||
|
||||
# Port - internal port, not exposed to internet (nginx-proxy-manager handles external)
|
||||
MCP_PORT=8000
|
||||
|
||||
# =============================================================================
|
||||
# API Monitoring Configuration (RECOMMENDED for production)
|
||||
# =============================================================================
|
||||
# Enable automatic API endpoint monitoring to detect schema changes
|
||||
MONITORING_ENABLED=true
|
||||
|
||||
# Check endpoints every 24 hours
|
||||
MONITORING_INTERVAL_HOURS=24
|
||||
|
||||
# Directory to store schema cache (persisted in Docker volume)
|
||||
SCHEMA_CACHE_DIR=/app/data/schemas
|
||||
|
||||
# =============================================================================
|
||||
# Logging Configuration
|
||||
# =============================================================================
|
||||
# Log level for production
|
||||
# Options: DEBUG (verbose), INFO (recommended), WARNING, ERROR, CRITICAL
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# For troubleshooting, temporarily set to DEBUG:
|
||||
# LOG_LEVEL=DEBUG
|
||||
|
||||
# =============================================================================
|
||||
# Request Configuration
|
||||
# =============================================================================
|
||||
# Request timeout in seconds (increase if API is slow)
|
||||
REQUEST_TIMEOUT=30.0
|
||||
|
||||
# Maximum retry attempts for failed requests
|
||||
MAX_RETRIES=3
|
||||
|
||||
# =============================================================================
|
||||
# Production Notes
|
||||
# =============================================================================
|
||||
# - This container is accessed through nginx-proxy-manager (firefly_network)
|
||||
# - SSL/HTTPS is handled by nginx-proxy-manager
|
||||
# - Port 8000 is NOT exposed to the internet
|
||||
# - Logs are available via: docker compose -f docker-compose.prod.yml logs -f
|
||||
# - Schema cache is persisted in volume: geoguessr-mcp-schemas-prod
|
||||
#
|
||||
# Deployment steps:
|
||||
# 1. Update DOCKER_USERNAME above
|
||||
# 2. Update GEOGUESSR_NCFA_COOKIE with your actual cookie
|
||||
# 3. Transfer this file to VPS as .env
|
||||
# 4. Run: docker compose -f docker-compose.prod.yml up -d
|
||||
# 5. Configure proxy host in nginx-proxy-manager (port 81)
|
||||
# 6. See DEPLOYMENT.md for detailed instructions
|
||||
444
DEPLOYMENT.md
Normal file
444
DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
# Production Deployment Guide - VPS with SSL
|
||||
|
||||
This guide covers deploying the GeoGuessr MCP Server to your VPS using your existing nginx-proxy-manager for SSL/HTTPS.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- VPS with Docker and Docker Compose installed
|
||||
- Existing nginx-proxy-manager running (port 81 for admin interface)
|
||||
- Domain or subdomain pointing to your VPS (e.g., `geoguessr-mcp.yourdomain.com`)
|
||||
- Docker Hub account (for hosting your image)
|
||||
|
||||
## Deployment Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
Internet ──────HTTPS (443)─────────►│ nginx-proxy-manager │
|
||||
│ (Firefly stack) │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
firefly_network (Docker network)
|
||||
│
|
||||
┌────────────────────┼────────────────────┐
|
||||
│ │ │
|
||||
┌─────▼──────┐ ┌──────▼──────┐ ┌───────▼────────┐
|
||||
│ Firefly │ │ GeoGuessr │ │ Other apps... │
|
||||
│ App │ │ MCP Server │ │ │
|
||||
└────────────┘ └─────────────┘ └────────────────┘
|
||||
```
|
||||
|
||||
## Step 1: Build and Push Docker Image
|
||||
|
||||
### 1.1 Build the Image
|
||||
|
||||
On your local machine or directly on the VPS:
|
||||
|
||||
```bash
|
||||
# Navigate to project directory
|
||||
cd /path/to/GeoGuessrMCP
|
||||
|
||||
# Build the image
|
||||
docker build -t yourusername/geoguessr-mcp:latest .
|
||||
|
||||
# Optional: Build multi-architecture image (if deploying to ARM64)
|
||||
docker buildx build --platform linux/amd64,linux/arm64 \
|
||||
-t yourusername/geoguessr-mcp:latest --push .
|
||||
```
|
||||
|
||||
### 1.2 Push to Docker Hub
|
||||
|
||||
```bash
|
||||
# Login to Docker Hub
|
||||
docker login
|
||||
|
||||
# Push the image
|
||||
docker push yourusername/geoguessr-mcp:latest
|
||||
|
||||
# Optionally tag with version
|
||||
docker tag yourusername/geoguessr-mcp:latest yourusername/geoguessr-mcp:v1.0.0
|
||||
docker push yourusername/geoguessr-mcp:v1.0.0
|
||||
```
|
||||
|
||||
## Step 2: Prepare VPS Directory
|
||||
|
||||
### 2.1 Create Project Directory
|
||||
|
||||
```bash
|
||||
# SSH into your VPS
|
||||
ssh user@your-vps-ip
|
||||
|
||||
# Create directory at same level as /firefly
|
||||
cd /
|
||||
sudo mkdir -p geoguessr-mcp
|
||||
sudo chown $USER:$USER geoguessr-mcp
|
||||
cd geoguessr-mcp
|
||||
```
|
||||
|
||||
### 2.2 Upload Required Files
|
||||
|
||||
Transfer these files to your VPS `/geoguessr-mcp` directory:
|
||||
- `docker-compose.prod.yml`
|
||||
- `.env` (production configuration)
|
||||
|
||||
```bash
|
||||
# From your local machine
|
||||
scp docker-compose.prod.yml user@your-vps-ip:/geoguessr-mcp/
|
||||
scp .env.production user@your-vps-ip:/geoguessr-mcp/.env
|
||||
```
|
||||
|
||||
### 2.3 Configure Environment Variables
|
||||
|
||||
```bash
|
||||
# On VPS - edit .env file
|
||||
cd /geoguessr-mcp
|
||||
nano .env
|
||||
```
|
||||
|
||||
Update the following variables:
|
||||
|
||||
```bash
|
||||
# Docker image configuration
|
||||
DOCKER_USERNAME=yourusername
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# GeoGuessr authentication (REQUIRED for most features)
|
||||
GEOGUESSR_NCFA_COOKIE=your_ncfa_cookie_here
|
||||
|
||||
# Monitoring (recommended for production)
|
||||
MONITORING_ENABLED=true
|
||||
MONITORING_INTERVAL_HOURS=24
|
||||
|
||||
# Logging
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# Schema cache directory (default is fine)
|
||||
SCHEMA_CACHE_DIR=/app/data/schemas
|
||||
```
|
||||
|
||||
## Step 3: Deploy the Container
|
||||
|
||||
### 3.1 Pull and Start the Container
|
||||
|
||||
```bash
|
||||
cd /geoguessr-mcp
|
||||
|
||||
# Pull the latest image
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
|
||||
# Start the service
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# Check logs
|
||||
docker compose -f docker-compose.prod.yml logs -f
|
||||
```
|
||||
|
||||
### 3.2 Verify Container is Running
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker ps | grep geoguessr-mcp
|
||||
|
||||
# Check health status
|
||||
docker inspect geoguessr-mcp-server --format='{{.State.Health.Status}}'
|
||||
|
||||
# Should output: healthy
|
||||
```
|
||||
|
||||
## Step 4: Configure nginx-proxy-manager
|
||||
|
||||
### 4.1 Access nginx-proxy-manager Admin
|
||||
|
||||
1. Open browser and navigate to: `http://your-vps-ip:81`
|
||||
2. Login with your credentials (default: `admin@example.com` / `changeme`)
|
||||
|
||||
### 4.2 Add Proxy Host
|
||||
|
||||
1. Click **"Hosts"** → **"Proxy Hosts"** → **"Add Proxy Host"**
|
||||
|
||||
2. **Details Tab:**
|
||||
- **Domain Names:** `geoguessr-mcp.yourdomain.com` (your subdomain)
|
||||
- **Scheme:** `http`
|
||||
- **Forward Hostname/IP:** `geoguessr-mcp-server` (container name)
|
||||
- **Forward Port:** `8000`
|
||||
- **Cache Assets:** ✓ (enable)
|
||||
- **Block Common Exploits:** ✓ (enable)
|
||||
- **Websockets Support:** ✓ (enable - required for MCP)
|
||||
|
||||
3. **SSL Tab:**
|
||||
- **SSL Certificate:** Select "Request a new SSL Certificate"
|
||||
- **Force SSL:** ✓ (enable)
|
||||
- **HTTP/2 Support:** ✓ (enable)
|
||||
- **HSTS Enabled:** ✓ (enable)
|
||||
- **Email Address for Let's Encrypt:** your-email@example.com
|
||||
- **I Agree to the Let's Encrypt Terms of Service:** ✓
|
||||
|
||||
4. Click **"Save"**
|
||||
|
||||
nginx-proxy-manager will now:
|
||||
- Request an SSL certificate from Let's Encrypt
|
||||
- Configure automatic HTTPS redirection
|
||||
- Proxy requests to your GeoGuessr MCP container
|
||||
|
||||
### 4.3 Verify SSL is Working
|
||||
|
||||
```bash
|
||||
# Test the endpoint
|
||||
curl https://geoguessr-mcp.yourdomain.com/health
|
||||
|
||||
# Should return: {"status": "healthy"}
|
||||
```
|
||||
|
||||
## Step 5: Connect Claude Desktop
|
||||
|
||||
### 5.1 Update Claude Desktop Configuration
|
||||
|
||||
On your local machine, edit `claude_desktop_config.json`:
|
||||
|
||||
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"geoguessr-mcp": {
|
||||
"url": "https://geoguessr-mcp.yourdomain.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 Restart Claude Desktop
|
||||
|
||||
Close and reopen Claude Desktop. The MCP server should now appear in the tools list.
|
||||
|
||||
## Step 6: Monitoring and Maintenance
|
||||
|
||||
### 6.1 View Logs
|
||||
|
||||
```bash
|
||||
# Follow logs in real-time
|
||||
docker compose -f docker-compose.prod.yml logs -f geoguessr-mcp
|
||||
|
||||
# View last 100 lines
|
||||
docker compose -f docker-compose.prod.yml logs --tail=100 geoguessr-mcp
|
||||
```
|
||||
|
||||
### 6.2 Update the Application
|
||||
|
||||
```bash
|
||||
cd /geoguessr-mcp
|
||||
|
||||
# Pull latest image
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
|
||||
# Recreate container with new image
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# Remove old images
|
||||
docker image prune -f
|
||||
```
|
||||
|
||||
### 6.3 Backup Schema Data
|
||||
|
||||
The schema cache is persisted in a Docker volume. To backup:
|
||||
|
||||
```bash
|
||||
# Create backup directory
|
||||
mkdir -p ~/backups
|
||||
|
||||
# Backup the volume
|
||||
docker run --rm \
|
||||
-v geoguessr-mcp-schemas-prod:/data \
|
||||
-v ~/backups:/backup \
|
||||
alpine tar czf /backup/geoguessr-schemas-$(date +%Y%m%d).tar.gz -C /data .
|
||||
```
|
||||
|
||||
### 6.4 SSL Certificate Renewal
|
||||
|
||||
Let's Encrypt certificates are valid for 90 days. nginx-proxy-manager automatically renews them. To manually check:
|
||||
|
||||
1. Go to nginx-proxy-manager admin (port 81)
|
||||
2. Navigate to **"SSL Certificates"**
|
||||
3. Check expiry date
|
||||
4. Click **"Renew"** if needed
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container Won't Start
|
||||
|
||||
```bash
|
||||
# Check logs for errors
|
||||
docker compose -f docker-compose.prod.yml logs geoguessr-mcp
|
||||
|
||||
# Common issues:
|
||||
# - Missing .env file
|
||||
# - Invalid NCFA cookie
|
||||
# - Network connection issues
|
||||
```
|
||||
|
||||
### SSL Certificate Failed
|
||||
|
||||
1. Ensure DNS is pointing to your VPS IP
|
||||
2. Check firewall allows ports 80 and 443
|
||||
3. Verify email address is valid
|
||||
4. Check nginx-proxy-manager logs:
|
||||
|
||||
```bash
|
||||
docker logs proxy_app
|
||||
```
|
||||
|
||||
### Can't Connect from Claude Desktop
|
||||
|
||||
1. Verify container is healthy: `docker ps`
|
||||
2. Test locally on VPS: `curl http://localhost:8000/health`
|
||||
3. Test through proxy: `curl https://geoguessr-mcp.yourdomain.com/health`
|
||||
4. Check nginx-proxy-manager proxy host configuration
|
||||
5. Verify firewall allows HTTPS (port 443)
|
||||
|
||||
### Schema Not Persisting
|
||||
|
||||
```bash
|
||||
# Check volume exists
|
||||
docker volume ls | grep geoguessr-mcp-schemas-prod
|
||||
|
||||
# Inspect volume
|
||||
docker volume inspect geoguessr-mcp-schemas-prod
|
||||
|
||||
# If missing, recreate:
|
||||
docker compose -f docker-compose.prod.yml down
|
||||
docker volume create geoguessr-mcp-schemas-prod
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### 1. Secure Environment Variables
|
||||
|
||||
```bash
|
||||
# Ensure .env file is not world-readable
|
||||
chmod 600 .env
|
||||
|
||||
# Never commit .env to git
|
||||
# (already in .gitignore)
|
||||
```
|
||||
|
||||
### 2. Update nginx-proxy-manager Default Credentials
|
||||
|
||||
After first login:
|
||||
1. Go to **"Users"**
|
||||
2. Edit the admin user
|
||||
3. Change email and password
|
||||
4. Enable 2FA if available
|
||||
|
||||
### 3. Configure Firewall
|
||||
|
||||
```bash
|
||||
# Allow only necessary ports
|
||||
sudo ufw allow 22/tcp # SSH
|
||||
sudo ufw allow 80/tcp # HTTP (for Let's Encrypt)
|
||||
sudo ufw allow 443/tcp # HTTPS
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
### 4. Regular Updates
|
||||
|
||||
```bash
|
||||
# Update system packages
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Update Docker images monthly
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 5. Monitor Access Logs
|
||||
|
||||
nginx-proxy-manager provides access logs:
|
||||
1. Admin interface → **"Hosts"** → **"Proxy Hosts"**
|
||||
2. Click on your host → **"Access List"** tab
|
||||
3. Optionally restrict by IP addresses
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Enable Caching in nginx-proxy-manager
|
||||
|
||||
Add custom nginx configuration:
|
||||
|
||||
```nginx
|
||||
# In proxy host "Advanced" tab
|
||||
proxy_cache_path /tmp/cache levels=1:2 keys_zone=geoguessr_cache:10m max_size=100m inactive=60m;
|
||||
proxy_cache geoguessr_cache;
|
||||
proxy_cache_valid 200 10m;
|
||||
proxy_cache_valid 404 1m;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
```
|
||||
|
||||
### 2. Adjust Container Resources
|
||||
|
||||
If needed, limit resources in `docker-compose.prod.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
geoguessr-mcp:
|
||||
# ... existing config ...
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 256M
|
||||
```
|
||||
|
||||
## Monitoring Tools
|
||||
|
||||
### Check API Endpoint Status
|
||||
|
||||
Use the MCP tools in Claude:
|
||||
|
||||
```
|
||||
Use the check_api_status() tool to see:
|
||||
- All monitored endpoints
|
||||
- Response times
|
||||
- Schema changes
|
||||
- Error rates
|
||||
```
|
||||
|
||||
### Container Health Metrics
|
||||
|
||||
```bash
|
||||
# CPU and memory usage
|
||||
docker stats geoguessr-mcp-server
|
||||
|
||||
# Detailed inspection
|
||||
docker inspect geoguessr-mcp-server
|
||||
```
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
If an update causes issues:
|
||||
|
||||
```bash
|
||||
cd /geoguessr-mcp
|
||||
|
||||
# Stop current version
|
||||
docker compose -f docker-compose.prod.yml down
|
||||
|
||||
# Update .env to use previous tag
|
||||
nano .env
|
||||
# Change: IMAGE_TAG=v1.0.0 (or previous version)
|
||||
|
||||
# Restart with old version
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Issues:** https://github.com/yourusername/geoguessr-mcp/issues
|
||||
- **Logs:** Always include container logs when reporting issues
|
||||
- **nginx-proxy-manager docs:** https://nginxproxymanager.com/guide/
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-11-29
|
||||
33
README.md
33
README.md
|
|
@ -204,27 +204,32 @@ EOF
|
|||
docker compose up -d
|
||||
```
|
||||
|
||||
#### Production Setup with SSL
|
||||
#### Production Setup with SSL (VPS with nginx-proxy-manager)
|
||||
|
||||
1. Create SSL certificates:
|
||||
If you have an existing nginx-proxy-manager setup (like with Firefly III), you can easily deploy this alongside it:
|
||||
|
||||
1. **Build and push your image to Docker Hub:**
|
||||
```bash
|
||||
mkdir -p nginx/ssl
|
||||
# Add your certificates:
|
||||
# nginx/ssl/fullchain.pem
|
||||
# nginx/ssl/privkey.pem
|
||||
docker build -t yourusername/geoguessr-mcp:latest .
|
||||
docker push yourusername/geoguessr-mcp:latest
|
||||
```
|
||||
|
||||
2. Update docker-compose.prod.yml to use your Docker image:
|
||||
2. **Deploy on VPS using the automated script:**
|
||||
```bash
|
||||
# Edit docker-compose.prod.yml and uncomment the image line:
|
||||
# image: ${DOCKER_USERNAME:-yourusername}/geoguessr-mcp:${IMAGE_TAG:-latest}
|
||||
# Then comment out the build section
|
||||
# On your VPS
|
||||
cd /geoguessr-mcp
|
||||
cp .env.production .env
|
||||
# Edit .env with your DOCKER_USERNAME and GEOGUESSR_NCFA_COOKIE
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
3. Deploy with production compose:
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
3. **Configure SSL in nginx-proxy-manager:**
|
||||
- Access admin panel: `http://your-vps-ip:81`
|
||||
- Add Proxy Host for your domain
|
||||
- Forward to: `geoguessr-mcp-server:8000`
|
||||
- Enable SSL with Let's Encrypt
|
||||
|
||||
**📖 For detailed VPS deployment instructions, see [DEPLOYMENT.md](DEPLOYMENT.md)**
|
||||
|
||||
### Method 3: Direct Docker Run
|
||||
|
||||
|
|
|
|||
235
deploy.sh
Executable file
235
deploy.sh
Executable file
|
|
@ -0,0 +1,235 @@
|
|||
#!/bin/bash
|
||||
# GeoGuessr MCP Server - Production Deployment Script
|
||||
# This script helps deploy the application to a VPS with nginx-proxy-manager
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
COMPOSE_FILE="docker-compose.prod.yml"
|
||||
ENV_FILE=".env"
|
||||
ENV_EXAMPLE=".env.production"
|
||||
|
||||
# Helper functions
|
||||
print_header() {
|
||||
echo -e "\n${BLUE}===================================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}===================================================${NC}\n"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ $1${NC}"
|
||||
}
|
||||
|
||||
# Check if running on VPS or local
|
||||
check_environment() {
|
||||
print_header "Step 1: Environment Check"
|
||||
|
||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||
print_error "docker-compose.prod.yml not found!"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Found $COMPOSE_FILE"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
print_warning "$ENV_FILE not found. Creating from example..."
|
||||
if [ -f "$ENV_EXAMPLE" ]; then
|
||||
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
||||
print_warning "Please edit $ENV_FILE with your actual credentials!"
|
||||
print_info "Required: DOCKER_USERNAME and GEOGUESSR_NCFA_COOKIE"
|
||||
exit 1
|
||||
else
|
||||
print_error "No .env.production example found!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
print_success "Found $ENV_FILE"
|
||||
|
||||
# Check Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_error "Docker is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Docker is installed"
|
||||
|
||||
# Check Docker Compose
|
||||
if ! docker compose version &> /dev/null; then
|
||||
print_error "Docker Compose is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Docker Compose is installed"
|
||||
}
|
||||
|
||||
# Check if .env is properly configured
|
||||
check_config() {
|
||||
print_header "Step 2: Configuration Check"
|
||||
|
||||
source "$ENV_FILE"
|
||||
|
||||
if [ -z "$DOCKER_USERNAME" ] || [ "$DOCKER_USERNAME" == "yourusername" ]; then
|
||||
print_error "DOCKER_USERNAME not configured in $ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
print_success "DOCKER_USERNAME is set: $DOCKER_USERNAME"
|
||||
|
||||
if [ -z "$GEOGUESSR_NCFA_COOKIE" ] || [ "$GEOGUESSR_NCFA_COOKIE" == "your_actual_ncfa_cookie_value_here" ]; then
|
||||
print_warning "GEOGUESSR_NCFA_COOKIE not configured"
|
||||
print_info "Most features require authentication. You can set this later."
|
||||
else
|
||||
print_success "GEOGUESSR_NCFA_COOKIE is configured"
|
||||
fi
|
||||
|
||||
if [ -z "$IMAGE_TAG" ]; then
|
||||
IMAGE_TAG="latest"
|
||||
fi
|
||||
print_info "Using image tag: $IMAGE_TAG"
|
||||
}
|
||||
|
||||
# Check if firefly_network exists
|
||||
check_network() {
|
||||
print_header "Step 3: Docker Network Check"
|
||||
|
||||
if docker network inspect firefly_network &> /dev/null; then
|
||||
print_success "firefly_network exists"
|
||||
else
|
||||
print_warning "firefly_network does not exist"
|
||||
print_info "Creating firefly_network..."
|
||||
docker network create firefly_network
|
||||
print_success "Created firefly_network"
|
||||
fi
|
||||
}
|
||||
|
||||
# Pull latest image
|
||||
pull_image() {
|
||||
print_header "Step 4: Pull Docker Image"
|
||||
|
||||
print_info "Pulling image: $DOCKER_USERNAME/geoguessr-mcp:$IMAGE_TAG"
|
||||
docker compose -f "$COMPOSE_FILE" pull
|
||||
print_success "Image pulled successfully"
|
||||
}
|
||||
|
||||
# Stop and remove old container
|
||||
stop_old() {
|
||||
print_header "Step 5: Stop Old Container (if exists)"
|
||||
|
||||
if docker ps -a | grep -q geoguessr-mcp-server; then
|
||||
print_info "Stopping old container..."
|
||||
docker compose -f "$COMPOSE_FILE" down
|
||||
print_success "Old container stopped"
|
||||
else
|
||||
print_info "No existing container found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Start new container
|
||||
start_new() {
|
||||
print_header "Step 6: Start New Container"
|
||||
|
||||
print_info "Starting container in detached mode..."
|
||||
docker compose -f "$COMPOSE_FILE" up -d
|
||||
print_success "Container started"
|
||||
|
||||
print_info "Waiting for container to be healthy..."
|
||||
sleep 5
|
||||
|
||||
# Check health
|
||||
HEALTH=$(docker inspect geoguessr-mcp-server --format='{{.State.Health.Status}}' 2>/dev/null || echo "unknown")
|
||||
if [ "$HEALTH" == "healthy" ]; then
|
||||
print_success "Container is healthy!"
|
||||
elif [ "$HEALTH" == "starting" ]; then
|
||||
print_warning "Container is still starting... Check logs with:"
|
||||
print_info "docker compose -f $COMPOSE_FILE logs -f"
|
||||
else
|
||||
print_warning "Container health check not yet available. Checking if running..."
|
||||
if docker ps | grep -q geoguessr-mcp-server; then
|
||||
print_success "Container is running"
|
||||
else
|
||||
print_error "Container is not running!"
|
||||
print_info "Check logs with: docker compose -f $COMPOSE_FILE logs"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Show logs
|
||||
show_logs() {
|
||||
print_header "Step 7: Recent Logs"
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" logs --tail=20
|
||||
}
|
||||
|
||||
# Show next steps
|
||||
show_next_steps() {
|
||||
print_header "Deployment Complete!"
|
||||
|
||||
echo -e "${GREEN}Your GeoGuessr MCP Server is now running!${NC}\n"
|
||||
|
||||
print_info "Next Steps:"
|
||||
echo ""
|
||||
echo "1. Configure nginx-proxy-manager:"
|
||||
echo " - Access admin panel: http://$(hostname -I | awk '{print $1}'):81"
|
||||
echo " - Add new Proxy Host"
|
||||
echo " - Forward Hostname/IP: geoguessr-mcp-server"
|
||||
echo " - Forward Port: 8000"
|
||||
echo " - Enable SSL with Let's Encrypt"
|
||||
echo ""
|
||||
echo "2. Test the health endpoint:"
|
||||
echo " curl https://your-domain.com/health"
|
||||
echo ""
|
||||
echo "3. Connect Claude Desktop:"
|
||||
echo " Add to claude_desktop_config.json:"
|
||||
echo ' "geoguessr-mcp": { "url": "https://your-domain.com" }'
|
||||
echo ""
|
||||
|
||||
print_info "Useful Commands:"
|
||||
echo ""
|
||||
echo " View logs: docker compose -f $COMPOSE_FILE logs -f"
|
||||
echo " Restart: docker compose -f $COMPOSE_FILE restart"
|
||||
echo " Stop: docker compose -f $COMPOSE_FILE down"
|
||||
echo " Update: ./deploy.sh"
|
||||
echo ""
|
||||
|
||||
print_info "Troubleshooting:"
|
||||
echo ""
|
||||
echo " Check status: docker ps | grep geoguessr-mcp"
|
||||
echo " Check health: docker inspect geoguessr-mcp-server --format='{{.State.Health.Status}}'"
|
||||
echo " Enter container: docker exec -it geoguessr-mcp-server /bin/bash"
|
||||
echo ""
|
||||
|
||||
print_info "For detailed documentation, see: DEPLOYMENT.md"
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
print_header "GeoGuessr MCP Server - Production Deployment"
|
||||
|
||||
check_environment
|
||||
check_config
|
||||
check_network
|
||||
pull_image
|
||||
stop_old
|
||||
start_new
|
||||
show_logs
|
||||
show_next_steps
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
|
|
@ -1,68 +1,51 @@
|
|||
# Production deployment with Nginx reverse proxy and SSL support
|
||||
# Production deployment for VPS with existing nginx-proxy-manager
|
||||
# This configuration connects to an existing nginx-proxy-manager for SSL/HTTPS
|
||||
|
||||
services:
|
||||
geoguessr-mcp:
|
||||
# Option 1: Build locally
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
# Option 1: Build locally (use for initial setup or development)
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile
|
||||
|
||||
# Option 2: Use pre-built image from Docker Hub (recommended for VPS)
|
||||
# Uncomment the line below and comment out the build section above
|
||||
# image: ${DOCKER_USERNAME:-yourusername}/geoguessr-mcp:${IMAGE_TAG:-latest}
|
||||
# Option 2: Use pre-built image from Docker Hub (recommended for production)
|
||||
# Update this with your Docker Hub username
|
||||
image: ${DOCKER_USERNAME:-yourusername}/geoguessr-mcp:${IMAGE_TAG:-latest}
|
||||
|
||||
container_name: geoguessr-mcp-server
|
||||
restart: unless-stopped
|
||||
|
||||
# Use expose instead of ports - only accessible through proxy
|
||||
expose:
|
||||
- "8000"
|
||||
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
volumes:
|
||||
- geoguessr-schemas:/app/data/schemas
|
||||
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:8000/health" ]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
networks:
|
||||
- internal
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: geoguessr-mcp-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./nginx/ssl:/etc/nginx/ssl:ro
|
||||
- ./nginx/logs:/var/log/nginx
|
||||
depends_on:
|
||||
geoguessr-mcp:
|
||||
condition: service_healthy
|
||||
# Connect to the same network as nginx-proxy-manager
|
||||
networks:
|
||||
- internal
|
||||
- external
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "5m"
|
||||
max-file: "3"
|
||||
- firefly_network
|
||||
|
||||
volumes:
|
||||
geoguessr-schemas:
|
||||
name: geoguessr-mcp-schemas-prod
|
||||
|
||||
networks:
|
||||
internal:
|
||||
name: geoguessr-internal
|
||||
internal: true
|
||||
external:
|
||||
name: geoguessr-external
|
||||
firefly_network:
|
||||
external: true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue