cactoz.su

Личный сайт-визитка на cactoz.su в Matrix-стилистике: резюме, проекты и браузерные игры. Три страницы статики + мультиплеерный сервер для ./tanks. Исходный замысел и игровой протокол — в TZ.md (⚠️ местами устарел).

Архитектура

                        ┌────────── homelab (cacto-homelab) ──────────┐
 push в main            │                                              │
 в Gitea ────────────►  │  gitea-actions runner (docker.sock хоста)    │
 git.cactoz.su          │     │ клонирует, синкает, собирает           │
                        │     ▼                                        │
                        │  /data/docker/compose/cactoz                 │
                        │  docker compose -f docker-compose.prod.yml   │
                        │     ├── nginx  (статика + прокси /ws)        │
                        │     └── gameserver (C++/uWebSockets, :9001)  │
                        │              │                               │
                        │              ▼ (external docker-сеть proxy)  │
                        │  Caddy-стек (TLS-терминация 80/443)          │
                        └──────────────────────────────────────────────┘
  • Деплой: push в main → workflow .gitea/workflows/deploy.yml → build + up -d + smoke-проверка по healthcheck'ам. Отката нет: если сборка/подъём падают, шлётся уведомление, старые контейнеры продолжают работать.
  • TLS терминирует отдельный Caddy-стек, сеть proxy создаётся там (external: true) — на этом хосте только подключаемся.
  • Gameserver изнутри доступен только по docker-сети internal; наружу смотрит только nginx (через Caddy).

Локальный запуск

docker compose up --build        # http://localhost, /ws на ws://localhost/ws

Сборка gameserver тянет зависимости через CMake FetchContent (uWebSockets, uSockets, nlohmann/json) — первый билд долгий, дальше кэшируется слоями Docker.

Структура

frontend/           чистый HTML/CSS/JS, без сборки
  vendor/fonts/     self-hosted JetBrains Mono (OFL), 4 сабсета × 4 насыщенности
  js/game/          клиент ./tanks: network (WS + ping 25с), lobby, battle
  js/blocks.js, js/invaders.js   одиночные мини-игры (canvas, без сервера)
gameserver/
  src/main.cpp      uWS::App, /ws, лимиты фреймов/таймауты
  src/Lobby.*       лобби: комнаты, broadcast, ping/pong, события в stdout
  src/Game.*        авторитетная симуляция (20 Гц), pvp и coop с AI
nginx/              статика + проксирование /ws (rate-limit на соединения)

Runbook

# на homelab:
cd /data/docker/compose/cactoz
docker compose -f docker-compose.prod.yml ps           # статус + healthcheck'и
docker logs -f cactoz-gameserver-... 2>&1 | less       # события лобби/игр
docker compose -f docker-compose.prod.yml up -d --build  # ручной перезапуск
  • Логи ротируются (max-size 10m × 3), лимиты ресурсов: nginx 128M/0.5cpu, gameserver 256M/1cpu.
  • Gameserver не умеет graceful shutdown — при рестарте активные матчи обрываются (комнаты сами поднимаются заново).
  • Статика без хешей в именах: js/css отдаются с no-cache, /assets/ — час.

Доступ и безопасность

  • SSH на homelab: ключи, вход только с доверенных сетей; sudo — по необходимости.
  • Gitea (git.cactoz.su) — источник истины для кода; секретов в репо нет.
  • За пределами compose на хосте живут Caddy-стек, Gitea и её runner — их конфиги не входят в этот репозиторий и бэкапятся отдельно.
S
Description
No description provided
Readme
652 KiB
Languages
JavaScript 44.5%
C++ 24.1%
HTML 15.8%
CSS 13.9%
Dockerfile 0.9%
Other 0.8%