golfgame/INSTALL.md
adlee-was-taken 9fc6b83bba v3.0.0: V3 features, server refactoring, and documentation overhaul
- Extract WebSocket handlers from main.py into handlers.py
- Add V3 feature docs (dealer rotation, dealing animation, round end reveal,
  column pair celebration, final turn urgency, opponent thinking, score tallying,
  card hover/selection, knock early drama, column pair indicator, swap animation
  improvements, draw source distinction, card value tooltips, active rules context,
  discard pile history, realistic card sounds)
- Add V3 refactoring docs (ai.py, main.py/game.py, misc improvements)
- Add installation guide with Docker, systemd, and nginx setup
- Add helper scripts (install.sh, dev-server.sh, docker-build.sh)
- Add animation flow diagrams documentation
- Add test files for handlers, rooms, and V3 features
- Add e2e test specs for V3 features
- Update README with complete project structure and current tech stack
- Update CLAUDE.md with full architecture tree and server layer descriptions
- Update .env.example to reflect PostgreSQL (remove SQLite references)
- Update .gitignore to exclude virtualenv files, .claude/, and .db files
- Remove tracked virtualenv files (bin/, lib64, pyvenv.cfg)
- Remove obsolete game_log.py (SQLite) and games.db

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:03:45 -05:00

12 KiB

Golf Game Installation Guide

Complete guide for installing and running the Golf card game server.

Table of Contents


Quick Start

The fastest way to get started is using the interactive installer:

./scripts/install.sh

This provides a menu with options for:

  • Development setup (Docker services + virtualenv + dependencies)
  • Production installation to /opt/golfgame
  • Systemd service configuration
  • Status checks

Requirements

For Development

  • Python 3.11+ (3.12, 3.13, 3.14 also work)
  • Docker and Docker Compose (for PostgreSQL and Redis)
  • Git

For Production

  • Python 3.11+
  • PostgreSQL 16+
  • Redis 7+
  • systemd (for service management)
  • nginx (recommended, for reverse proxy)

Development Setup

./scripts/install.sh
# Select option 1: Development Setup

This will:

  1. Start PostgreSQL and Redis in Docker containers
  2. Create a Python virtual environment
  3. Install all dependencies
  4. Generate a .env file configured for local development

Option B: Manual Setup

1. Start Docker Services

docker-compose -f docker-compose.dev.yml up -d

This starts:

  • PostgreSQL on localhost:5432 (user: golf, password: devpassword, database: golf)
  • Redis on localhost:6379

Verify services are running:

docker-compose -f docker-compose.dev.yml ps

2. Create Python Virtual Environment

# Create venv in project root
python3 -m venv .

# Activate it
source bin/activate

# Upgrade pip
pip install --upgrade pip

# Install dependencies (including dev tools)
pip install -e ".[dev]"

3. Configure Environment

cp .env.example .env

Edit .env for development:

HOST=0.0.0.0
PORT=8000
DEBUG=true
LOG_LEVEL=DEBUG
ENVIRONMENT=development

DATABASE_URL=postgresql://golf:devpassword@localhost:5432/golf
POSTGRES_URL=postgresql://golf:devpassword@localhost:5432/golf

4. Run the Development Server

cd server
../bin/uvicorn main:app --reload --host 0.0.0.0 --port 8000

Or use the helper script:

./scripts/dev-server.sh

The server will be available at http://localhost:8000

5. Verify Installation

# Health check
curl http://localhost:8000/health

# Should return: {"status":"ok","timestamp":"..."}

Stopping Development Services

# Stop the server: Ctrl+C

# Stop Docker containers
docker-compose -f docker-compose.dev.yml down

# Stop and remove volumes (clean slate)
docker-compose -f docker-compose.dev.yml down -v

Production Installation

sudo ./scripts/install.sh
# Select option 2: Production Install to /opt/golfgame

Option B: Manual Installation

1. Install System Dependencies

# Debian/Ubuntu
sudo apt update
sudo apt install -y python3 python3-venv python3-pip postgresql redis-server nginx

# Start and enable services
sudo systemctl enable --now postgresql redis-server nginx

2. Create PostgreSQL Database

sudo -u postgres psql << EOF
CREATE USER golf WITH PASSWORD 'your_secure_password';
CREATE DATABASE golf OWNER golf;
GRANT ALL PRIVILEGES ON DATABASE golf TO golf;
EOF

3. Create Installation Directory

sudo mkdir -p /opt/golfgame
sudo chown $USER:$USER /opt/golfgame

4. Clone and Install Application

cd /opt/golfgame
git clone https://github.com/alee/golfgame.git .

# Create virtual environment
python3 -m venv .
source bin/activate

# Install application
pip install --upgrade pip
pip install .

5. Configure Production Environment

Create /opt/golfgame/.env:

# Generate a secret key
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")

cat > /opt/golfgame/.env << EOF
HOST=0.0.0.0
PORT=8000
DEBUG=false
LOG_LEVEL=INFO
ENVIRONMENT=production

DATABASE_URL=postgresql://golf:your_secure_password@localhost:5432/golf
POSTGRES_URL=postgresql://golf:your_secure_password@localhost:5432/golf

SECRET_KEY=$SECRET_KEY

MAX_PLAYERS_PER_ROOM=6
ROOM_TIMEOUT_MINUTES=60

# Optional: Error tracking with Sentry
# SENTRY_DSN=https://your-sentry-dsn

# Optional: Email via Resend
# RESEND_API_KEY=your-api-key
EOF

# Secure the file
chmod 600 /opt/golfgame/.env

6. Set Ownership

sudo chown -R www-data:www-data /opt/golfgame

7. Create Systemd Service

Create /etc/systemd/system/golfgame.service:

[Unit]
Description=Golf Card Game Server
Documentation=https://github.com/alee/golfgame
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/golfgame/server
Environment="PATH=/opt/golfgame/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=/opt/golfgame/.env
ExecStart=/opt/golfgame/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/golfgame

[Install]
WantedBy=multi-user.target

8. Enable and Start Service

sudo systemctl daemon-reload
sudo systemctl enable golfgame
sudo systemctl start golfgame

# Check status
sudo systemctl status golfgame

# View logs
journalctl -u golfgame -f

9. Configure Nginx Reverse Proxy

Create /etc/nginx/sites-available/golfgame:

upstream golfgame {
    server 127.0.0.1:8000;
    keepalive 64;
}

server {
    listen 80;
    server_name your-domain.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    # SSL configuration (use certbot for Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    location / {
        proxy_pass http://golfgame;
        proxy_http_version 1.1;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Standard proxy headers
        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;

        # Timeouts for WebSocket
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/golfgame /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

10. SSL Certificate (Let's Encrypt)

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com

Docker Deployment

Build the Docker Image

./scripts/docker-build.sh

# Or manually:
docker build -t golfgame:latest .

Development with Docker

# Start dev services only (PostgreSQL + Redis)
docker-compose -f docker-compose.dev.yml up -d

Production with Docker Compose

# Set required environment variables
export DB_PASSWORD="your-secure-database-password"
export SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")
export ACME_EMAIL="your-email@example.com"
export DOMAIN="your-domain.com"

# Optional
export RESEND_API_KEY="your-resend-key"
export SENTRY_DSN="your-sentry-dsn"

# Start all services
docker-compose -f docker-compose.prod.yml up -d

# View logs
docker-compose -f docker-compose.prod.yml logs -f app

# Scale app instances
docker-compose -f docker-compose.prod.yml up -d --scale app=3

The production compose file includes:

  • app: The Golf game server (scalable)
  • postgres: PostgreSQL database
  • redis: Redis for sessions
  • traefik: Reverse proxy with automatic HTTPS

Configuration Reference

Environment Variables

Variable Default Description
HOST 0.0.0.0 Server bind address
PORT 8000 Server port
DEBUG false Enable debug mode
LOG_LEVEL INFO Logging level (DEBUG, INFO, WARNING, ERROR)
ENVIRONMENT production Environment name
DATABASE_URL - PostgreSQL URL (event sourcing, game logs, stats)
POSTGRES_URL - PostgreSQL URL for auth/stats (can be same as DATABASE_URL)
SECRET_KEY - Secret key for JWT tokens
MAX_PLAYERS_PER_ROOM 6 Maximum players per game room
ROOM_TIMEOUT_MINUTES 60 Inactive room cleanup timeout
ROOM_CODE_LENGTH 4 Length of room codes
DEFAULT_ROUNDS 9 Default holes per game
SENTRY_DSN - Sentry error tracking DSN
RESEND_API_KEY - Resend API key for emails
RATE_LIMIT_ENABLED false Enable rate limiting

File Locations

Path Description
/opt/golfgame/ Production installation root
/opt/golfgame/.env Production environment config
/opt/golfgame/server/ Server application code
/opt/golfgame/client/ Static web client
/opt/golfgame/bin/ Python virtualenv binaries
/etc/systemd/system/golfgame.service Systemd service file
/etc/nginx/sites-available/golfgame Nginx site config

Troubleshooting

Check Service Status

# Systemd service
sudo systemctl status golfgame
journalctl -u golfgame -n 100

# Docker containers
docker-compose -f docker-compose.dev.yml ps
docker-compose -f docker-compose.dev.yml logs

# Using the installer
./scripts/install.sh
# Select option 6: Show Status

Health Check

curl http://localhost:8000/health
# Expected: {"status":"ok","timestamp":"..."}

Common Issues

"No module named 'config'"

The server must be started from the server/ directory:

cd /opt/golfgame/server
../bin/uvicorn main:app --host 0.0.0.0 --port 8000

"Connection refused" on PostgreSQL

  1. Check PostgreSQL is running:

    sudo systemctl status postgresql
    # Or for Docker:
    docker ps | grep postgres
    
  2. Verify connection settings in .env

  3. Test connection:

    psql -h localhost -U golf -d golf
    

"POSTGRES_URL not configured" warning

Add POSTGRES_URL to your .env file. This is required for authentication and stats features.

If Python was upgraded, the virtualenv symlinks may break. Recreate it:

rm -rf bin lib lib64 pyvenv.cfg include share
python3 -m venv .
source bin/activate
pip install -e ".[dev]"  # or just: pip install .

Permission denied on /opt/golfgame

sudo chown -R www-data:www-data /opt/golfgame
sudo chmod 600 /opt/golfgame/.env

Updating

Development

git pull
source bin/activate
pip install -e ".[dev]"
# Server auto-reloads with --reload flag

Production

cd /opt/golfgame
sudo systemctl stop golfgame
sudo -u www-data git pull
sudo -u www-data ./bin/pip install .
sudo systemctl start golfgame

Docker

docker-compose -f docker-compose.prod.yml down
git pull
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml up -d

Scripts Reference

Script Description
scripts/install.sh Interactive installer menu
scripts/dev-server.sh Start development server
scripts/docker-build.sh Build production Docker image

Support