Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
23 KiB
VCH-Plattform — die Regeln dieser Umgebung
Diese Datei gehört VCH und wird bei jedem Abgleich überschrieben. Projektwissen gehört
in die CLAUDE.md daneben, nicht hierher.
Sie beschreibt, was VCH mit diesem Projekt macht — vor allem die Stellen, an denen ein Verstoß nicht als Fehler auffällt, sondern als falsches Ergebnis: ein Deploy, der grün meldet und nichts ausliefert, eine Datenbank, die niemand verbindet, ein Audit, das etwas prüft, das du gar nicht gepusht hast.
1. Zwei Maschinen, nicht eine
- Hier (DEV): ein Debian-LXC. Nutzer
vchuser, Heimat/home/vchuser, Projekte unter/home/vchuser/projects/<name>.vchuserhatsudoohne Passwort und ist in der Docker-Gruppe. Vorhanden: Node 20 (npm; pnpm und yarn sind NICHT installiert —corepack enableholt sie, wenn dein Projekt sie braucht), Python samt venv, Docker, tmux, git, code-server auf Port 8080, Claude Code alsclaude, OpenCode alsopencode; Git gegen Gitea vorkonfiguriert. Das Terminal läuft in tmux — ein Dev-Server im Vordergrund blockiert die Sitzung, starte ihn in einem eigenen tmux-Fenster oder mit&. - Dort (PROD): eine andere Maschine mit demselben Werkzeugsatz. VCH klont dein
Repository dorthin und startet es. Der Build läuft dort mit gelöschtem
NODE_ENV, damit devDependencies installiert werden; einNODE_ENV=productionaus.env.examplegilt erst zur Laufzeit.
Daraus folgt die wichtigste Regel überhaupt: VCH deployt und auditiert deinen gepushten Commit, nie dein Arbeitsverzeichnis. Nicht committete Änderungen existieren für Deploy, Audit und Veröffentlichung nicht — auch dann nicht, wenn hier alles läuft.
2. Wegweiser — welcher Weg in welcher Lage
Bevor du baust: such deine Lage, nimm den Weg, kenn die Folgen. Die Abschnitte dahinter erklären das Wie.
Eine Datenbank, Schlüssel in .env.example. Der Mensch stellt sie im Projektarbeitsplatz
bereit, VCH trägt die Werte in genau deine Schlüssel ein (Abschnitt 8). Folgen: Datenbank und
Benutzer heißen app, sofern beim Anlegen nichts anderes gewählt wurde; Migrationen laufen in
deinem build oder start, VCH führt keine aus; DB-Zeilen im Env-Editor werden gestrichen,
solange die Datenbank läuft; erst der nächste Deploy trägt die Werte ein.
Zwei Datenbanken — oder Redis, Mongo, Elasticsearch. Compose mit eigenen Diensten
(Abschnitt 13). Folgen: ein Compose mit eigener Datenbank deployt nicht blau-grün, sondern
in place — kurze Auszeit beim Umschalten, das Audit läuft als Torprüfung vor dem Start; VCH
sichert diese Datenbank nicht (kein Backup über die Karte); jeder Datenbankdienst braucht ein
Named Volume; den DB-Port nicht als festen Host-Port veröffentlichen. An der verwalteten
Datenbank landen zwei deklarierte Verbindungen (DATABASE_URL und ANALYTICS_DATABASE_URL)
auf derselben — deshalb Compose.
Nur Dateien oder SQLite. Keine Datenbank; alles, was bleiben soll, nach VCH_DATA_DIR
(Abschnitt 9). Folgen: HISTORY_DB=/pfad.sqlite ist bewusst keine Verbindung und wird nicht
überschrieben; ein Pfad relativ zum Release ist beim nächsten Deploy weg.
Eine Datenbank zum Entwickeln, hier auf DEV. VCH stellt hier keine bereit. Starte selbst
eine — Docker ist da, vchuser ist in der Docker-Gruppe:
docker run -d --name dev-db -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=dev postgres:16.
Lege eine lokale .env an, deklariere die Schlüssel in .env.example. Folgen: die Bindung an
127.0.0.1 ist Pflicht — ohne Adresse vor dem Port lauscht die Datenbank für jeden im LAN; die
.env gehört nicht ins Repository; für PROD trägt VCH die verwaltete Datenbank ein.
Ein zweiter Prozess neben der App (Worker, Cron, Queue). Compose (Abschnitt 13). Folgen:
systemd startet genau einen Befehl, den aus start; im Compose läuft jeder Dienst mit,
Dienste hinter profiles: bleiben aus.
Reines Frontend ohne Server. Statisch ausliefern, irgendetwas muss auf $PORT lauschen
(Abschnitt 6.2, „Statische Seite"). Folgen: relative Pfade und Vite base: './' (Abschnitt 3),
sonst bricht die Vorschau hinter dem Pfad-Proxy.
Code in einem Unterordner. cd in build und start (Abschnitt 6.2, „Monorepo"), die
.env.example in den Ordner, der sie liest. Folgen: jede Beispieldatei bestimmt ihr eigenes
.env-Ziel (Abschnitt 7).
Die Vorschau zeigt nichts, der Port wird aber erkannt. Dein Server lauscht auf 127.0.0.1.
Lausche auf 0.0.0.0: vite --host, next dev -H 0.0.0.0, HOST=0.0.0.0. Folgen: die
Porterkennung sieht auch lokale Lauscher, der Proxy erreicht sie nicht — ein erkannter Port
beweist keine erreichbare Vorschau.
Ein Geheimnis wird gebraucht (API-Schlüssel, Token). In .env.example leer deklarieren
(API_KEY=); den Wert hinterlegt der Mensch im Env-Editor (Abschnitt 7). Folgen: leer ohne
Vorgabe blockiert den Deploy, bis der Wert da ist — gewollt; die Prüfung secrets findet
eingecheckte Werte (Abschnitt 11).
Der Deploy schlägt fehl. Du siehst weder das Deploy-Log noch Logs der PROD-Maschine — lass
dir den Fehlertext aus dem Projektarbeitsplatz geben. Dann prüfen: lauscht die App auf PORT,
antwortet der health-Pfad innerhalb von 30 Sekunden, liest sie ihre Werte aus der Umgebung?
Folgen: im Deploy-Log stehen die letzten 50 Logzeilen der App — logge nach stdout, nicht in
Dateien.
Dem Projekt ist eine Integration zugeordnet. Die Zugangsdaten liegen in
.vch-integrations.env im Projektstamm: <NAME>_API_URL, <NAME>_USER, <NAME>_PASSWORD,
<NAME>_TOKEN. Folgen: die Datei liegt nur hier auf DEV, im Klartext, wird nicht deployt
und ist nicht ignoriert — trag sie in .gitignore ein und committe sie nie; für PROD dieselben
Schlüssel in .env.example deklarieren, die Werte in den Env-Editor.
3. Vorschau im Browser läuft über einen Proxy
Deine Entwicklungs-Server sind nicht direkt erreichbar. VCH erkennt lauschende Ports und stellt zwei Wege bereit:
- Subdomain (bevorzugt):
https://lxc<VMID>-<PORT>.<domain>/— deine App liegt auf der Wurzel, alles verhält sich normal. - Pfad-Proxy (Rückfallweg):
https://<host>/proxy/<instanz>/p/<port>/— deine App liegt hinter einem Pfadpräfix.
Damit beides funktioniert: relative Pfade verwenden.
css/style.css✅ — nicht/css/style.css❌fetch('api/daten')✅ — nichtfetch('/api/daten')❌- Wenn absolute Pfade unvermeidbar sind:
<base href="./">in den<head>.
Rahmenwerke: Vite base: './' · Create React App "homepage": "." in der
package.json · Next.js Vorgabe belassen (Subdomain) oder basePath setzen (Pfad-Proxy)
· Express express.static genügt, solange das HTML relativ verweist.
4. Dateien, die VCH im Projektstamm liest
| Datei | Pflicht | Wozu |
|---|---|---|
README.md |
ja | Audit-Prüfung readme — blockiert die Veröffentlichung |
.vch-description |
ja | Audit-Prüfung description; der Text steht später im Showcase |
.env.example |
wenn die App Umgebungsvariablen liest | die Deklaration aller Variablen (Abschnitt 7) |
.vch/deploy.yaml |
wenn die Autoerkennung nicht reicht | wie gebaut und gestartet wird (Abschnitt 6) |
CLAUDE.md |
— | dein Projektwissen; VCH fasst sie nicht mehr an |
README.md muss beschreiben, was das Projekt tut, wie man es installiert, wie man es
startet und worauf es aufbaut. Die unveränderte Vorlage besteht die Prüfung nicht.
.vch-description ist nicht technisch: was das Projekt tut, welches Problem es löst,
für wen. Kein Technologie-Stapel, keine Installationsanleitung — die stehen im README.
Halte beide aktuell, wenn sich Zweck oder Aufbau ändern.
.vch-description legt VCH beim Anlegen als Platzhalter an, der die Prüfung nicht besteht —
dass die Datei existiert, heißt nicht, dass sie fertig ist.
VCH-eigen, nicht anfassen: .vch/PLATFORM.md, ~/.vch_env, ~/.config/vch/ und
/etc/profile.d/vch-opencode.sh. Wer „die Shell-Umgebung aufräumt", kappt sich den AI-Server.
5. Der Port gehört VCH
VCH weist jedem Projekt auf der PROD-Maschine einen festen Port zu (Bereich 13000–13999)
und hält ihn über alle Deploys hinweg stabil. Du wählst ihn nicht und stimmst dich mit
niemandem ab.
Deine App MUSS auf PORT aus der Umgebung lauschen:
- Node/Express:
app.listen(process.env.PORT || 3000) - Next.js:
next startbeachtetPORTvon selbst - Python:
gunicorn app:app -b 0.0.0.0:$PORTbzw.uvicorn main:app --port $PORT - Go/andere: den Wert aus der Umgebung lesen, nicht hartkodieren
Ein fest verdrahteter Port läuft hier und scheitert dort am Healthcheck. PORT und
VCH_DATA_DIR sind VCH-eigene Schlüssel: setzt du sie selbst — in .env.example, im
Env-Editor oder im Compose — wird dein Wert verworfen.
6. .vch/deploy.yaml — die vollständige Referenz
Ohne diese Datei versucht VCH, das Projekt selbst zu erkennen (Abschnitt 6.3). Reicht das nicht, bricht der Deploy ab und legt dir eine fertige Vorlage vor, die du nur noch committen musst.
6.1 Alle Felder
| Feld | Typ | Vorgabe | Bedeutung |
|---|---|---|---|
runtime |
auto | systemd | docker |
auto |
Wie gestartet wird. auto: Dockerfile oder Compose vorhanden → docker, sonst systemd. |
build |
Zeichenkette | — | Shell-Befehl im Release-Verzeichnis. Nur systemd — bei docker baut das Dockerfile. |
start |
Zeichenkette | — | Startbefehl des Dienstes. Nur systemd. Muss $PORT binden. |
port |
Ganzzahl 1–65535 | 3000 |
Nur docker: der Port, auf dem deine App im Container lauscht. VCH bildet den zugewiesenen Host-Port darauf ab. |
health |
Pfad | / |
Pfad, der 2xx oder 3xx liefert, sobald die App bereit ist. |
env |
Liste von Zeichenketten | [] |
Zusätzliche Variablennamen, die VCH ausliefern soll. Wird mit den Schlüsseln aus .env.example vereinigt. |
compose |
Pfad | — | Welche Compose-Datei gilt, wenn mehrere gefunden werden. |
Unbekannte Felder und Tippfehler in runtime brechen den Deploy mit einer benannten
Fehlermeldung ab — sie werden nicht still ignoriert.
6.2 Beispiele
Node mit eigenem Build (systemd):
runtime: systemd
build: "npm ci && npm run build"
start: "npm start"
health: /
Python (systemd) — beachte $PORT im Startbefehl:
runtime: systemd
build: "python3 -m venv .venv && .venv/bin/pip install -r requirements.txt"
start: ".venv/bin/gunicorn app:app -b 0.0.0.0:$PORT"
health: /
Statische Seite (systemd) — irgendetwas muss lauschen:
runtime: systemd
build: "npm ci && npm run build"
start: "python3 -m http.server $PORT --directory dist"
Monorepo, Code in einem Unterordner:
runtime: systemd
build: "cd backend && npm ci && npm run build"
start: "cd backend && npm start"
Dockerfile:
runtime: docker
port: 3000 # der Port INNERHALB des Containers
health: /
Mehrere Compose-Dateien im Repository:
runtime: docker
compose: docker/compose.yaml
6.3 Was ohne die Datei passiert
In dieser Reihenfolge:
- Ein echtes
Dockerfilegewinnt →runtime: dockermit dem Image. - Eine Compose-Datei, die
${VCH_PORT}veröffentlicht → Compose-Deploy. - Eine Compose-Datei, die nur Infrastruktur startet (Postgres, Redis, … und keinen App-Dienst), wird als Entwicklungs-Beiwerk erkannt und nicht deployt — VCH sucht weiter nach der Sprache.
- Eine Compose-Datei mit App-Dienst, die
${VCH_PORT}nicht veröffentlicht → Abbruch mit Vorlage (Abschnitt 13). package.jsonim Stamm:build-Skript → Build,start-Skript bzw.main→ Start. Paketmanager wird am Lockfile erkannt (pnpm/yarn/npm).- Alles andere — Python, PHP/Laravel, Go, reines Frontend ohne
start, Code nur in Unterordnern — endet mit einer passenden Vorlage zum Committen.
7. Umgebungsvariablen: .env.example ist die Deklaration
VCH liest keine Umgebungsvariablen aus deinem Code. Was in einer Beispieldatei steht, existiert; alles andere nicht.
- Erkannte Dateinamen:
.env.example,.env.sample,.env.templatesowie dieselben ohne führenden Punkt (env.example, …). Der erste Fund je Schlüssel gewinnt. - Gesucht wird im ganzen Repository (ohne
node_modules,.git,dist,build,.next,out,vendor,coverage,.turbo), Stammdateien zuerst, höchstens 25 Dateien. - Jede gefundene Beispieldatei bestimmt ein Ziel:
backend/.env.example→ VCH schreibt die Produktionswerte nachbackend/.env. Für Monorepos ist das der Weg, mehrere.envzu bekommen.
Was den Deploy blockiert: ein Schlüssel, der keinen Wert nennt (KEY=) und für den
noch kein Produktionswert hinterlegt ist. Nicht blockierend sind:
API_URL=https://beispiel.test # Vorgabewert vorhanden
OPTIONAL_TOKEN="" # ausdrücklich leer erlaubt
FEATURE_FLAG= # optional
Der Marker muss direkt hinter dem # stehen (# optional); Fließtext, in dem das Wort
vorkommt, zählt nicht. Die Vorgabewerte sind Hinweise für den Menschen — in Produktion
wird nichts davon verwendet.
Im Zweifel:
grep -RhoE "process\.env\.[A-Z_]+" src/ | sort -u
und jeden Treffer in die .env.example schreiben.
Bei Docker: nur Variablen mit dem Präfix NEXT_PUBLIC_, VITE_ oder PUBLIC_ gehen als
--build-arg in den Build (sie sind ohnehin im Auslieferungsstand sichtbar) — dafür brauchst
du passende ARG-Zeilen im Dockerfile. Alle übrigen Werte kommen erst zur Laufzeit über
--env-file und landen nie im Image.
8. Datenbank
Deklariert deine App Verbindungsvariablen, bietet VCH eine verwaltete Datenbank an und trägt die Werte automatisch in genau die Schlüssel ein, die du deklariert hast. Du musst deine Variablennamen also nicht ändern — VCH erkennt sie.
Was du bekommst: genau eine verwaltete Datenbank je Projekt — Postgres 16 oder MySQL 8
als eigener Container auf der PROD-Maschine, Host 127.0.0.1, Port aus 15000–15999, nicht
aus dem LAN erreichbar. Datenbank und Benutzer heißen app; der Mensch kann beim Anlegen unter
„Erweitert" eigene Werte wählen (Kleinbuchstaben, Ziffern, Unterstrich, Buchstabe vorne;
reservierte Namen und das Präfix pg_ sind gesperrt) — nur beim Anlegen,
danach nicht mehr. Das Passwort wird erzeugt oder gewählt und beim Deploy in deine Schlüssel
eingetragen; deklarierst du keine erkennbaren Schlüssel, zeigt die Karte im Projektarbeitsplatz
die Verbindung samt Passwort zum Kopieren. Auf DEV gibt es diese Datenbank nicht (Wegweiser).
Migrationen macht deine App im build oder start. Backup: der Abzug liegt im Projekt-Backup,
vor dem Löschen zieht VCH einen Pflicht-Abzug. Solange die Datenbank läuft, werden DB-Zeilen im
Env-Editor gestrichen — dein eigener Wert hält nicht. Deklarierst du zwei Verbindungen,
landen beide auf dieser einen Datenbank: dann Compose (Wegweiser).
Erkannt wird (Groß-/Kleinschreibung egal):
- Verbindungszeichenketten:
DATABASE_URL,DB_URL, jeder Name auf_DSN - Einzelteile mit Familienwort (
DB,DATABASE,POSTGRES,MYSQL) plus Rolle:..._HOST,..._PORT,..._USER/..._USERNAME,..._PASSWORD/..._PASS,..._NAME/..._DATABASE/..._DB - Die üblichen nackten Namen:
PGHOST,PGPORT,PGUSER,PGPASSWORD,PGDATABASE,MYSQL_HOST,MYSQL_USER,MYSQL_PASSWORD,MYSQL_DATABASE,POSTGRES_DB
Bewusst nicht erkannt (und deshalb nie überschrieben):
- alles mit
ROOTim Namen (POSTGRES_ROOT_PASSWORD,MYSQL_ROOT_PASSWORD) — das sind die Zugangsdaten des Datenbankservers, nicht die deiner App SENTRY_DSNund verwandte Fehlermelder (GLITCHTIP,BUGSNAG,ROLLBAR,AIRBRAKE,RAYGUN,APPSIGNAL) — ein DSN ist dort keine DatenbankHISTORY_DB=/data/verlauf.sqliteund Ähnliches: ein..._DBohne Datenbank-Familienwort im übrigen Namen gilt nicht als Verbindung
Die Engine (Postgres oder MySQL) leitet VCH aus deinen Schlüsselnamen und dem Schema in
DATABASE_URL ab; ist das mehrdeutig, entscheidest du im Projektarbeitsplatz.
Bringt dein Compose seine eigene Datenbank mit, startet VCH sie mit und bietet keine
zweite an. Achte dann selbst auf ein dauerhaftes Volume — ein Datenbankdienst ohne Volume
verliert seine Daten beim nächsten Neubau, und VCH warnt nur. Erkannt wird der Dienst am
Image-Namen: postgres, postgresql, pgvector, postgis, timescaledb, mysql,
mariadb, percona/percona-server. Ein anderes Image (eigener Build, fremder Name) gilt
nicht als Datenbank — dann bietet VCH eine verwaltete an, und der Deploy läuft blau-grün mit
einem zweiten Stapel.
Eine Compose-Datei, die nur eine Datenbank startet, ist Entwicklungs-Beiwerk: sie läuft in Produktion nicht mit. Nimm dort die verwaltete Datenbank.
9. Dauerhafte Daten: VCH_DATA_DIR
Jedes Release liegt in einem eigenen Verzeichnis und verschwindet wieder. Was überleben soll —
SQLite-Datei, Uploads, erzeugte Dateien — gehört in das Verzeichnis aus VCH_DATA_DIR.
const datenVerzeichnis = process.env.VCH_DATA_DIR || './data';
VCH setzt die Variable bei allen Betriebsarten (bei Docker als Einhängepunkt /data). Lies
sie zur Laufzeit, schreibe den Pfad nirgends fest und trage sie nicht in .env-Dateien ein.
Ein Verzeichnis relativ zum Release (./data) ist beim nächsten Deploy weg.
Der Prüfling während des Audits (Abschnitt 10) bekommt diesen Speicher nicht — er läuft gegen einen leeren. Das ist Absicht: zwei Prozesse dürfen nicht gleichzeitig auf dieselbe SQLite-Datei schreiben.
10. Wie ein Deploy abläuft
Klonen → Bauen → Healthcheck (Prüfling) → Audit → Umschalten → Live
- Klonen. VCH klont den Deploy-Branch auf die PROD-Maschine — genau den gepushten Stand.
- Torprüfung. Fehlt ein blockierender Wert aus
.env.example(Abschnitt 7), endet es hier, bevor irgendetwas läuft. - Bauen nach
.vch/deploy.yamlbzw. Autoerkennung. - Healthcheck. Der neue Stand startet als Prüfling auf einem freien Port aus dem
Bereich
14000–14999, neben der weiterhin laufenden alten Fassung. VCH ruft dort deinenhealth-Pfad auf: rund 30 Sekunden lang, alle 1,5 s ein Versuch, Erfolg beim ersten 2xx/3xx. Bis dahin muss die App antworten. - Audit (Abschnitt 11) gegen den deployten Commit.
- Umschalten. Erst wenn das Audit besteht, wird der Prüfling zur laufenden Fassung auf dem stabilen Port. Ein durchgefallenes Audit heißt: der alte Stand bleibt live.
Vor dem Umschalten legt VCH einen Datenschnappschuss an. Geht das Umschalten schief, werden erst die Daten und dann der Code zurückgerollt. Frühere Releases lassen sich im Projektarbeitsplatz per Rollback zurückholen.
Auto-Deploy: ist er eingeschaltet, löst jeder Push auf den konfigurierten Deploy-Branch einen Deploy aus. Pushes auf andere Branches werden ignoriert.
- Das Ergebnis jedes Deploys liegt in
.vch/deploy-report.md(nicht im Git — VCH trägt die Datei wie den Audit-Bericht in.git/info/excludeein). Er nennt Commit, Stufe, Fehlermeldung, das Ende des Logs (Geheimnisse geschwärzt) und eine Einschätzung: „probably fixable in this repository" heißt, die Ursache liegt vermutlich im Code — beheben, committen, pushen. „platform error" heißt: nicht im Code suchen, sondern dem Nutzer sagen, was dort steht. Nach einem erfolgreichen Deploy steht dort genau das; ein alter Fehlerbericht bleibt nicht liegen. Nennt der Bericht einen anderen Commit als den, nach dem du gefragt wirst, ist er noch nicht aktualisiert.
11. Audit — was geprüft wird
Das Audit läuft nicht hier, sondern in einem eigenen Runner gegen einen sauberen Checkout
des deployten Commits. Nicht Gepushtes wird nicht geprüft — und ein .gitignore-Eintrag
macht eine Datei für das Audit unsichtbar.
| Prüfung | Schwere | Darf entfallen |
|---|---|---|
readme |
Fehler | nein |
secrets |
Fehler | nein |
description |
Warnung | nein |
lint |
Fehler | ja |
typescript |
Fehler | ja |
npm-audit |
Fehler | ja |
- Eine Warnung blockiert nie.
descriptionhält dich also nicht auf, kostet dich aber den Platz im Showcase. - „Darf entfallen" heißt: die Prüfung meldet
skipped, wenn sie auf dein Projekt nicht passt (kein TypeScript, kein npm). Eine Prüfung, die nicht entfallen darf, aber trotzdemskippedmeldet, gilt als durchgefallen — sie ist nie gelaufen. secretssucht eingecheckte Zugangsdaten. Echte Werte gehören nie ins Repository: in die.env.examplenur Beispiele, die echten Werte in den Env-Editor von VCH.- Das Ergebnis liegt nach jedem Audit in
.vch/audit-report.md(nicht im Git — VCH trägt die Datei in.git/info/excludeein). Bei einem Fehlschlag: lesen, beheben, committen, pushen — erst der nächste Deploy auditiert den neuen Commit. Der Kopf nennt Commit und Zeitpunkt; lief die Instanz beim Audit nicht, ist die Datei älter oder fehlt, dann steht der aktuelle Bericht im Audit-Fenster von VCH zum Kopieren.
12. Veröffentlichen
- Intern erreichbar ist dein Projekt, sobald ein Deploy läuft — ohne Audit, ohne weiteren
Schritt, unter
http://<prod-ip>:<port>. - Öffentlich unter einer Subdomain mit SSL wird es erst mit laufendem Deploy und bestandenem Audit für genau diesen Deploy. Die Subdomain kommt oben drauf; entfernst du sie wieder, bleibt das Projekt intern erreichbar.
- Im Showcase erscheinen veröffentlichte Projekte mit bestandenem Audit und einer
eingecheckten
.vch-description.
13. Compose — die vier Regeln, an denen es sonst scheitert
- Der App-Dienst muss seinen Port als
ports: ["${VCH_PORT}:<intern>"]veröffentlichen. VCH setztVCH_PORTund kann so einen Prüfling neben deiner laufenden Fassung starten. Ohne diese Zeile bricht der Deploy ab. - VCH führt genau EINE Compose-Datei aus — keine
-f-Ketten. Gesucht wirdcompose.yaml/compose.yml/docker-compose.yaml/docker-compose.ymlim Stamm oder in einem Unterordner. Eine Override-Datei (docker-compose.ports.yml,*.override.yml) wird ignoriert — die${VCH_PORT}-Zeile gehört in die Hauptdatei. Bei mehreren Fundstellen:compose: <pfad>in die.vch/deploy.yaml. - Jeder Dienst, der Produktionswerte braucht, bekommt
env_file: [.env]. VCH schreibt deine Werte in eine.envneben der Compose-Datei. - Der ganze Stapel startet. Datenbanken, Caches und Ähnliches aus deinem Compose laufen
automatisch mit — eine zusätzliche verwaltete Datenbank brauchst du dafür nicht. Dienste
hinter einem
profiles:-Schlüssel bleiben aus.