1. Ziel der Einrichtung
Am Ende soll dein Sync Server auf einem Linux-Server laufen, über Subdomains erreichbar sein und per HTTPS abgesichert werden.
Das Programm selbst läuft als ein Binary. Es kann aber mehrere Instanzen gleichzeitig bedienen. Welche Instanz für eine Anfrage benutzt wird, entscheidet der Hostname der Anfrage.
Was sind Multiinstanzen?
Multiinstanzen bedeuten: Ein Sync Server-Prozess bedient mehrere logisch getrennte Bereiche gleichzeitig. Jeder Bereich hat eine eigene Subdomain und eigene Datenordner.
Beispiel: alpha-sync.example.com und beta-sync.example.com
laufen im selben Dienst, aber mit getrenntem Content unter
/syncserver/instances/<host>/....
Wofür sind sie?
- Trennung von Serien, Ligen oder Umgebungen (z. B. Live, Test, Event)
- Saubere Datenstruktur je Host ohne Vermischung
Wann braucht man sie?
- Eine Instanz reicht, wenn du nur eine Subdomain betreibst (darin können eine oder viele Serien liegen)
- Mehrere Instanzen brauchst du, wenn Inhalte/Benutzer je Subdomain getrennt bleiben sollen
Sync Server läuft lokal auf 127.0.0.1:5055,
Nginx nimmt HTTPS an Port 443 an und leitet an den lokalen Sync Server weiter.
2. Voraussetzungen
- Ein Linux-Server oder VPS
- Root-Zugriff oder
sudo - Eine Domain, zum Beispiel
example.com - Ein DNS-Provider, bei dem du A-Records setzen kannst
- Das Sync Server-Binary
- Die Konfigurationsdatei
config.yml - Nginx und Certbot für den Produktivbetrieb
logs unter jeder Instanz enthält aktuell nur
Client-State-Dateien wie clients.json.
Dort werden keine klassischen Server-Logs geschrieben.
3. DNS und Subdomains
Damit die Domain erreichbar ist, müssen die Subdomains auf die öffentliche IP deines Servers zeigen.
Subdomains und IP live anpassen
Trage hier deine Subdomains und eine Beispiel-IP ein. Alle Beispiele in der Anleitung werden ohne Reload sofort aktualisiert und im Browser gespeichert.
Speicherung: localStorage im aktuellen Browser.
Einzelinstanz (eine Subdomain)
- Setze einen A-Record, zum Beispiel
alpha-sync.example.com->203.0.113.10. - In
config.ymlmuss derselbe Host ininstances[].hostsstehen.
Mehrere Instanzen (mehrere Subdomains)
Typisches Beispiel:
- Setze pro Instanz/Subdomain einen eigenen A-Record.
alpha-sync.example.com- A auf203.0.113.10beta-sync.example.com- A auf203.0.113.10cup-sync.example.net- A auf203.0.113.10
4. Basispfade anlegen
Lege dir auf dem Server einen festen Arbeitsordner an. Bei dir ist das zum Beispiel
/syncserver.
sudo mkdir -p /syncserver/bin
Zuerst brauchst du nur den Binary-Pfad und die Position der Konfigurationsdatei.
Die Instanz-Unterordner unter /syncserver/instances legt der Sync Server
später selbst an (pro Instanz aus dem ersten Hostnamen abgeleitet).
/syncserver
|-- bin
| |-- syncserver
|-- config.yml
Wichtig: Die Datei muss genau unter /syncserver/config.yml liegen.
5. Binary und config.yml hochladen
Die Datei syncserver ist die eigentliche Anwendung, also das ausführbare
Programm des Sync Servers. Du musst sie mit einem FTP- oder SFTP-Programm deiner Wahl in
das Verzeichnis /syncserver/bin hochladen.
Wichtig ist nur, dass die Datei am Ende genau hier liegt:
/syncserver/bin/syncserver
Die Konfigurationsdatei muss hier liegen:
/syncserver/config.yml
Erst wenn Binary und config.yml an diesen Pfaden liegen, gehst du zur
Konfigurationsanpassung im nächsten Abschnitt.
Beim Start erzeugt der Server die Instanzverzeichnisse unter /syncserver/instances
automatisch aus den Hosts in der config.yml.
Beispiel:
/syncserver/instances/alpha-sync.example.com/sync_root
/syncserver/instances/alpha-sync.example.com/sync_json
/syncserver/instances/alpha-sync.example.com/logs
6. config.yml anpassen
Die Konfiguration entscheidet über Serverport, Instanzen und die Speicherorte. Der wichtigste Teil ist das Instanzmodell.
Wichtige Felder
server.host- die IP, an der das Binary lauschtserver.port- der Port, zum Beispiel5055routing.default_instance- optionaler Fallback auf eine abgeleitete Instanz-IDinstances- Liste aller Instanzen mithostsinstances[].id- wird automatisch ausinstances[].hosts[0]abgeleitet (Teil vor dem ersten Punkt)instances[].hosts- Hostnamen/Subdomains dieser Instanz
Grundprinzip
Wenn eine Anfrage mit Hostname
alpha-sync.example.com reinkommt, wird die passende Instanz benutzt.
Der Code macht das über das HTTP-Host-Header-Mapping. Deshalb müssen DNS,
Nginx und config.yml zueinander passen.
Die Verzeichnisse pro Instanz werden automatisch aus dem Binary-Ort gebildet:
<base>/instances/<erster-host>/sync_root,
<base>/instances/<erster-host>/sync_json und
<base>/instances/<erster-host>/logs.
Wenn das Binary unter
/syncserver/bin/syncserver liegt, ist die Base
/syncserver. Daraus entstehen automatisch die Instanzpfade unter
/syncserver/instances/<erster-host>/....
config.yml setzt du pro Instanz nur
hosts. Die id leitet der Sync Server immer aus dem ersten
Hostteil vor dem ersten Punkt ab. Einen paths-Block gibt es dort nicht mehr.
Wie die Config grob aufgebaut ist
7. Einzelne Instanz einrichten
Wenn du nur eine Domain betreibst, reicht eine Instanz. Das ist der einfachste Einstieg.
sync_root möglich.
- Lege
hostsfür deine Instanz fest. - Setze
server.hostauf127.0.0.1, wenn Nginx davor sitzt. - Setze
server.portauf einen freien internen Port, zum Beispiel5055. - Trage in
instancesgenau eine Instanz mit deiner Subdomain ein. - Optional: Setze
routing.default_instanceauf die abgeleitete Instanz-ID (z. B.alpha-sync) oder lasse es auf""für keinen Fallback.
/syncserver
|-- bin
| |-- syncserver
|-- config.yml
|-- instances
|-- alpha-sync.example.com
|-- sync_root
|-- sync_json
|-- logs
server:
host: "127.0.0.1"
port: 5055
routing:
default_instance: ""
instances:
- hosts:
- alpha-sync.example.com
8. Mehrere Instanzen einrichten
Mehrere Instanzen sind sinnvoll, wenn du Bereiche/Umgebungen je Subdomain getrennt halten willst. Eine Instanz kann trotzdem mehrere Serien enthalten. Jede Instanz bekommt:
- eigene Hosts/Subdomains
- eigene Serienordner (automatisch erzeugt)
- eigene JSON-Ausgabe (automatisch erzeugt)
- eigene Client-State-Dateien im
logs-Ordner
So funktioniert die Zuordnung
Der Server schaut auf den Hostnamen der Anfrage.
Wenn die Anfrage auf beta-sync.example.com kommt, wird die Instanz mit
diesem Host verwendet.
Wenn kein Host passt, wird routing.default_instance verwendet. Ist der Wert leer (""), wird die Anfrage abgewiesen.
hosts.
Die Instanzpfade werden automatisch aus dem ersten Hostnamen berechnet.
Beispiel mit mehreren Instanzen
/syncserver
|-- bin
| |-- syncserver
|-- config.yml
|-- instances
|-- alpha-sync.example.com
| |-- sync_root
| |-- sync_json
| |-- logs
|-- beta-sync.example.com
| |-- sync_root
| |-- sync_json
| |-- logs
|-- cup-sync.example.net
|-- sync_root
|-- sync_json
|-- logs
routing:
default_instance: ""
instances:
- hosts:
- alpha-sync.example.com
- hosts:
- beta-sync.example.com
- hosts:
- cup-sync.example.net
id). Jede Subdomain sollte nur bei einer Instanz vorkommen.
9. Nginx als Reverse Proxy
In der Praxis läuft der Sync Server meist nicht direkt auf Port 443. Nginx nimmt die HTTPS-Verbindung an und leitet an den lokalen Sync Server weiter.
Warum Nginx?
- HTTPS-Termination
- saubere Subdomain-Trennung
- einfacheres SSL-Handling
- der Sync Server kann intern auf
127.0.0.1bleiben
Einzelinstanz: Nginx-Vorlage pro Instanz
Das folgende Muster ist die vereinheitlichte Vorlage für eine einzelne Instanz.
Nimm dafür pro Instanz eine eigene Nginx-Datei, zum Beispiel
/etc/nginx/sites-available/alpha-sync.example.com.conf,
und passe nur die Domain im server_name und im
Host-Header an. Diese Vorlage läuft zuerst über Port 80.
HTTPS und der SSL-Zertifikatsteil werden im nächsten Schritt durch Certbot ergänzt.
upstream sync_backend {
server 127.0.0.1:5055;
keepalive 128;
}
server {
listen 80;
server_name alpha-sync.example.com;
proxy_http_version 1.1;
proxy_set_header Connection "";
access_log /var/log/nginx/alpha-sync.access.log;
error_log /var/log/nginx/alpha-sync.error.log;
gzip on;
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
application/octet-stream;
gzip_min_length 512;
gzip_comp_level 5;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";
client_max_body_size 1024m;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
location = /health {
proxy_pass http://sync_backend;
proxy_set_header Host alpha-sync.example.com;
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_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_buffering off;
add_header Cache-Control "no-store" always;
}
location = /healthz {
proxy_pass http://sync_backend/health;
proxy_set_header Host alpha-sync.example.com;
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_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_buffering off;
add_header Cache-Control "no-store" always;
}
location = /list_projects {
proxy_pass http://sync_backend;
proxy_set_header Host alpha-sync.example.com;
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_set_header Accept-Encoding "";
proxy_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
add_header Cache-Control "no-store, must-revalidate, max-age=0" always;
}
location ^~ /file_list/ {
proxy_pass http://sync_backend;
proxy_set_header Host alpha-sync.example.com;
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_set_header Accept-Encoding "";
proxy_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
add_header Cache-Control "no-store, must-revalidate, max-age=0" always;
}
location ^~ /download_file/ {
proxy_pass http://sync_backend;
proxy_set_header Host alpha-sync.example.com;
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_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_request_buffering off;
proxy_buffering off;
proxy_max_temp_file_size 0;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
location / {
proxy_pass http://sync_backend;
proxy_set_header Host alpha-sync.example.com;
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_set_header Accept-Encoding "";
proxy_cache off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_buffering on;
proxy_buffers 32 64k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 1024m;
}
}
Mehrere Instanzen: so passt du die Nginx-Konfiguration an
- lege für jede Instanz eine eigene Datei in
/etc/nginx/sites-availablean - kopiere den Inhalt der Vorlage vollständig in diese neue Datei
- ändere
server_name alpha-sync.example.comauf die neue Subdomain - ändere jeden
proxy_set_header Host alpha-sync.example.comauf dieselbe neue Subdomain - passe optional die Logdateien an, damit jede Instanz eigene Nginx-Logs bekommt
- nutze pro Instanz möglichst eine eigene Konfigurationsdatei, damit Änderungen sauber getrennt bleiben
Beispiel für eine zweite Instanz
Wenn du zusätzlich beta-sync.example.com betreiben möchtest, legst du
eine zweite Datei an:
/etc/nginx/sites-available/beta-sync.example.com.conf
In diese Datei kopierst du exakt dieselbe Nginx-Konfiguration wie oben. Danach ersetzt du nur die Domain:
alpha-sync.example.comwird zubeta-sync.example.com<id>.access.logund<id>.error.logals Schema verwendenalpha-sync.access.logwird optional zubeta-sync.access.logalpha-sync.error.logwird optional zubeta-sync.error.log
server.host im Sync Server auf
127.0.0.1. Dann ist der Dienst nicht direkt aus dem Internet erreichbar.
Der Port 5055 bleibt für mehrere Instanzen gleich, wenn alle Instanzen
über denselben Sync Server-Prozess laufen. Die Zuordnung passiert dann über den
Hostnamen aus der Anfrage.
10. SSL mit Certbot
Die Subdomains sollten per HTTPS erreichbar sein. Dafür nutzt man in der Regel Certbot mit Nginx.
Certbot installieren
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx
Zertifikat anfordern je Szenario
Variante A: Eine Instanz mit einer Subdomain
Wenn du nur eine Instanz hast, fordere das Zertifikat genau für diese eine Domain an.
sudo certbot --nginx -d alpha-sync.example.com
Certbot erweitert danach die Nginx-Datei dieser Subdomain um HTTPS und Redirect.
Variante B: Mehrere Instanzen mit mehreren Subdomains
Bei mehreren Instanzen hast du zwei saubere Optionen:
- ein gemeinsames Zertifikat mit mehreren
-d-Einträgen - pro Subdomain ein eigenes Zertifikat
Beispiel für ein gemeinsames Zertifikat:
sudo certbot --nginx \
-d alpha-sync.example.com \
-d beta-sync.example.com \
-d cup-sync.example.net
Beispiel pro Subdomain (nacheinander ausführen):
sudo certbot --nginx -d alpha-sync.example.com
sudo certbot --nginx -d beta-sync.example.com
sudo certbot --nginx -d cup-sync.example.net
Was dabei wichtig ist
- Die DNS-Records müssen schon auf den Server zeigen.
- Nginx muss auf Port 80 erreichbar sein.
- Die Domain muss auflösbar sein, sonst kann Certbot nicht prüfen.
- Nach erfolgreicher Ausstellung übernimmt Certbot die HTTPS-Konfiguration in Nginx.
11. Als Dienst starten
Damit der Server nach einem Neustart automatisch startet, nimmst du am besten einen systemd-Service.
Datei öffnen
sudo nano /etc/systemd/system/syncserver.service
Danach den folgenden Service-Block komplett in den Editor kopieren und speichern.
Service-Block
[Unit]
Description=Sync Server
After=network.target
[Service]
WorkingDirectory=/syncserver
ExecStart=/syncserver/bin/syncserver --config /syncserver
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Danach ausführen
sudo systemctl daemon-reload
sudo systemctl enable --now syncserver
sudo systemctl status syncserver
Einzelinstanz vs. mehrere Instanzen
- Einzelinstanz: ein Service reicht.
- Mehrere Instanzen: ebenfalls ein Service; die Trennung passiert über
config.ymlund Hostnamen.
Wenn du mehrere Instanzen im selben Binary betreibst, reicht ein Service.
Alle Instanzen werden aus derselben config.yml geladen.
12. Test und Kontrolle
Wenn alles eingerichtet ist, prüfe die Kette von innen nach außen:
- läuft der Sync Server lokal?
- antwortet Nginx auf Port 80/443?
- zeigen die DNS-Records auf den Server?
- ist das SSL-Zertifikat gültig?
- wird der richtige Host auf die richtige Instanz geroutet?
curl sind optional. Die Kernprüfung bleibt der Browser-Test.
Optionale curl-Tests: Einzelinstanz
curl -I http://127.0.0.1:5055
curl -I https://alpha-sync.example.com
Optionale curl-Tests: Mehrere Instanzen
curl -I http://127.0.0.1:5055
curl -I https://alpha-sync.example.com
curl -I https://beta-sync.example.com
curl -I https://cup-sync.example.net
Häufige Fehler
- 404 oder falsche Daten: Hostname in Nginx oder
config.ymlpasst nicht. - Certbot scheitert: DNS zeigt noch nicht auf den Server oder Port 80 ist blockiert.
- Seite nicht erreichbar: Nginx läuft nicht oder Firewall blockiert 80/443.
- Sync Server startet nicht: Rechte auf den Ordnern fehlen oder der Port ist belegt.
13. Content bereitstellen
Hier legst du fest, wo deine eigentlichen Dateien liegen. Der Sync Server liest Content
immer aus sync_root der jeweiligen Instanz.
Zielpfad je Instanz
- Einzelinstanz:
/syncserver/instances/alpha-sync.example.com/sync_root - Mehrere Instanzen: pro Host ein eigener Pfad
/syncserver/instances/<host>/sync_root - Lade den Content nur nach
sync_root, nicht nachsync_jsonoderlogs - Wenn du per Samba arbeitest: der Share muss auf genau diesen
sync_root-Pfad zeigen
Pflichtstruktur im Serienordner
Jeder Serienordner unter sync_root muss einen
content-Unterordner haben. Nur Dateien in diesem Baum werden indexiert.
/syncserver
|-- instances
|-- alpha-sync.example.com
|-- sync_root
|-- Formula1
| |-- content
| |-- cars
| |-- tracks
|-- TouringCup_pw123_
|-- content
|-- cars
<name>_<passwort>_Beispiel:
TouringCup_pw123_ wird öffentlich als
TouringCup angezeigt und benötigt das Passwort pw123.
Wichtige Regeln
- Lege pro Instanz nur die Serien ab, die zu diesem Host gehören
- Vermeide doppelte Seriennamen (auch nur in anderer Groß-/Kleinschreibung)
- Dateien außerhalb von
contentwerden nicht in die Serien-JSON aufgenommen sync_jsonwird vom Server erzeugt; diese Dateien nicht manuell bearbeiten- Prüfe Dateirechte nach Upload: der Sync Server-User muss lesen können (typisch
syncsrv:syncsrv)
Einzelinstanz: schneller Check nach Upload (curl optional)
ls -la /syncserver/instances/alpha-sync.example.com/sync_root
curl -sS -H "Host: alpha-sync.example.com" http://127.0.0.1:5055/list_projects
curl -sS -H "Host: alpha-sync.example.com" http://127.0.0.1:5055/file_list/Formula1.json | head
Mehrere Instanzen: pro Host prüfen (curl optional)
curl -sS -H "Host: alpha-sync.example.com" http://127.0.0.1:5055/list_projects
curl -sS -H "Host: beta-sync.example.com" http://127.0.0.1:5055/list_projects
curl -sS -H "Host: cup-sync.example.net" http://127.0.0.1:5055/list_projects
Empfohlener Gesamtablauf
Ablauf für eine Instanz
- DNS-A-Record für diese eine Subdomain setzen.
- Basispfade unter
/syncserveranlegen (mindestens/syncserver/bin). syncserverundconfig.ymlauf den Server hochladen.config.ymlmit genau einer Instanz (hosts) anpassen.- Nginx-Site für diese eine Subdomain konfigurieren.
- Certbot für diese eine Subdomain ausführen.
- Sync Server als systemd-Dienst starten.
- Content nach
/syncserver/instances/<host>/sync_rootladen und Struktur prüfen. - Diese Subdomain im Browser testen (
curloptional).
Ablauf für mehrere Instanzen
- Für jede Subdomain einen DNS-A-Record setzen.
- Basispfade unter
/syncserveranlegen (mindestens/syncserver/bin). syncserverundconfig.ymlauf den Server hochladen.config.ymlmit mehreren Instanzen (hosts) anpassen.- Für jede Subdomain eine eigene Nginx-Site konfigurieren.
- Certbot mit mehreren
-doder je Subdomain einzeln ausführen. - Sync Server als einen systemd-Dienst starten (ein Prozess, mehrere Instanzen).
- Content je Instanz in den passenden
sync_root-Pfad laden und je Host prüfen. - Alle Subdomains im Browser testen (
curloptional).