Fix: Nakama chess modules, chat WebSocket protocol, and streaming SSL
Some checks failed
Build and Push / build-all (push) Failing after 1m50s
Some checks failed
Build and Push / build-all (push) Failing after 1m50s
- Add Nakama Dockerfile to build custom image with chess modules - Update docker-compose.prod.yml to use custom Nakama image with --runtime.js_entrypoint - Fix chat WebSocket to use wss:// on HTTPS pages (was hardcoded ws://) - Add SSL configuration to nginx port 8088 for HLS/LLHLS streaming - Add Nakama build step to CI workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3155eacdac
commit
e32e5aceaf
5 changed files with 68 additions and 6 deletions
|
|
@ -104,3 +104,20 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
docker push ${{ env.REGISTRY }}/${{ github.repository }}/openresty:${{ github.sha }}
|
docker push ${{ env.REGISTRY }}/${{ github.repository }}/openresty:${{ github.sha }}
|
||||||
docker push ${{ env.REGISTRY }}/${{ github.repository }}/openresty:latest
|
docker push ${{ env.REGISTRY }}/${{ github.repository }}/openresty:latest
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Build Nakama (Game Server with Chess Modules)
|
||||||
|
# =========================================================================
|
||||||
|
- name: Build Nakama Image
|
||||||
|
run: |
|
||||||
|
echo "=== Building Nakama ==="
|
||||||
|
docker build \
|
||||||
|
-t ${{ env.REGISTRY }}/${{ github.repository }}/nakama:${{ github.sha }} \
|
||||||
|
-t ${{ env.REGISTRY }}/${{ github.repository }}/nakama:latest \
|
||||||
|
./nakama
|
||||||
|
|
||||||
|
- name: Push Nakama Image
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
run: |
|
||||||
|
docker push ${{ env.REGISTRY }}/${{ github.repository }}/nakama:${{ github.sha }}
|
||||||
|
docker push ${{ env.REGISTRY }}/${{ github.repository }}/nakama:latest
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ services:
|
||||||
- backend
|
- backend
|
||||||
|
|
||||||
nakama:
|
nakama:
|
||||||
image: registry.heroiclabs.com/heroiclabs/nakama:3.21.1
|
image: qbit.realms.pub/doomtube/beeta/nakama:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
|
|
@ -134,6 +134,7 @@ services:
|
||||||
--database.address "streamuser:$DB_PASSWORD@postgres:5432/nakama?sslmode=disable" \
|
--database.address "streamuser:$DB_PASSWORD@postgres:5432/nakama?sslmode=disable" \
|
||||||
--socket.server_key "$NAKAMA_SERVER_KEY" \
|
--socket.server_key "$NAKAMA_SERVER_KEY" \
|
||||||
--session.token_expiry_sec 86400 \
|
--session.token_expiry_sec 86400 \
|
||||||
|
--runtime.js_entrypoint "main.js" \
|
||||||
--runtime.env "JWT_SECRET=$JWT_SECRET" \
|
--runtime.env "JWT_SECRET=$JWT_SECRET" \
|
||||||
--console.username admin \
|
--console.username admin \
|
||||||
--console.password "$NAKAMA_CONSOLE_PASSWORD" \
|
--console.password "$NAKAMA_CONSOLE_PASSWORD" \
|
||||||
|
|
@ -143,7 +144,6 @@ services:
|
||||||
- NAKAMA_CONSOLE_PASSWORD=${NAKAMA_CONSOLE_PASSWORD}
|
- NAKAMA_CONSOLE_PASSWORD=${NAKAMA_CONSOLE_PASSWORD}
|
||||||
- NAKAMA_SERVER_KEY=${NAKAMA_SERVER_KEY}
|
- NAKAMA_SERVER_KEY=${NAKAMA_SERVER_KEY}
|
||||||
- DB_PASSWORD=${DB_PASSWORD}
|
- DB_PASSWORD=${DB_PASSWORD}
|
||||||
# Custom modules can be baked into a custom nakama image if needed
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:7350/healthcheck"]
|
test: ["CMD", "curl", "-f", "http://localhost:7350/healthcheck"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,9 @@ class ChatWebSocket {
|
||||||
|
|
||||||
// SECURITY FIX #9: Don't include token in URL query params
|
// SECURITY FIX #9: Don't include token in URL query params
|
||||||
// Token will be sent as first message after connection to avoid logging/exposure
|
// Token will be sent as first message after connection to avoid logging/exposure
|
||||||
let wsUrl = `ws://${window.location.host}/chat/ws?realmId=${encodeURIComponent(realmId)}`;
|
// Use wss:// for HTTPS, ws:// for HTTP (dynamic protocol detection)
|
||||||
|
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
let wsUrl = `${wsProtocol}//${window.location.host}/chat/ws?realmId=${encodeURIComponent(realmId)}`;
|
||||||
|
|
||||||
// Guest connection - generate fingerprint for ban enforcement
|
// Guest connection - generate fingerprint for ban enforcement
|
||||||
// Only guests are fingerprinted, registered users are NOT fingerprinted for privacy
|
// Only guests are fingerprinted, registered users are NOT fingerprinted for privacy
|
||||||
|
|
|
||||||
36
nakama/Dockerfile
Normal file
36
nakama/Dockerfile
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Nakama with Custom Chess Modules
|
||||||
|
# =============================================================================
|
||||||
|
# Two-stage build:
|
||||||
|
# 1. Build TypeScript modules with Node.js
|
||||||
|
# 2. Copy compiled JS to Nakama runtime
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Stage 1: Build TypeScript modules
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy module files
|
||||||
|
COPY modules/package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY modules/tsconfig.json ./
|
||||||
|
COPY modules/src ./src
|
||||||
|
|
||||||
|
# Build with esbuild (output to build/index.js)
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Verify build output exists
|
||||||
|
RUN ls -la build/ && test -f build/index.js
|
||||||
|
|
||||||
|
# Stage 2: Nakama runtime with modules
|
||||||
|
FROM registry.heroiclabs.com/heroiclabs/nakama:3.21.1
|
||||||
|
|
||||||
|
# Copy compiled JavaScript modules
|
||||||
|
# Nakama expects modules at /nakama/data/modules/
|
||||||
|
COPY --from=builder /app/build/index.js /nakama/data/modules/main.js
|
||||||
|
|
||||||
|
# Copy config file (optional - can also be passed via CLI)
|
||||||
|
COPY config.yml /nakama/data/config.yml
|
||||||
|
|
@ -820,10 +820,17 @@ http {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Separate server block for port 8088 (HLS/LLHLS)
|
# Separate server block for port 8088 (HLS/LLHLS) - with SSL for production
|
||||||
server {
|
server {
|
||||||
listen 8088;
|
listen 8088 ssl http2;
|
||||||
server_name localhost;
|
server_name beeta.realms.pub;
|
||||||
|
|
||||||
|
# SSL certificates (same as main server block)
|
||||||
|
ssl_certificate /etc/letsencrypt/live/beeta.realms.pub/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/beeta.realms.pub/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
# Site-wide uberban check - blocks banned fingerprints from streaming
|
# Site-wide uberban check - blocks banned fingerprints from streaming
|
||||||
access_by_lua_block {
|
access_by_lua_block {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue