Files
caro/docs/deployment-guide.md
T

17 KiB

Deployment Guide

Prerequisites

Required

Optional

  • Git — for cloning repository
  • Docker + Docker Compose — for containerized deployment (recommended for quick start)
  • nginx/Apache — for reverse proxy (if needed)

Quick Start (Docker Compose)

Fastest way to get started — single command:

docker compose up --build

Then:

  • Open http://localhost:8080 in your browser
  • Server API: http://localhost:1024 (TCP), http://localhost:1025 (WebSocket)

Stop:

docker compose down

What's running:

  • caro-server — Java server on 1024 (TCP) + 1025 (WebSocket/HTTP)
  • caro-web-client — Nginx serving web UI on host port 8080

Storage: In-memory only; games not persisted. Restart to clear all rooms.

Logs:

docker compose logs -f caro-server
docker compose logs -f caro-web-client

Prerequisites: Docker + Docker Compose


Local Development Setup

1. Clone Repository

git clone https://github.com/tiennm99/caro.git
cd caro

2. Build Java Modules

Build all modules (server + CLI client):

mvn clean package -DskipTests

Output:

  • landlords-server/target/landlords-server-1.4.0.jar (15-20 MB)
  • landlords-client/target/landlords-client-1.4.0.jar (10-15 MB)
  • landlords-common/target/landlords-common-1.4.0.jar (shared lib)

With tests (recommended):

mvn clean package

Takes ~30-60 seconds. Tests must pass before continuing.

3. Run Server

java -jar landlords-server/target/landlords-server-1.4.0.jar -p 1024

Output:

[INFO] Server listening on port 1024 (TCP)
[INFO] WebSocket server listening on port 1025
[INFO] Static file handler enabled

What's running:

  • TCP port 1024 — CLI clients connect here (Protobuf protocol)
  • WebSocket port 1025 — Web clients connect here (JSON protocol)
  • HTTP port 1025 — Static file serving (same port as WebSocket)

4. Play in Browser (Built-in UI)

Open http://localhost:1025/ in your browser.

This is a basic static HTML UI served directly by the server. To play:

  1. Enter your nickname
  2. Choose PVP or PVE (with difficulty)
  3. Create or join a room
  4. Wait for opponent or start AI game

In a new terminal:

cd web-client
npm install
npm run dev

Output:

  VITE v6.3.1  ready in 234 ms

  ➜  Local:   http://localhost:5173/
  ➜  press h to show help

Open http://localhost:5173/ in your browser.

This is the full-featured Phaser 3 client with:

  • Professional board rendering
  • Stone animations
  • Move history panel
  • Sound effects
  • Better responsive design

6. Play from CLI (Terminal)

In another terminal:

java -jar landlords-client/target/landlords-client-1.4.0.jar -h 127.0.0.1 -p 1024

Usage:

  1. Enter your nickname
  2. Choose game mode (create PVP/PVE, join room, spectate)
  3. Make moves as row,col (e.g., 7,7 for center)
  4. Type exit or e to quit

Production Deployment

Simplest deployment — single command:

java -jar landlords-server-1.4.0.jar -p 1024

For production:

  • Run in background: nohup java -jar ... &
  • Or use systemd service (see below)
  • Or container (Docker)

System Requirements:

  • 512 MB RAM (minimum)
  • 1 GB RAM (recommended)
  • 100 MB disk space
  • Java 8+

Port Configuration:

  • Server listens on -p {port} (TCP)
  • WebSocket/HTTP automatically use {port} + 1

Example:

  • -p 1024 → TCP:1024, WS/HTTP:1025
  • -p 8080 → TCP:8080, WS/HTTP:8081

Option B: Docker Container

Dockerfile example:

FROM openjdk:8-jre-slim

WORKDIR /app

COPY landlords-server/target/landlords-server-1.4.0.jar .

EXPOSE 1024 1025

CMD ["java", "-jar", "landlords-server-1.4.0.jar", "-p", "1024"]

Build:

docker build -t caro-server:1.4.0 .

Run:

docker run -d --name caro-server \
  -p 1024:1024/tcp \
  -p 1025:1025/tcp \
  caro-server:1.4.0

Option C: Linux Systemd Service

Create service file /etc/systemd/system/caro-server.service:

[Unit]
Description=Caro Gomoku Server
After=network.target

[Service]
Type=simple
User=gameserver
WorkingDirectory=/opt/caro
ExecStart=/usr/bin/java -jar /opt/caro/landlords-server-1.4.0.jar -p 1024
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable caro-server
sudo systemctl start caro-server

Monitor:

sudo systemctl status caro-server
sudo journalctl -u caro-server -f

Web Client Deployment

Option A: GitHub Pages (Automatic)

Push to master branch. GitHub Actions automatically:

  1. Build web client (npm run build)
  2. Deploy to https://tiennm99.github.io/caro/

Configuration: .github/workflows/deploy-pages.yml

URL: https://<username>.github.io/caro/

Connect to custom server:

  • Web client connects to server on window.location.hostname
  • For different server, modify connection-service.js endpoint

Option B: Static Hosting (Netlify, Vercel, AWS S3)

Build:

cd web-client
npm install
npm run build

Output: web-client/dist/ directory (ready to deploy)

Deploy to Netlify:

npm install -g netlify-cli
netlify deploy --prod --dir web-client/dist

Deploy to Vercel:

npm install -g vercel
vercel --prod

Deploy to AWS S3:

aws s3 sync web-client/dist/ s3://my-bucket/caro/ --delete

Option C: Nginx Reverse Proxy

Serve web client + proxy API:

server {
    listen 80;
    server_name caro.example.com;

    # Static files (web client)
    location / {
        root /var/www/caro;
        try_files $uri /index.html;
    }

    # WebSocket proxy to server
    location /ratel {
        proxy_pass ws://localhost:1025;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

Deploy:

# Build web client
cd web-client
npm run build

# Copy to nginx root
sudo cp -r dist/* /var/www/caro/

# Restart nginx
sudo systemctl restart nginx

Configuration & Options

Server Options

Usage:

java -jar landlords-server-1.4.0.jar [OPTIONS]

Available options:

-p, -port    TCP port (default: 1024)
              WebSocket will use port + 1 (e.g., 1025)

Examples:

java -jar landlords-server-1.4.0.jar -p 1024    # TCP:1024, WS:1025
java -jar landlords-server-1.4.0.jar -p 8080    # TCP:8080, WS:8081
java -jar landlords-server-1.4.0.jar             # TCP:1024, WS:1025 (default)

CLI Client Options

Usage:

java -jar landlords-client-1.4.0.jar -h <host> -p <port> [OPTIONS]

Required:

-h, -host         Server hostname/IP (required)
-p, -port         Server TCP port (required)

Optional:

-ptl, -protocol   Protocol: "pb" (Protobuf/TCP) or "ws" (WebSocket)
                  Default: "pb" (Protobuf)
-lang             Language: "en", "en_US"
                  Default: "en"

Examples:

# Connect to localhost via TCP (default)
java -jar landlords-client-1.4.0.jar -h 127.0.0.1 -p 1024

# Connect to remote server via WebSocket
java -jar landlords-client-1.4.0.jar -h example.com -p 1024 -ptl ws

# With language
java -jar landlords-client-1.4.0.jar -h localhost -p 1024 -lang en_US

Web Client Configuration

Connection endpoint: Defined in connection-service.js

// Default: connect to server on same host:1025/ratel
const wsUrl = `ws://${window.location.hostname}:1025/ratel`;

To connect to different server:

Edit web-client/src/services/connection-service.js:

// Change this line:
const wsUrl = `ws://${window.location.hostname}:1025/ratel`;

// To:
const wsUrl = 'ws://your-server.com:1025/ratel';

Then rebuild:

npm run build

Running Tests

Java Unit Tests

Run all tests:

mvn clean test

Expected output:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.nico.ratel.landlords.helper.tests.GomokuHelperTest
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0
Running org.nico.ratel.landlords.robot.tests.GomokuAITest
Tests run: 17, Failures: 0, Errors: 0, Skipped: 0

Results: 37 tests passed

Run specific test:

mvn test -Dtest=GomokuHelperTest

Run with coverage (requires plugin):

mvn clean test jacoco:report
# Report: target/site/jacoco/index.html

Web Client Tests

Currently no automated tests for web client (UI testing requires Selenium/Cypress).

Manual testing:

  1. Start server: java -jar landlords-server-1.4.0.jar
  2. Start web client: npm run dev in web-client/
  3. Open browser: http://localhost:5173
  4. Test flows: Create game, make moves, check AI, spectate, etc.

Monitoring & Maintenance

Server Health Check

Check if server is running:

# Check port 1024 (TCP)
netstat -an | grep 1024

# Or using lsof
lsof -i :1024

Test WebSocket connection:

# Using curl (if server supports HTTP health endpoint)
curl -i http://localhost:1025/

# Or open browser console and test:
// In browser console:
ws = new WebSocket('ws://localhost:1025/ratel')
ws.onopen = () => console.log('Connected')
ws.onerror = (e) => console.log('Error:', e)

Logs

Server logs:

  • Standard output (if running in foreground)
  • If using systemd: journalctl -u caro-server -f
  • If using Docker: docker logs -f caro-server

Key log patterns:

[INFO] Client connected: <ip>
[INFO] Room created: <room-id>
[INFO] Game move: <player> at <row>,<col>
[ERROR] Invalid move: <reason>

Performance Monitoring

Memory usage:

# While server is running
top -p $(pgrep -f landlords-server)

Check concurrent connections:

# Linux
netstat -an | grep -c ESTABLISHED

# macOS
netstat -an | grep -c ESTABLISHED

# Or with lsof
lsof -i -P -n | grep java | wc -l

Cleanup & Maintenance

Clear inactive rooms (automatic):

  • Server auto-cleans finished rooms after 1 hour
  • No manual action needed

Restart server:

# Kill current process
kill $(pgrep -f landlords-server)

# Or force kill
kill -9 $(pgrep -f landlords-server)

# Start again
java -jar landlords-server-1.4.0.jar -p 1024

Troubleshooting

Port Already in Use

Error: Address already in use

Solution:

# Find process using port 1024
lsof -i :1024

# Kill it
kill -9 <PID>

# Or use different port
java -jar landlords-server-1.4.0.jar -p 9090

Connection Refused

Error: Connection refused: connect (client can't reach server)

Solutions:

  1. Check server is running:

    ps aux | grep landlords-server
    
  2. Check firewall:

    # Allow port
    sudo ufw allow 1024/tcp
    sudo ufw allow 1025/tcp
    
  3. Check hostname/IP:

    # From client machine, test connectivity
    nc -zv localhost 1024
    nc -zv server-ip 1024
    
  4. Check port mapping (if Docker):

    docker ps -a
    docker port caro-server
    

WebSocket Connection Fails

Error: Failed to connect to WebSocket

Solutions:

  1. Check WebSocket port (TCP + 1):

    # If TCP is 1024, WebSocket should be 1025
    lsof -i :1025
    
  2. Check CORS (if web client on different domain):

    • Server doesn't require CORS (native WebSocket)
    • Ensure client connects to correct hostname
  3. Test WebSocket directly:

    # Using websocat tool
    websocat ws://localhost:1025/ratel
    # Should show connection
    

High Memory Usage

If server uses > 1 GB RAM:

  1. Check concurrent players:

    netstat -an | grep ESTABLISHED | wc -l
    
  2. Increase JVM heap:

    java -Xmx2g -jar landlords-server-1.4.0.jar -p 1024
    
  3. Check for room leaks (finished rooms not cleaned):

    • Restart server to clear memory
    • Or check RoomClearTask configuration

Slow Performance

If moves are delayed (> 500ms):

  1. Check CPU usage:

    top -p $(pgrep -f landlords-server)
    
  2. Check network latency:

    ping server-ip
    
  3. Check board size (AI might be slow):

    • Hard difficulty AI takes ~1 second
    • This is normal, not a bug
  4. Reduce AI difficulty (if PVE):

    • Easy: instant
    • Medium: < 100ms
    • Hard: ~1 second

Client Can't Join Room

Error: Room is full or Room does not exist

Solutions:

  1. Room full: Max 2 players + spectators. Create new room.
  2. Room doesn't exist: Room was deleted (auto-cleanup). List rooms again.
  3. Connection lost: Try reconnecting. Web client auto-reconnects.

Deployment Checklist

Before going live:

  • Java 8+ installed
  • Build successful: mvn clean package (all tests pass)
  • Server starts without errors: java -jar landlords-server-1.4.0.jar -p 1024
  • TCP port 1024 and WebSocket port 1025 open (firewall)
  • Web client built: npm run build
  • Web client connects to correct server endpoint
  • Tested: Create game, make moves, join room, spectate
  • Tested: CLI client connection
  • Monitored: Server memory and CPU under load
  • Logged: Set up log aggregation if needed
  • Backup: Keep copy of JAR and config
  • Health check: Set up monitoring/alerting

Updating & Patching

Update Server

  1. Back up current JAR:

    cp landlords-server-1.4.0.jar landlords-server-1.4.0.jar.backup
    
  2. Download new version:

    git pull origin master
    mvn clean package -DskipTests
    
  3. Stop current server:

    kill $(pgrep -f landlords-server)
    
  4. Start new version:

    java -jar landlords-server/target/landlords-server-1.4.0.jar -p 1024
    
  5. Verify:

    # Test connection
    java -jar landlords-client-1.4.0.jar -h localhost -p 1024
    

Update Web Client

  1. Rebuild:

    cd web-client
    git pull origin master
    npm install
    npm run build
    
  2. Deploy new dist/ to hosting:

    # If using GitHub Pages: just push
    git push origin master
    
    # If manual: copy dist/ to server
    scp -r dist/* user@server:/var/www/caro/
    

Zero-Downtime Update

For critical updates without disconnecting players:

  1. Keep old server running on separate port: -p 9090
  2. Start new server on original port: -p 1024
  3. Gradually migrate clients (or wait for natural disconnect)
  4. Stop old server

Performance Tuning

JVM Tuning

For production servers with 4+ GB RAM:

java -Xmx4g \
     -Xms2g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -jar landlords-server-1.4.0.jar -p 1024

Flags:

  • -Xmx4g — Max heap size (4 GB)
  • -Xms2g — Initial heap size (2 GB)
  • -XX:+UseG1GC — Use G1 garbage collector (better for large heaps)
  • -XX:MaxGCPauseMillis=200 — Limit pause time

Network Tuning

Linux socket tuning (for high concurrency):

# Increase max file descriptors
ulimit -n 65536

# Increase TCP backlog
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535

Load Balancing

If more than 50+ concurrent players, consider load balancing:

upstream caro_servers {
    server localhost:1024;
    server localhost:1025;
}

server {
    listen 1024;
    proxy_pass caro_servers;
}

Rollback Plan

If new version has issues:

  1. Stop new server:

    kill $(pgrep -f landlords-server)
    
  2. Restore backup JAR:

    cp landlords-server-1.4.0.jar.backup landlords-server-1.4.0.jar
    
  3. Start old version:

    java -jar landlords-server-1.4.0.jar -p 1024
    
  4. Notify players:

    • Existing games end
    • Players reconnect to stable version

References