Includes docker-compose, setup script, nginx reverse proxy docs, and GAME_ENV configuration notes for self-hosted deployments.
268 lines
7.5 KiB
Markdown
268 lines
7.5 KiB
Markdown
# OpenFrontIO — Self-Hosted Docker Setup
|
||
|
||
Portables, reproduzierbares Docker-Setup für [OpenFrontIO](https://github.com/openfrontio/OpenFrontIO), einen browserbasierten Echtzeit-Strategietitel mit Territorien, Bündnissen und bis zu 41 gleichzeitigen Worker-Prozessen.
|
||
|
||
---
|
||
|
||
## Voraussetzungen
|
||
|
||
- Docker >= 24
|
||
- Docker Compose >= 2.20
|
||
- Git
|
||
- 2 GB freier RAM (empfohlen: 4 GB)
|
||
- ~2 GB freier Speicher für das Image
|
||
|
||
---
|
||
|
||
## Schnellstart
|
||
|
||
```bash
|
||
# 1. Repository klonen & vorbereiten
|
||
./setup.sh
|
||
|
||
# 2. (optional) Konfiguration anpassen
|
||
nano .env
|
||
|
||
# 3. Image bauen
|
||
docker compose build
|
||
|
||
# 4. Container starten
|
||
docker compose up -d
|
||
```
|
||
|
||
Das Spiel ist danach unter **http://localhost** erreichbar (Standard-Port 80).
|
||
|
||
---
|
||
|
||
## Verzeichnisstruktur
|
||
|
||
```
|
||
openfront/
|
||
├── setup.sh # Einmaliger Setup-Assistent
|
||
├── docker-compose.yml # Compose-Konfiguration
|
||
├── startup-local.sh # Container-Entrypoint (Cloudflare optional)
|
||
├── supervisord-local.conf # Supervisor-Konfiguration ohne Cloudflared
|
||
├── .env.example # Vorlage für Umgebungsvariablen
|
||
├── .env # Deine Konfiguration (wird von setup.sh erstellt)
|
||
└── OpenFrontIO/ # Geklontes Upstream-Repository (wird von setup.sh erstellt)
|
||
```
|
||
|
||
---
|
||
|
||
## Konfiguration
|
||
|
||
`setup.sh` erstellt automatisch eine `.env`-Datei aus `.env.example`. Alle verfügbaren Optionen:
|
||
|
||
| Variable | Standard | Beschreibung |
|
||
|---|---|---|
|
||
| `HOST_PORT` | `80` | Externer Port auf dem Host |
|
||
| `GIT_COMMIT` | automatisch | Git-Commit-Hash, der ins Image eingebettet wird |
|
||
| `GAME_ENV` | leer | Spielumgebung: `dev`, `staging` oder `prod` (siehe unten) |
|
||
| `CF_API_TOKEN` | leer | Cloudflare API-Token (optional, siehe unten) |
|
||
| `CF_ACCOUNT_ID` | leer | Cloudflare Account-ID (optional) |
|
||
| `SUBDOMAIN` | leer | Subdomain-Präfix für den Tunnel (optional) |
|
||
| `DOMAIN` | leer | Root-Domain bei Cloudflare (optional) |
|
||
|
||
### Anderen Port verwenden
|
||
|
||
```bash
|
||
# .env
|
||
HOST_PORT=8080
|
||
```
|
||
|
||
---
|
||
|
||
## Nginx Reverse Proxy mit HTTPS
|
||
|
||
Um den Server öffentlich unter einer eigenen Domain zu betreiben:
|
||
|
||
**1. Nginx-Config erstellen** (`/etc/nginx/conf.d/openfront.example.com`):
|
||
|
||
```nginx
|
||
map $http_upgrade $connection_upgrade {
|
||
default upgrade;
|
||
'' close;
|
||
}
|
||
|
||
server {
|
||
listen 80;
|
||
listen [::]:80;
|
||
server_name openfront.example.com;
|
||
|
||
location ^~ /.well-known/acme-challenge {
|
||
default_type text/plain;
|
||
root /var/www/letsencrypt;
|
||
}
|
||
|
||
location / {
|
||
return 301 https://$host$request_uri;
|
||
}
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl;
|
||
listen [::]:443 ssl;
|
||
server_name openfront.example.com;
|
||
|
||
ssl_certificate /etc/letsencrypt/live/openfront.example.com/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/openfront.example.com/privkey.pem;
|
||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||
|
||
location / {
|
||
proxy_pass http://127.0.0.1:8989; # HOST_PORT aus .env
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection $connection_upgrade;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_read_timeout 3600s;
|
||
proxy_send_timeout 3600s;
|
||
}
|
||
}
|
||
```
|
||
|
||
**2. TLS-Zertifikat holen** (DNS-Challenge empfohlen, da HTTP-Challenge durch vorgelagerte Auth-Proxies blockiert werden kann):
|
||
|
||
```bash
|
||
# Mit Cloudflare DNS:
|
||
sudo certbot certonly --dns-cloudflare \
|
||
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
|
||
-d openfront.example.com
|
||
|
||
# Oder manuell:
|
||
sudo certbot certonly --manual --preferred-challenges dns -d openfront.example.com
|
||
```
|
||
|
||
**3. `GAME_ENV` korrekt setzen** – Pflicht, damit `/api/env` antwortet und das Frontend korrekt initialisiert wird:
|
||
|
||
```bash
|
||
# .env
|
||
GAME_ENV=dev
|
||
```
|
||
|
||
> **Wichtig:** `GAME_ENV` muss gesetzt sein, sonst gibt `/api/env` HTTP 500 zurück und Features wie der „Link kopieren"-Button funktionieren nicht.
|
||
>
|
||
> `GAME_ENV=prod` und `GAME_ENV=staging` verwenden hardcodierte Cloudflare-Turnstile-Keys für `openfront.io` bzw. `openfront.dev` – diese Keys sind domain-gebunden und schlagen auf anderen Domains mit Fehler **110200** fehl. `GAME_ENV=dev` verwendet Cloudflares offizielle Test-Keys, die immer durchgehen.
|
||
|
||
**4. Container mit neuer Konfiguration neu erstellen:**
|
||
|
||
```bash
|
||
docker compose up -d --force-recreate
|
||
```
|
||
|
||
> `docker compose restart` reicht nicht – Änderungen an `.env` werden erst nach `up -d` (oder `--force-recreate`) übernommen.
|
||
|
||
---
|
||
|
||
## Cloudflare Tunnel (optional)
|
||
|
||
Ohne Cloudflare-Konfiguration läuft der Server ausschließlich lokal auf `HOST_PORT`. Für einen öffentlich erreichbaren Server über Cloudflare Tunnel:
|
||
|
||
1. Erstelle einen API-Token im [Cloudflare Dashboard](https://dash.cloudflare.com/profile/api-tokens) mit den Berechtigungen **Tunnel:Edit** und **DNS:Edit**.
|
||
2. Trage die Werte in `.env` ein:
|
||
|
||
```bash
|
||
CF_API_TOKEN=dein_token
|
||
CF_ACCOUNT_ID=deine_account_id
|
||
SUBDOMAIN=myserver # → tunnel-myserver.example.com
|
||
DOMAIN=example.com
|
||
```
|
||
|
||
3. Beim nächsten Start erstellt der Container automatisch den Tunnel und den passenden DNS-CNAME-Eintrag.
|
||
|
||
---
|
||
|
||
## Nützliche Befehle
|
||
|
||
```bash
|
||
# Logs in Echtzeit verfolgen
|
||
docker compose logs -f
|
||
|
||
# Nur Node-Server-Logs
|
||
docker compose logs -f openfront | grep "\[node\]"
|
||
|
||
# Container-Status prüfen
|
||
docker compose ps
|
||
|
||
# Container neustarten
|
||
docker compose restart
|
||
|
||
# Stoppen
|
||
docker compose down
|
||
|
||
# Stoppen und Image entfernen
|
||
docker compose down --rmi local
|
||
|
||
# Neu bauen nach Upstream-Updates
|
||
git -C OpenFrontIO pull
|
||
docker compose build --no-cache
|
||
docker compose up -d
|
||
```
|
||
|
||
---
|
||
|
||
## Architektur
|
||
|
||
Das Image enthält drei Prozesse, verwaltet von [Supervisor](http://supervisord.org/):
|
||
|
||
```
|
||
Container (Port 80)
|
||
└── Nginx (Reverse Proxy + Cache)
|
||
├── / → Node.js Master (Port 3000)
|
||
├── /api/* → Node.js Master (Port 3000)
|
||
├── /lobbies → Node.js Master (Port 3000, WebSocket)
|
||
└── /w0 … /w40 → Node.js Worker 0–40 (Ports 3001–3041)
|
||
```
|
||
|
||
Nginx übernimmt Caching, WebSocket-Upgrades und das Routing zu den Worker-Prozessen. Alle internen Ports (3000–3041) sind **nicht** nach außen exponiert.
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Build schlägt wegen `proprietary`-Verzeichnis fehl
|
||
|
||
Das `proprietary`-Submodul ist ein privates Repository der Entwickler. `setup.sh` erstellt automatisch einen leeren Placeholder, falls es nicht erreichbar ist. Der Build und das Spiel funktionieren auch ohne dieses Verzeichnis.
|
||
|
||
```bash
|
||
mkdir -p OpenFrontIO/proprietary
|
||
docker compose build
|
||
```
|
||
|
||
### Port 80 bereits belegt
|
||
|
||
```bash
|
||
# .env anpassen:
|
||
HOST_PORT=8080
|
||
docker compose up -d
|
||
```
|
||
|
||
### Container startet, Spiel ist nicht erreichbar
|
||
|
||
```bash
|
||
# Healthcheck-Status prüfen
|
||
docker inspect openfront-openfront-1 | grep -A5 Health
|
||
|
||
# Direkt im Container nachsehen
|
||
docker compose exec openfront supervisorctl status
|
||
```
|
||
|
||
### Upstream-Updates einspielen
|
||
|
||
```bash
|
||
git -C OpenFrontIO pull
|
||
docker compose build
|
||
docker compose up -d
|
||
```
|
||
|
||
---
|
||
|
||
## Lizenz
|
||
|
||
Der Quellcode von OpenFrontIO steht unter der [AGPL-3.0](https://github.com/openfrontio/OpenFrontIO/blob/main/LICENSE). Assets stehen unter [CC BY-SA 4.0](https://github.com/openfrontio/OpenFrontIO/blob/main/LICENSE-ASSETS). Copyright-Hinweise müssen in der Oberfläche sichtbar bleiben.
|
||
|
||
Dieses Docker-Setup ist ein inoffizielles Convenience-Wrapper ohne eigene Lizenzansprüche.
|