mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-11-03 19:58:14 +00:00 
			
		
		
		
	feat(web-app-chess): add castling.club role with ports, networks, and build setup
- Added network subnet (192.168.103.192/28) and port 8050 for web-app-chess - Replaced stub README with usability-focused description of castling.club - Implemented config, vars, meta, and tasks for web-app-chess - Added Dockerfile, docker-compose.yml, env, and docker-entrypoint.sh templates - Integrated entrypoint asset placement - Updated meta to reflect usability and software features Ref: https://chatgpt.com/share/68b6c65a-3de8-800f-86b2-a110920cd50e
This commit is contained in:
		@@ -96,6 +96,8 @@ defaults_networks:
 | 
			
		||||
      subnet: 192.168.103.160/28
 | 
			
		||||
    web-svc-logout:
 | 
			
		||||
      subnet: 192.168.103.176/28
 | 
			
		||||
    web-app-chess:
 | 
			
		||||
      subnet: 192.168.103.192/28
 | 
			
		||||
 | 
			
		||||
    # /24 Networks / 254 Usable Clients
 | 
			
		||||
    web-app-bigbluebutton:
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,7 @@ ports:
 | 
			
		||||
      web-app-mig: 8047
 | 
			
		||||
      web-svc-logout: 8048
 | 
			
		||||
      web-app-bookwyrm: 8049
 | 
			
		||||
      web-app-chess: 8050
 | 
			
		||||
      web-app-bigbluebutton: 48087    # This port is predefined by bbb. @todo Try to change this to a 8XXX port
 | 
			
		||||
  public:
 | 
			
		||||
    # The following ports should be changed to 22 on the subdomain via stream mapping
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,25 @@
 | 
			
		||||
# Todo 
 | 
			
		||||
- Implement https://joinbookwyrm.com/de/
 | 
			
		||||
# web-app-chess
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
**castling.club** is a federated chess server built on the ActivityPub protocol.  
 | 
			
		||||
It provides an open and decentralized way to play chess online, where games and moves are visible across the Fediverse.
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
Instead of relying on closed platforms, castling.club uses an arbiter actor (“the King”) to validate moves and mediate matches.  
 | 
			
		||||
This ensures fair play, federation with platforms like Mastodon or Friendica, and community visibility of ongoing games.  
 | 
			
		||||
The service runs as a lightweight Node.js app backed by PostgreSQL.
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- **Federated Chess Matches:** Challenge and play with others across the Fediverse.  
 | 
			
		||||
- **Rule Enforcement:** The arbiter validates each move for correctness.  
 | 
			
		||||
- **Open Identities:** Use your existing Fediverse account; no new silo account needed.  
 | 
			
		||||
- **Game Visibility:** Matches and moves can appear in social timelines.  
 | 
			
		||||
- **Lightweight Service:** Built with Node.js and PostgreSQL for efficiency.  
 | 
			
		||||
 | 
			
		||||
## Further Resources
 | 
			
		||||
 | 
			
		||||
- [castling.club GitHub Repository](https://github.com/stephank/castling.club)  
 | 
			
		||||
- [ActivityPub Specification (W3C)](https://www.w3.org/TR/activitypub/)  
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								roles/web-app-chess/config/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								roles/web-app-chess/config/main.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# roles/web-app-chess/config/main.yml
 | 
			
		||||
credentials: {}
 | 
			
		||||
docker:
 | 
			
		||||
  services:
 | 
			
		||||
    database:
 | 
			
		||||
      enabled:      true            # Use central DB role (recommended)
 | 
			
		||||
    application:
 | 
			
		||||
      image:        "node"          # Base image family; final image is custom
 | 
			
		||||
      version:      "20-bullseye"   # >=16 as required upstream
 | 
			
		||||
      name:         "web-app-chess"
 | 
			
		||||
      backup:
 | 
			
		||||
        no_stop_required: true
 | 
			
		||||
  volumes:
 | 
			
		||||
    data:           "chess_data"
 | 
			
		||||
features:
 | 
			
		||||
  matomo:           false
 | 
			
		||||
  css:              false
 | 
			
		||||
  desktop:          false
 | 
			
		||||
  central_database: true
 | 
			
		||||
  logout:           false
 | 
			
		||||
  oidc:             false
 | 
			
		||||
server:
 | 
			
		||||
  csp:
 | 
			
		||||
    whitelist:      {}
 | 
			
		||||
    flags:          {}
 | 
			
		||||
  domains:
 | 
			
		||||
    canonical:
 | 
			
		||||
      - "chess.{{ PRIMARY_DOMAIN }}"
 | 
			
		||||
    aliases: []
 | 
			
		||||
rbac:
 | 
			
		||||
  roles: {}
 | 
			
		||||
source:
 | 
			
		||||
  repo: "https://github.com/stephank/castling.club.git"
 | 
			
		||||
  ref:  "main"
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
---
 | 
			
		||||
galaxy_info:
 | 
			
		||||
  author: "Kevin Veen-Birchenbach"
 | 
			
		||||
  description: "Stub role for deploying a Chess web application via Docker Compose (implementation pending)."
 | 
			
		||||
  description: "Federated chess server based on ActivityPub. Play and follow games across the Fediverse with verified rules and open identities."
 | 
			
		||||
  license: "Infinito.Nexus NonCommercial License"
 | 
			
		||||
  license_url: "https://s.infinito.nexus/license"
 | 
			
		||||
  company: |
 | 
			
		||||
@@ -10,13 +10,16 @@ galaxy_info:
 | 
			
		||||
    https://www.veen.world
 | 
			
		||||
  galaxy_tags:
 | 
			
		||||
    - chess
 | 
			
		||||
    - docker
 | 
			
		||||
    - federation
 | 
			
		||||
    - activitypub
 | 
			
		||||
    - social
 | 
			
		||||
  repository: "https://s.infinito.nexus/code"
 | 
			
		||||
  issue_tracker_url: "https://s.infinito.nexus/issues"
 | 
			
		||||
  documentation: "https://s.infinito.nexus/code/tree/main/roles/web-app-chess"
 | 
			
		||||
  documentation: "https://github.com/stephank/castling.club"
 | 
			
		||||
  logo:
 | 
			
		||||
    class: "fas fa-chess-king"
 | 
			
		||||
  min_ansible_version: "2.9"
 | 
			
		||||
  platforms:
 | 
			
		||||
    - name: Any
 | 
			
		||||
      versions: [ all ]
 | 
			
		||||
dependencies: []
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								roles/web-app-chess/tasks/02_assets.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								roles/web-app-chess/tasks/02_assets.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
- block:
 | 
			
		||||
  - name: "load docker, db and proxy for {{ application_id }}"
 | 
			
		||||
    include_role:
 | 
			
		||||
      name: sys-stk-full-stateful
 | 
			
		||||
 | 
			
		||||
  - name: "Place entrypoint and other assets"
 | 
			
		||||
    include_tasks: 02_assets.yml
 | 
			
		||||
 | 
			
		||||
  - include_tasks: utils/run_once.yml
 | 
			
		||||
  when: run_once_web_app_chess is not defined
 | 
			
		||||
							
								
								
									
										8
									
								
								roles/web-app-chess/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								roles/web-app-chess/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
---
 | 
			
		||||
- block:
 | 
			
		||||
  - name: "load docker, db and proxy for {{ application_id }}"
 | 
			
		||||
    include_role:
 | 
			
		||||
      name: sys-stk-full-stateful
 | 
			
		||||
 | 
			
		||||
  - include_tasks: utils/run_once.yml
 | 
			
		||||
  when: run_once_web_app_chess is not defined
 | 
			
		||||
							
								
								
									
										47
									
								
								roles/web-app-chess/templates/Dockerfile.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								roles/web-app-chess/templates/Dockerfile.j2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
# Multi-stage build for castling.club
 | 
			
		||||
# Stage 1: build
 | 
			
		||||
FROM node:{{ CHESS_VERSION }} AS build
 | 
			
		||||
 | 
			
		||||
ARG CHESS_REPO_URL={{ CHESS_REPO_URL }}
 | 
			
		||||
ARG CHESS_REPO_REF={{ CHESS_REPO_REF }}
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install -y --no-install-recommends \
 | 
			
		||||
    git ca-certificates openssl dumb-init python3 build-essential \
 | 
			
		||||
 && rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
RUN git clone --depth 1 --branch "${CHESS_REPO_REF}" "${CHESS_REPO_URL}" ./
 | 
			
		||||
 | 
			
		||||
# Yarn is preinstalled in Node images via corepack; enable it.
 | 
			
		||||
RUN corepack enable
 | 
			
		||||
 | 
			
		||||
# Install deps and build TS
 | 
			
		||||
RUN yarn install --frozen-lockfile && yarn build
 | 
			
		||||
 | 
			
		||||
# Stage 2: runtime
 | 
			
		||||
FROM node:{{ CHESS_VERSION }}
 | 
			
		||||
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
ENV PORT={{ container_port }}
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
 | 
			
		||||
# Minimal runtime packages + dumb-init
 | 
			
		||||
RUN apt-get update && apt-get install -y --no-install-recommends \
 | 
			
		||||
    openssl dumb-init postgresql-client \
 | 
			
		||||
 && rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
# Copy built app
 | 
			
		||||
COPY --from=build /src /app
 | 
			
		||||
 | 
			
		||||
# Create data dir for signing keys & cache
 | 
			
		||||
RUN mkdir -p /app/data && chown -R node:node /app
 | 
			
		||||
VOLUME ["/app/data"]
 | 
			
		||||
 | 
			
		||||
# Entrypoint script
 | 
			
		||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
 | 
			
		||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
 | 
			
		||||
 | 
			
		||||
USER node
 | 
			
		||||
EXPOSE {{ container_port }}
 | 
			
		||||
ENTRYPOINT ["dumb-init", "--"]
 | 
			
		||||
CMD ["docker-entrypoint.sh"]
 | 
			
		||||
							
								
								
									
										29
									
								
								roles/web-app-chess/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								roles/web-app-chess/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
{% include 'roles/docker-compose/templates/base.yml.j2' %}
 | 
			
		||||
  application:
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      dockerfile: Dockerfile
 | 
			
		||||
      args:
 | 
			
		||||
        CHESS_REPO_URL: "{{ CHESS_REPO_URL }}"
 | 
			
		||||
        CHESS_REPO_REF: "{{ CHESS_REPO_REF }}"
 | 
			
		||||
    image: "castling_custom"
 | 
			
		||||
    container_name: "{{ CHESS_CONTAINER }}"
 | 
			
		||||
    hostname: "{{ CHESS_HOSTNAME }}"
 | 
			
		||||
    environment:
 | 
			
		||||
      - NODE_ENV=production
 | 
			
		||||
    ports:
 | 
			
		||||
      - "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
 | 
			
		||||
    volumes:
 | 
			
		||||
      - 'data:/app/data'
 | 
			
		||||
    env_file:
 | 
			
		||||
      - .env
 | 
			
		||||
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
 | 
			
		||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
 | 
			
		||||
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
 | 
			
		||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
 | 
			
		||||
 | 
			
		||||
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
 | 
			
		||||
  data:
 | 
			
		||||
    name: {{ CHESS_DATA_VOLUME }}
 | 
			
		||||
 | 
			
		||||
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
 | 
			
		||||
							
								
								
									
										27
									
								
								roles/web-app-chess/templates/docker-entrypoint.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								roles/web-app-chess/templates/docker-entrypoint.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
set -euo pipefail
 | 
			
		||||
 | 
			
		||||
APP_KEY_FILE="${APP_KEY_FILE:-/app/data/{{ CHESS_KEY_FILENAME }}}"
 | 
			
		||||
APP_KEY_PUB="${APP_KEY_FILE}.pub"
 | 
			
		||||
 | 
			
		||||
# 1) Generate signing key pair if missing
 | 
			
		||||
if [[ ! -f "${APP_KEY_FILE}" || ! -f "${APP_KEY_PUB}" ]]; then
 | 
			
		||||
  echo "[chess] generating RSA signing key pair at ${APP_KEY_FILE}"
 | 
			
		||||
  /app/tools/gen-signing-key.sh "${APP_KEY_FILE}"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# 2) Wait for PostgreSQL if env is provided
 | 
			
		||||
if [[ -n "${PGHOST:-}" ]]; then
 | 
			
		||||
  echo "[chess] waiting for PostgreSQL at ${PGHOST}:${PGPORT:-5432}..."
 | 
			
		||||
  until pg_isready -h "${PGHOST}" -p "${PGPORT:-5432}" -U "${PGUSER:-postgres}" >/dev/null 2>&1; do
 | 
			
		||||
    sleep 1
 | 
			
		||||
  done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# 3) Run migrations (idempotent)
 | 
			
		||||
echo "[chess] running migrations"
 | 
			
		||||
yarn migrate up
 | 
			
		||||
 | 
			
		||||
# 4) Start app
 | 
			
		||||
echo "[chess] starting server on port ${PORT:-5080}"
 | 
			
		||||
exec yarn start
 | 
			
		||||
							
								
								
									
										16
									
								
								roles/web-app-chess/templates/env.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								roles/web-app-chess/templates/env.j2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
# App basics
 | 
			
		||||
APP_SCHEME="{{ 'https' if WEB_PROTOCOL == 'https' else 'http' }}"
 | 
			
		||||
APP_DOMAIN="{{ CHESS_HOSTNAME }}"
 | 
			
		||||
APP_ADMIN_URL="{{ CHESS_ADMIN_URL }}"
 | 
			
		||||
APP_ADMIN_EMAIL="{{ CHESS_ADMIN_EMAIL }}"
 | 
			
		||||
APP_KEY_FILE="/app/data/{{ CHESS_KEY_FILENAME }}"
 | 
			
		||||
APP_HMAC_SECRET="{{ CHESS_HMAC_SECRET }}"
 | 
			
		||||
NODE_ENV="production"
 | 
			
		||||
PORT="{{ container_port }}"
 | 
			
		||||
 | 
			
		||||
# PostgreSQL (libpq envs)
 | 
			
		||||
PGHOST="{{ database_host }}"
 | 
			
		||||
PGPORT="{{ database_port }}"
 | 
			
		||||
PGDATABASE="{{ database_name }}"
 | 
			
		||||
PGUSER="{{ database_username }}"
 | 
			
		||||
PGPASSWORD="{{ database_password }}"
 | 
			
		||||
@@ -1 +1,25 @@
 | 
			
		||||
application_id: web-app-chess
 | 
			
		||||
# General
 | 
			
		||||
application_id:                 "web-app-chess"
 | 
			
		||||
database_type:                  "postgres"
 | 
			
		||||
container_port:                 5080
 | 
			
		||||
container_hostname:             "{{ domains | get_domain(application_id) }}"
 | 
			
		||||
 | 
			
		||||
# App URLs & meta
 | 
			
		||||
#CHESS_URL:                      "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
 | 
			
		||||
CHESS_HOSTNAME:                 "{{ container_hostname }}"
 | 
			
		||||
CHESS_ADMIN_URL:                ""
 | 
			
		||||
CHESS_ADMIN_EMAIL:              ""
 | 
			
		||||
 | 
			
		||||
# Docker image
 | 
			
		||||
#CHESS_IMAGE:                    "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
 | 
			
		||||
CHESS_VERSION:                  "{{ applications | get_app_conf(application_id, 'docker.services.application.version') }}"
 | 
			
		||||
CHESS_CONTAINER:                "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
 | 
			
		||||
CHESS_DATA_VOLUME:              "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
 | 
			
		||||
 | 
			
		||||
# Build source
 | 
			
		||||
CHESS_REPO_URL:                 "{{ applications | get_app_conf(application_id, 'source.repo') }}"
 | 
			
		||||
CHESS_REPO_REF:                 "{{ applications | get_app_conf(application_id, 'source.ref') }}"
 | 
			
		||||
 | 
			
		||||
# Security
 | 
			
		||||
CHESS_HMAC_SECRET:              "{{ lookup('password', '/dev/null length=63 chars=ascii_letters,digits') }}"
 | 
			
		||||
CHESS_KEY_FILENAME:             "signing-key"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user