2026-06-02 17:45:29 +05:00
new
2026-06-02 21:32:45 +05:00
2026-06-02 18:01:57 +05:00
2026-06-02 22:17:15 +05:00
2026-06-02 17:45:29 +05:00
new
2026-06-02 21:32:45 +05:00
2026-06-02 17:45:29 +05:00
2026-06-02 17:45:29 +05:00
2026-06-02 17:45:29 +05:00
2026-06-02 22:17:15 +05:00
new
2026-06-02 21:32:45 +05:00
2026-06-02 22:17:15 +05:00
2026-06-02 17:45:29 +05:00

Strike Arena

Next.js 15 standalone application for Strike Arena. The app runs on Node.js 22, stores data in SQLite through better-sqlite3, and is served by Nginx in Docker Compose.

Runtime Paths

  • SQLite database: /app/data/strike-arena.db
  • Uploaded files: /app/uploads
  • Game images in the repository: uploads/games

SQLite WAL and foreign keys are enabled on startup in src/lib/bd.ts.

Environment

Create .env from the example:

cp .env.local.example .env

Required variables:

ADMIN_HASHED_PASSWORD=
JWT_SECRET=
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=

Generate a production JWT_SECRET:

JWT_SECRET_NEW="$(openssl rand -base64 48 | tr -d '\n')"
sed -i "s#^JWT_SECRET=.*#JWT_SECRET=${JWT_SECRET_NEW}#" .env
grep '^JWT_SECRET=' .env

Do not deploy with JWT_SECRET=replace-with-generated-secret.

Local Development

npm ci
npm run dev

Open http://localhost:3000.

Production Docker

The production Compose file binds Nginx to 10.20.0.25:18083.

uploads is mounted as ./uploads:/app/uploads so repository images remain available and new admin uploads are persisted on the host. SQLite data is stored in the Docker volume sqlite_data.

Deploy on docker-runtime-2:

ssh -i /root/.ssh/docker2_vm_ed25519 crimson@10.20.0.25
sudo su

mkdir -p /opt/docker-apps/strike_arena
chown -R crimson:crimson /opt/docker-apps/strike_arena
cd /opt/docker-apps/strike_arena

git clone https://git.flamy.studio/sbb45/StikeArena_chrt.git .
cp .env.local.example .env

Set a real JWT_SECRET, fill Telegram variables if notifications are needed, then prepare uploads permissions:

mkdir -p uploads/games
chown -R 1001:1001 uploads

Check the port:

ss -lntup | grep ':18083' || true

Build and run:

docker compose config
docker compose build --no-cache
docker compose up -d
docker compose ps
docker compose logs -f --tail=120 app nginx

Runtime checks:

curl -I http://10.20.0.25:18083
curl -I http://10.20.0.25:18083/health
curl -I http://10.20.0.25:18083/api/faq
curl -I http://10.20.0.25:18083/api/games

SQLite checks:

docker compose exec app node - <<'NODE'
const Database = require('better-sqlite3');
const db = new Database('/app/data/strike-arena.db');
console.log(db.pragma('journal_mode', { simple: true }));
console.log(db.pragma('foreign_keys', { simple: true }));
db.close();
NODE

Expected output:

wal
1

Check persisted paths:

docker compose exec app ls -lah /app/data
docker compose exec app ls -lah /app/uploads/games | head

Caddy

Add this on edge-proxy after the app responds on 10.20.0.25:18083:

ssh -i /root/.ssh/edge_vm_ed25519 crimson@192.168.0.80

curl -I --connect-timeout 5 http://10.20.0.25:18083
curl -I --connect-timeout 5 http://10.20.0.25:18083/health
sudo grep -R "belixa.ru\|10.20.0.25:18083" -n /etc/caddy || true

sudo cp -a /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%F-%H%M%S)

Append the Caddy block:

# Strike Arena
http://www.belixa.ru, https://www.belixa.ru {
        redir https://belixa.ru{uri} 308
}

belixa.ru {
        encode zstd gzip

        reverse_proxy 10.20.0.25:18083 {
                header_up Host {host}
                header_up X-Real-IP {remote_host}
                header_up X-Forwarded-Host {host}
                header_up X-Forwarded-Proto https
                header_up X-Forwarded-Port 443
        }
}

Reload Caddy:

sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo systemctl status caddy --no-pager

Public checks:

curl -I https://belixa.ru
curl -I https://www.belixa.ru
curl -I http://belixa.ru
curl -I http://www.belixa.ru
S
Description
No description provided
Readme 7.1 MiB
Languages
TypeScript 98.1%
JavaScript 1%
CSS 0.6%
Dockerfile 0.3%