# CS2 Mapveto als Container betreiben CS2 Mapveto läuft als **ein** Container: Webseite, Backend, Datenbank (SQLite) und ein Docker-Client. Er steht auf demselben Docker-Host wie die CS2-Server und startet pro Match über `/var/run/docker.sock` einen eigenen CS2-Container. Der Host kann jeder Linux-Rechner mit Docker sein. ``` Docker-Host (beliebig, Linux, Adresse z. B. 192.168.178.111) ├── cs2-mapveto ← diese Anwendung, Port 3000 ├── cs2mv- ← CS2-Server pro Match (startet/entfernt CS2 Mapveto) ├── Volume cs2-mapveto-gamefiles CS2-Spieldateien (~73 GB) └── Volume cs2-mapveto-data Datenbank der Anwendung ``` > **Nur eine Instanz pro Docker-Host.** Läuft CS2 Mapveto zusätzlich anderswo mit demselben Host, streiten > sich beide um Ports und Containernamen. Die andere Instanz vorher beenden. --- ## Was du brauchst | | | |---|---| | Docker + Compose | `docker compose version` muss funktionieren | | Speicher | ~80 GB frei für Spieldateien, Images und Updates | | CPU / RAM | pro gleichzeitigem Match etwa 1–2 Kerne und 2–3 GB RAM | | Netz | Ports TCP/UDP 27100–27139 (Spiel, RCON) und UDP 27101… (CSTV) sowie TCP 3000 im LAN freigeben | | Dateien | das Image `cs2-mapveto` (siehe Schritt 1) und die CS2-Spieldateien (Schritt 2) | --- ## Schritt 1: Image auf den neuen Host bringen Du hast zwei Wege. ### Weg A: Image-Datei kopieren (ohne Build, schnell) Auf dem Rechner, auf dem das Image gebaut wurde, liegt die Datei `dist/cs2-mapveto-image.tar` (294 MB). Sie auf den neuen Host kopieren und laden: ```bash scp cs2-mapveto-image.tar USER@NEUERHOST:/tmp/ ssh USER@NEUERHOST "docker load -i /tmp/cs2-mapveto-image.tar && rm /tmp/cs2-mapveto-image.tar" ``` Prüfen mit `docker image ls cs2-mapveto`. ### Weg B: aus dem Repository bauen Auf dem neuen Host ist Git nötig. Das Repository liegt auf dem Gitea (`http://192.168.178.45:3002/marcel/Cs2-Mapveto.git`): ```bash git clone http://192.168.178.45:3002/marcel/Cs2-Mapveto.git cd Cs2-Mapveto docker build -t cs2-mapveto:latest . ``` Beim Bauen laufen alle Tests mit. Schlägt einer fehl, bricht der Build ab. --- ## Schritt 2: CS2-Spieldateien auf den neuen Host bringen Das Volume `cs2-mapveto-gamefiles` muss vor dem ersten Match vorhanden und befüllt sein. Sonst lädt jeder Match-Start die ~60 GB neu. Zwei Wege: **a) Vom bisherigen Host kopieren** (im LAN, kein Internet nötig, dauert je nach Netz Stunden): ```bash ssh ALTERHOST "docker run --rm -v cs2-mapveto-gamefiles:/from alpine tar -C /from -cf - ." \ | ssh NEUERHOST "docker volume create cs2-mapveto-gamefiles >/dev/null && docker run --rm -i -v cs2-mapveto-gamefiles:/to alpine tar -C /to -xf -" ``` **b) Neu laden** (braucht Internet, ~60 GB). Der Container lädt die Dateien und stoppt danach von selbst: ```bash docker volume create cs2-mapveto-gamefiles docker run -d --name cs2-updater -e STEAMAPPVALIDATE=0 -e CS2_RCONPW=updater1 -v cs2-mapveto-gamefiles:/home/steam/cs2-dedicated/ joedwards32/cs2:latest docker logs -f cs2-updater # warten auf "Success! App '730' fully installed" docker rm -f cs2-updater ``` Danach liegen unter `docker system df -v` rund 73 GB im Volume. Das CS2-Image selbst (`joedwards32/cs2:latest`, ~3,7 GB) holt Docker beim ersten Match automatisch aus dem Docker Hub. Ohne Internet muss es vorher ebenfalls geladen werden (`docker save`/`docker load` wie bei Schritt 1). --- ## Schritt 3: Konfiguration Im Ordner `deploy/` die Vorlage kopieren und anpassen: ```bash cp deploy/.env.example deploy/.env ``` Das Wichtigste: | Variable | Bedeutung | |---|---| | `HOST_IP` | **Pflicht.** IP des neuen Hosts im LAN. Spieler verbinden sich dorthin, Einladungslinks zeigen darauf | | `WEB_PORT` | Port der Webseite (Standard 3000) | | `SERVER_ADAPTER` | `docker` für echte Server, `demo` nur zum Ausprobieren ohne CS2 | | `CS2_GSLT` | leer = LAN-Modus (`sv_lan 1`), kein Token nötig | | `CS2_PORT_RANGE_START` / `_END` | Ports für Match-Server, zwei pro Match | | `CREATE_MATCH_PASSWORD` | Passwort zum Anlegen von Matches (empfohlen) | | `STREAM_KEY` | Schlüssel für `/stream?key=…` (optional) | Passwörter nur aus Buchstaben und Ziffern wählen. --- ## Schritt 4: Starten ```bash docker compose --env-file deploy/.env -f deploy/compose.yml up -d ``` Prüfen: ```bash docker compose --env-file deploy/.env -f deploy/compose.yml ps # Status "healthy" nach ~20 s curl http://HOST_IP:3000/api/config # JSON mit "adapter": "docker" ``` Danach ist die Webseite unter `http://HOST_IP:3000` erreichbar, die Stream-Übersicht unter `/stream`. Stoppen und neu starten: ```bash docker compose --env-file deploy/.env -f deploy/compose.yml down docker compose --env-file deploy/.env -f deploy/compose.yml up -d ``` Die Datenbank (Volume `cs2-mapveto-data`) bleibt dabei erhalten. ### Mit Portainer statt Kommandozeile Portainer → Stacks → **Add stack** → Web editor: den Inhalt von `deploy/compose.yml` einfügen. Die Variablen aus `deploy/.env` als *Environment variables* eintragen (mindestens `HOST_IP`). Danach **Deploy the stack**. --- ## Aktualisieren 1. Neues Image holen (Weg A oder B aus Schritt 1). 2. `docker compose … up -d` erneut ausführen. Compose ersetzt den Container, die Datenbank bleibt. --- ## Sicherheit Der Container hat über `/var/run/docker.sock` volle Kontrolle über Docker auf dem Host. Das ist nötig, um Match-Container zu starten, entspricht aber Root-Rechten auf dem Host. Deshalb: - Port 3000 nur im LAN anbieten, nicht ins Internet weiterleiten. - `CREATE_MATCH_PASSWORD` setzen, wenn nicht jeder im LAN Matches anlegen soll. - `deploy/.env` enthält Passwörter. Nicht ins Repository einchecken (ist in `.gitignore`). --- ## Fehlersuche | Symptom | Ursache / Lösung | |---|---| | `HOST_IP in deploy/.env eintragen` beim Start | `deploy/.env` fehlt oder `HOST_IP` ist leer | | „Server wird angefordert“ bleibt stehen | Log des Containers prüfen: `docker logs cs2-mapveto` | | `permission denied … docker.sock` im Log | Rootless-Docker oder anderer Socket-Pfad. Dann den Pfad im `volumes:`-Eintrag anpassen | | Match-Server startet, Spieler finden ihn nicht | Ports 27100–27139 im Host-Netz freigeben; `HOST_IP` muss die LAN-Adresse des Hosts sein | | Keine Live-Ergebnisse | `HOST_IP` falsch oder Port 3000 vom Match-Server aus nicht erreichbar | | Ein Match-Start dauert sehr lange | Spieldateien fehlen im Volume und werden neu geladen (Schritt 2) |