Initial commit: self-hosted Docker setup for OpenFrontIO
Includes docker-compose, setup script, nginx reverse proxy docs, and GAME_ENV configuration notes for self-hosted deployments.
This commit is contained in:
35
.env.example
Normal file
35
.env.example
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# ============================================================
|
||||||
|
# OpenFrontIO — Docker Compose Environment Configuration
|
||||||
|
# Copy this file to .env and adjust values as needed.
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# Port to expose the game on the host machine (default: 80)
|
||||||
|
HOST_PORT=8989
|
||||||
|
|
||||||
|
# Git commit hash embedded in the build for version tracking.
|
||||||
|
# Automatically set by setup.sh. Can also be pinned to a specific commit.
|
||||||
|
GIT_COMMIT=unknown
|
||||||
|
|
||||||
|
# Game environment: dev | staging | prod
|
||||||
|
# Must be set, otherwise /api/env returns HTTP 500 and the frontend breaks.
|
||||||
|
# Use "dev" for self-hosted setups — prod/staging use domain-bound Cloudflare
|
||||||
|
# Turnstile keys (openfront.io / openfront.dev) that fail on other domains (error 110200).
|
||||||
|
GAME_ENV=dev
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Cloudflare Tunnel (optional)
|
||||||
|
# Leave all CF_* variables empty to run without a tunnel.
|
||||||
|
# The server will then be accessible only via HOST_PORT.
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# Cloudflare API token with Tunnel:Edit and DNS:Edit permissions
|
||||||
|
CF_API_TOKEN=
|
||||||
|
|
||||||
|
# Cloudflare Account ID (from the Cloudflare dashboard URL)
|
||||||
|
CF_ACCOUNT_ID=
|
||||||
|
|
||||||
|
# Subdomain prefix for the tunnel (e.g. "myserver" → tunnel-myserver.example.com)
|
||||||
|
SUBDOMAIN=
|
||||||
|
|
||||||
|
# Root domain managed by Cloudflare (e.g. "example.com")
|
||||||
|
DOMAIN=openfront.muc.datenh.eu
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Upstream-Repository – wird von setup.sh geklont
|
||||||
|
OpenFrontIO/
|
||||||
|
|
||||||
|
# Lokale Konfiguration mit Secrets
|
||||||
|
.env
|
||||||
267
README.md
Normal file
267
README.md
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
# 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.
|
||||||
23
docker-compose.yml
Normal file
23
docker-compose.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
services:
|
||||||
|
openfront:
|
||||||
|
build:
|
||||||
|
context: ./OpenFrontIO
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
GIT_COMMIT: ${GIT_COMMIT:-unknown}
|
||||||
|
entrypoint: ["/usr/local/bin/startup-local.sh"]
|
||||||
|
ports:
|
||||||
|
- "${HOST_PORT:-80}:80"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
# Override startup and supervisor config with our local versions
|
||||||
|
- ./startup-local.sh:/usr/local/bin/startup-local.sh:ro
|
||||||
|
- ./supervisord-local.conf:/etc/supervisor/conf.d/supervisord-local.conf:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-sf", "http://localhost/api/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 90s
|
||||||
54
setup.sh
Executable file
54
setup.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REPO_URL="https://github.com/openfrontio/OpenFrontIO.git"
|
||||||
|
REPO_DIR="./OpenFrontIO"
|
||||||
|
|
||||||
|
echo "=== OpenFrontIO Docker Setup ==="
|
||||||
|
|
||||||
|
# Clone repo if not already present
|
||||||
|
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||||
|
echo "[1/4] Cloning OpenFrontIO repository..."
|
||||||
|
git clone "$REPO_URL" "$REPO_DIR"
|
||||||
|
else
|
||||||
|
echo "[1/4] Repository already cloned. Pulling latest changes..."
|
||||||
|
git -C "$REPO_DIR" pull
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Initialize git submodules (proprietary assets etc.)
|
||||||
|
echo "[2/4] Initializing submodules..."
|
||||||
|
git -C "$REPO_DIR" submodule update --init --recursive 2>/dev/null || true
|
||||||
|
|
||||||
|
# The 'proprietary' directory may be a private submodule.
|
||||||
|
# If it doesn't exist after submodule init, create an empty one so Docker COPY doesn't fail.
|
||||||
|
if [ ! -d "$REPO_DIR/proprietary" ]; then
|
||||||
|
echo " Note: 'proprietary' submodule not available (private). Creating empty placeholder."
|
||||||
|
mkdir -p "$REPO_DIR/proprietary"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up .env from example if it doesn't exist yet
|
||||||
|
echo "[3/4] Setting up .env..."
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
cp .env.example .env
|
||||||
|
echo " .env created from .env.example — edit it before starting!"
|
||||||
|
else
|
||||||
|
echo " .env already exists, skipping."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Capture git commit hash for reproducible builds
|
||||||
|
GIT_COMMIT=$(git -C "$REPO_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||||||
|
# Update GIT_COMMIT in .env if placeholder
|
||||||
|
if grep -q "^GIT_COMMIT=unknown" .env 2>/dev/null; then
|
||||||
|
sed -i "s/^GIT_COMMIT=unknown/GIT_COMMIT=${GIT_COMMIT}/" .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[4/4] Setup complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Edit .env (at minimum set HOST_PORT if port 80 is taken)"
|
||||||
|
echo " 2. docker compose build"
|
||||||
|
echo " 3. docker compose up -d"
|
||||||
|
echo " 4. Open http://localhost (or your HOST_PORT)"
|
||||||
|
echo ""
|
||||||
|
echo " Optional: Set CF_API_TOKEN, CF_ACCOUNT_ID, SUBDOMAIN, DOMAIN in .env"
|
||||||
|
echo " for automatic Cloudflare Tunnel setup."
|
||||||
73
startup-local.sh
Executable file
73
startup-local.sh
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SUPERVISORD_CMD="/usr/bin/supervisord"
|
||||||
|
SUPERVISORD_CONF_FULL="/etc/supervisor/conf.d/supervisord.conf"
|
||||||
|
SUPERVISORD_CONF_LOCAL="/etc/supervisor/conf.d/supervisord-local.conf"
|
||||||
|
|
||||||
|
# Check if all required Cloudflare variables are set
|
||||||
|
if [ -n "$CF_API_TOKEN" ] && [ -n "$CF_ACCOUNT_ID" ] && [ -n "$SUBDOMAIN" ] && [ -n "$DOMAIN" ]; then
|
||||||
|
echo "Cloudflare variables detected — setting up tunnel..."
|
||||||
|
|
||||||
|
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||||
|
TUNNEL_NAME="${SUBDOMAIN}-tunnel-${TIMESTAMP}"
|
||||||
|
echo "Tunnel name: ${TUNNEL_NAME}"
|
||||||
|
|
||||||
|
TUNNEL_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/cfd_tunnel" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data "{\"name\":\"${TUNNEL_NAME}\"}")
|
||||||
|
|
||||||
|
TUNNEL_ID=$(echo "$TUNNEL_RESPONSE" | jq -r '.result.id')
|
||||||
|
TUNNEL_TOKEN=$(echo "$TUNNEL_RESPONSE" | jq -r '.result.token')
|
||||||
|
|
||||||
|
if [ -z "$TUNNEL_ID" ] || [ "$TUNNEL_ID" = "null" ]; then
|
||||||
|
echo "Error: Failed to create Cloudflare tunnel"
|
||||||
|
echo "$TUNNEL_RESPONSE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Tunnel ID: ${TUNNEL_ID}"
|
||||||
|
|
||||||
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/cfd_tunnel/${TUNNEL_ID}/configurations" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data "{\"config\":{\"ingress\":[{\"hostname\":\"tunnel-${SUBDOMAIN}.${DOMAIN}\",\"service\":\"http://localhost:80\"},{\"service\":\"http_status:404\"}]}}"
|
||||||
|
|
||||||
|
DNS_RECORDS=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=${DOMAIN}" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json")
|
||||||
|
ZONE_ID=$(echo "$DNS_RECORDS" | jq -r '.result[0].id')
|
||||||
|
|
||||||
|
if [ -z "$ZONE_ID" ] || [ "$ZONE_ID" = "null" ]; then
|
||||||
|
echo "Error: Could not find DNS zone for ${DOMAIN}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXISTING=$(curl -s "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=tunnel-${SUBDOMAIN}.${DOMAIN}" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json")
|
||||||
|
RECORD_ID=$(echo "$EXISTING" | jq -r '.result[0].id')
|
||||||
|
|
||||||
|
if [ -z "$RECORD_ID" ] || [ "$RECORD_ID" = "null" ]; then
|
||||||
|
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data "{\"type\":\"CNAME\",\"name\":\"tunnel-${SUBDOMAIN}.${DOMAIN}\",\"content\":\"${TUNNEL_ID}.cfargotunnel.com\",\"ttl\":1,\"proxied\":true}"
|
||||||
|
else
|
||||||
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
|
||||||
|
-H "Authorization: Bearer ${CF_API_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data "{\"type\":\"CNAME\",\"name\":\"tunnel-${SUBDOMAIN}.${DOMAIN}\",\"content\":\"${TUNNEL_ID}.cfargotunnel.com\",\"ttl\":1,\"proxied\":true}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Site will be available at: https://tunnel-${SUBDOMAIN}.${DOMAIN}"
|
||||||
|
export CLOUDFLARE_TUNNEL_TOKEN="${TUNNEL_TOKEN}"
|
||||||
|
|
||||||
|
# Use the full supervisor config (includes cloudflared)
|
||||||
|
exec "$SUPERVISORD_CMD" -c "$SUPERVISORD_CONF_FULL"
|
||||||
|
else
|
||||||
|
echo "No Cloudflare variables set — starting without tunnel (port 80 only)."
|
||||||
|
# Use local supervisor config (nginx + node only, no cloudflared)
|
||||||
|
exec "$SUPERVISORD_CMD" -c "$SUPERVISORD_CONF_LOCAL"
|
||||||
|
fi
|
||||||
25
supervisord-local.conf
Normal file
25
supervisord-local.conf
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
user=root
|
||||||
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
|
pidfile=/var/run/supervisord.pid
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=/usr/sbin/nginx -g "daemon off;"
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stdout_logfile=/dev/stdout
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/stderr
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
|
||||||
|
[program:node]
|
||||||
|
command=npm run start:server
|
||||||
|
directory=/usr/src/app
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
user=node
|
||||||
|
stdout_logfile=/dev/stdout
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/stderr
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
Reference in New Issue
Block a user