Files
ToolCTRL-website/README.md
T
ToolCTRLandClaude Opus 4.7 bec5dc7363
Deploy / build-and-deploy (push) Successful in 33s
Produktion: ClamAV in den App-Container integriert
Dockerfile installiert clamav-daemon + clamav-freshclam und konfiguriert
clamd auf TCP 127.0.0.1:3310 mit DB-Verzeichnis auf der persistenten
Coolify-Volume (/app/data/clamav-db).

entrypoint.sh startet clamd und freshclam vor dem Node-Server, wartet
auf clamd-PING und exec't dann node als unprivilegierter Nutzer. tini
übernimmt PID 1 für Signal-Forwarding.

Folge: GameJam-Uploads werden in Produktion automatisch per ClamAV
geprüft, ohne dass Coolify manuell angepasst werden muss. Erster
Deploy lädt einmalig ~300 MB Virendefinitionen auf die Volume,
Folge-Starts in ~30 s. RAM-Bedarf des Containers ~1.5 GB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:40:19 +02:00

142 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ToolCTRL — Website
Mehrseitige Website im Visitenkarten-Stil: Landing Page mit Lead-Formular,
TechDay-2026-Seite, AI-GameJam-Seite mit Datei-Upload sowie Impressum und
Datenschutz. Monochrom (weiß / schwarz), an die ToolCTRL Brand Identity
angelehnt. Der Server läuft ohne npm-Pakete (nur Node-Standardbibliothek).
## Starten
```bash
node server.js
```
Der Server sucht automatisch einen freien Port (zuerst `4317`) und gibt lokale
und Netzwerk-URL aus. Stoppen mit `Strg + C`.
Voraussetzung: Node.js (getestet mit v26).
## Aufbau
```
public/ statische Website
index.html Landing Page + Kontaktformular
techday.html TechDay Bruchsal 2026
gamejam.html AI GameJam (eigenes Styling, Spiel-Upload)
impressum.html Impressum
datenschutz.html Datenschutzerklärung
styles.css Designsystem
script.js Formular-Logik & Mobile-Navigation
assets/ Logos, Emblem, Favicon, Icons, Schriften, Mockups
server.js abhängigkeitsfreier Node-HTTP-Server + API
leads/ gesammelte Kontaktanfragen (wird automatisch angelegt)
gamejam/ GameJam-Einreichungen, Metadaten (wird automatisch angelegt)
```
`leads/`, `gamejam/` und hochgeladene Spiele sind per `.gitignore` vom Repo
ausgeschlossen.
## Leads
`POST /api/lead` (JSON, Pflichtfelder `name`, `email`, `nachricht`). Jede
Anfrage landet sofort lokal in `leads/leads.csv` **und** `leads.ndjson` — so
geht auf der Messe nichts verloren. Ein Honeypot-Feld fängt einfache Bots ab.
## GameJam-Upload & Virenscan (ClamAV)
`POST /api/gamejam/upload` nimmt eine `.html`-Datei entgegen (max. 5 MB).
**Jede hochgeladene Datei wird vor dem Speichern per ClamAV auf Viren
geprüft.** Befund → Ablehnung; ist der Scanner nicht erreichbar, wird der
Upload ebenfalls abgelehnt (fail-closed, kein ungeprüftes Speichern).
Der Server spricht den ClamAV-Daemon `clamd` direkt über sein Socket-Protokoll
an — keine zusätzliche Abhängigkeit. Beim Start meldet der Server
`Virenscan: aktiv` bzw. eine Warnung, falls `clamd` nicht erreichbar ist.
### Produktion (Coolify)
In der Produktion läuft ClamAV **im selben Container** wie der Node-Server.
Das `Dockerfile` installiert `clamav-daemon` und `clamav-freshclam`, das
`entrypoint.sh` startet beide Daemons vor Node:
- Virendefinitionen liegen auf der persistenten Volume unter
`/app/data/clamav-db` und überleben Restarts/Deploys.
- Erster Start auf einer leeren Volume lädt einmalig ~300 MB Definitionen
(~1–2 Min). Folge-Starts sind in ~30 s wieder oben.
- `freshclam --daemon` hält die Definitionen im Hintergrund aktuell.
- **Speicherbedarf:** ~1–1,5 GB RAM für die geladene DB.
Die Coolify-VM muss entsprechend dimensioniert sein.
Keine manuelle Coolify-Konfiguration nötig — push auf `main` baut das Image
mit ClamAV, beim nächsten Deploy ist der Scanner aktiv.
### ClamAV einrichten — macOS (lokale Entwicklung)
```bash
brew install clamav
cd "$(brew --prefix)/etc/clamav"
cp freshclam.conf.sample freshclam.conf
cp clamd.conf.sample clamd.conf
# In BEIDEN Dateien die Zeile "Example" entfernen oder auskommentieren.
# In clamd.conf zusätzlich diese zwei Zeilen aktivieren (Raute entfernen):
# TCPSocket 3310
# TCPAddr 127.0.0.1
freshclam # Virendefinitionen laden (einmalig)
clamd # Daemon starten
```
### ClamAV einrichten — Linux (Debian/Ubuntu)
```bash
sudo apt install clamav clamav-daemon
# In /etc/clamav/clamd.conf: TCPSocket 3310 und TCPAddr 127.0.0.1 setzen
sudo systemctl restart clamav-daemon
```
### Konfiguration
Host/Port und An/Aus stehen in `server.js` im Objekt `CLAMAV`. Mit
`enabled: false` läuft der Upload ohne Virenscan (nur für lokale Tests
ohne ClamAV gedacht).
Per Environment kann der Runtime-Betrieb konfiguriert werden:
```bash
PORT=3000
HOST=0.0.0.0
DATA_DIR=/app/data
CLAMAV_HOST=127.0.0.1
CLAMAV_PORT=3310
CLAMAV_ENABLED=true
APP_REVISION=<git-sha>
```
`/healthz` ist die leichte Liveness-Probe für Container und Coolify.
`/readyz` prüft zusätzlich Schreibzugriff auf die Datenverzeichnisse und,
falls aktiv, die Erreichbarkeit von ClamAV.
### Funktion testen
Eine Datei mit der EICAR-Testsignatur hochladen — `clamd` meldet dann
`Eicar-Test-Signature FOUND`, der Upload wird abgelehnt.
## Hinweis für die Messe
Für den QR-Code am Stand muss der Rechner im selben WLAN erreichbar sein.
Soll die Seite öffentlich laufen, hinter einen Reverse-Proxy mit HTTPS setzen
oder bei einem Hoster bereitstellen — `tool-ctrl.de`.
## Deployment
Deployment folgt dem Gitea-Infra-Standard aus `toolctrl-labs/infra`:
1. Push auf `main` triggert `.gitea/workflows/deploy.yml`.
2. Gitea Actions baut das Docker-Image und pusht es nach
`git.tool-ctrl.de/toolctrl-labs/toolctrl-website`.
3. Tags: kurzer Commit-SHA und `main`.
4. Coolify-App `toolctrl-website` (`ocwtt7rd2zijtlszgua005k9`) zieht
`:main` auf der Marketing-VM und startet neu.
Die Coolify-App läuft im Projekt `Marketing`, Environment `production`, Server
`marketing-vm`, Port `3000`, mit persistentem Storage auf `/app/data`.