Installation
QuoteNode aktualisieren
Neue Versionen prüfen, auf das Paket eines neuen Release aktualisieren und sicher zurückrollen.
QuoteNode aktualisieren
QuoteNode prüft automatisch, ob neue Releases verfügbar sind. Ist eine neuere Version verfügbar, zeigt der Admin-Bereich eine Benachrichtigung mit der Release-Bezeichnung und einem Link zu den Release Notes.
Jedes Release wird als Bereitstellungspaket veröffentlicht: docker-compose.yml (und docker-compose.coolify.yml) mit den per Digest festgelegten Release-Images, env.example, release.json und die Werkzeuge in operator/. Aktualisieren heißt, die Compose-Datei durch die des nächsten Pakets zu ersetzen. Aktuelles Release ist v0.9.8-alpha (Paket).
Wie Sie aktualisieren, hängt von der Installationsart ab. Die Checkliste und die Befehle unten gelten für ein Installationsverzeichnis (Server, LAN, Laptop oder ein NAS-Ordner mit docker-compose.yml und .env). Ein Portainer-Stack hat kein solches Verzeichnis: weiter mit Portainer-Stack. Coolify: weiter mit Coolify.
Bekanntes Problem in v0.9.5-alpha: Beispiel-Backup-Ziel
Die env.example von v0.9.5-alpha enthält eine aktive Beispielzeile, BACKUP_RCLONE_REMOTE=s3:mybucket/backups. Dieses Ziel ist nicht konfiguriert: Gelangt die Zeile in Ihre Einstellungen, schlägt jedes Backup fehl, und ein fehlgeschlagener Upload hinterlässt keine lokale Kopie dieses Backups. Die Einstellungen dieser Anleitungen enthalten sie nie; prüfen Sie Ihre Installation, wenn Sie .env aus env.example erstellt oder bei einem Upgrade Einstellungen daraus übernommen haben.
Kommentieren Sie im Installationsverzeichnis genau diese Beispielzeile aus (ein echtes Ziel bleibt unverändert) und erstellen Sie die Container neu:
# Run in Bash (for example Linux, Git Bash or WSL); other shells can edit the exact placeholder manually.
(
set -eu
umask 077
temporary_env="$(mktemp .env.backup-remote.XXXXXX)"
trap 'rm -f "$temporary_env"' EXIT
carriage_return="$(printf '\r')"
# Match only the published placeholder, with either LF or Windows CRLF line endings.
sample_pattern="^BACKUP_RCLONE_REMOTE=s3:mybucket/backups${carriage_return}\{0,1\}$"
sed "s|${sample_pattern}|# &|" .env > "$temporary_env"
if LC_ALL=C grep -Eq "^BACKUP_RCLONE_REMOTE=s3:mybucket/backups${carriage_return}?$" "$temporary_env"; then
echo "Sample backup remote is still active; settings were not replaced." >&2
exit 1
else
match_status=$?
[ "$match_status" -eq 1 ] || exit "$match_status"
fi
# Keep real remote settings unchanged; publish a changed file atomically with private permissions.
if ! cmp -s .env "$temporary_env"; then
mv "$temporary_env" .env
fi
docker compose up -d
)
Löschen Sie in Portainer die Stack-Variable BACKUP_RCLONE_REMOTE, wenn sie diesen Beispielwert hat, und aktualisieren Sie dann den Stack. Die Coolify-Definition von v0.9.5-alpha übergibt diese Variable nicht an die Anwendung; löschen Sie den Beispielwert aus der Ressource, bevor Sie auf ein späteres Release aktualisieren.
Backups bleiben dann im Backup-Volume. Starten Sie ein Backup im Admin-Bereich (Admin → Security → Backup), prüfen Sie, dass es erfolgreich abgeschlossen wird, und sorgen Sie für eine Kopie außerhalb des Servers: ein konfiguriertes rclone-Ziel oder regelmäßige Kopien der Archive auf einen anderen Rechner (Sicherung und Wiederherstellung).
Umstieg auf PostgreSQL 18
Die Compose-Dateien verwenden bereits postgres:18-alpine, neue Installationen benötigen daher nichts. Lief eine frühere Alpha auf PostgreSQL 16, migrieren Sie die Daten einmalig — ein PostgreSQL-18-Server startet nicht auf einem älteren Datenverzeichnis, und die Anwendung schreibt es nie automatisch um. Folgen Sie dem eigenen, datensicheren Verfahren: Daten auf PostgreSQL 18 migrieren (Wege über die Kommandozeile und nur über die Oberfläche, je Plattform).
So funktioniert die Versionsprüfung
Die Admin-Oberfläche ruft beim Admin-Login https://quotenode.dev/releases/latest.json ab. Das ist eine nur lesende, nicht authentifizierte GET-Anfrage; es werden keine Daten Ihrer Instanz gesendet. Ist das Manifest nicht erreichbar, schlägt die Prüfung still fehl und der Admin-Bereich funktioniert normal.
Die Prüfung und die Manifest-URL sind Teil der fertig gebauten Weboberfläche. VITE_RELEASE_CHECK_ENABLED oder VITE_RELEASE_MANIFEST_URL in .env oder in Coolify zu setzen, hat bei einem Release keine Wirkung; diese Werte gelten nur, wenn Sie das Frontend-Image selbst aus dem Quellcode bauen. Soll eine Installation quotenode.dev nicht kontaktieren, sperren Sie diese Adresse in Ihrem Netz.
Checkliste vor dem Upgrade
Für ein Installationsverzeichnis; Portainer und Coolify haben unten eigene Abschnitte.
- Notieren Sie das aktuelle Release:
release.jsonim Installationsverzeichnis oder Admin > Lizenz. - Kopieren Sie
.envaußerhalb des Servers — sie enthält Secrets, die sich nicht neu erzeugen lassen (insbesondereDB_ENCRYPTION_KEY). - Laden Sie das neue Paket neben die Installation. Am laufenden Betrieb ändert das nichts:
mkdir -p ../next && cd ../next
curl -fsSLO https://quotenode.dev/releases/v0.9.8-alpha/quotenode-deploy-v0.9.8-alpha.tar.gz
tar -xzf quotenode-deploy-v0.9.8-alpha.tar.gz --strip-components=1
cd -
# Hat das neue Release Einstellungen hinzugefügt oder entfernt? Vergleichen Sie Ihre .env mit der neuen Vorlage.
diff <(grep -o '^[A-Z_]*=' .env | sort) <(grep -o '^[A-Z_]*=' ../next/env.example | sort)
- Ergänzen Sie in
.envdie Einstellungen, die das neue Release braucht (der Vergleich oben listet sie auf; Installationen aus der Zeit vor Release-Paketen: siehe Installationen aus der Zeit vor Release-Paketen). Die laufende Installation verwendet sie noch nicht. - Erstellen Sie mit dem Werkzeug des neuen Pakets den Upgrade-Checkpoint und eine verifizierte Sicherung. Am laufenden Betrieb ändert das nichts, und beim ersten Fehler bricht es ab:
BACKUP_ARCHIVE_ENCRYPTION_MODE=AGE_RECIPIENT BACKUP_AGE_RECIPIENT=age1... \
../next/operator/upgrade.sh prepare --export-to ../quotenode-backups
Der Checkpoint (in .quotenode-upgrade/, nur von dieser Installation verwendet) hält die installierte docker-compose.yml, .env und release.json, die Identität der laufenden Images und den Zustand des Datenbankschemas fest. Die Sicherung entsteht mit den Werkzeugen des neuen Releases auf dem Compose-Projekt und den Volumes dieser Installation, bleibt in diesem Lauf lokal, auch wenn entfernte Sicherungen konfiguriert sind, und wird in ../quotenode-backups erst behalten, wenn ihr SHA-256 übereinstimmt. Kopieren Sie dieses Verzeichnis außerhalb des Servers, bevor Sie fortfahren. Den age-Empfänger finden Sie in Ihrem Recovery Kit (Sicherung und Wiederherstellung).
- Sind geplante Sicherungen aktiv, prüfen Sie zusätzlich, ob die letzte erfolgreich war (Admin-Bereich).
Ablauf des Upgrades
Docker Compose (Server, LAN, Laptop, NAS-Ordner)
Führen Sie nach der Checkliste im Installationsverzeichnis aus, damit Compose-Projekt und Volumes gleich bleiben:
../next/operator/upgrade.sh apply
upgrade.sh apply lädt zuerst alle Images des neuen Releases und bricht beim ersten Fehler ab: Scheitert ein Download, läuft die Installation unverändert weiter. Erst danach installiert es docker-compose.yml, release.json, env.example und operator/ aus dem Paket, startet die neue Version und wartet, bis sie gesund ist. Datenbankmigrationen laufen automatisch beim Start des neuen Backends. Docker Compose 2.17 oder neuer ist erforderlich.
Portainer-Stack
upgrade.sh benötigt ein Installationsverzeichnis, daher wird ein Portainer-Stack in Portainer aktualisiert:
- Prüfen Sie, dass das letzte geplante Backup erfolgreich war (Admin-Bereich), sichern Sie die Volumes des Stacks mit dem Snapshot- oder Backup-Werkzeug Ihrer Plattform und speichern Sie eine Kopie der aktuellen Stack-Definition und ihrer Umgebungsvariablen.
- Öffnen Sie den Editor des Stacks und ersetzen Sie die Definition durch den folgenden Block: die Portainer-Anpassung der
docker-compose.ymldes Release, derselbe Block wie in Installation mit Portainer. Fügen Sie nicht die Originaldatei des Pakets ein: Sie liest.env, die Portainer nicht hat. - Behalten Sie den Stack-Namen und seine Umgebungsvariablen (
stack.env); ergänzen Sie die Einstellungen, die das neue Release braucht (Vergleich mit seinerenv.example). - Klicken Sie mit aktiviertem Image-Abruf auf Update the stack. Datenbankmigrationen laufen beim Start des neuen Backends.
# Portainer Web editor adaptation of the release docker-compose.yml: env_file reads stack.env (the stack's
# environment variables) instead of .env in postgres, backend and backup-worker. Images, services, ports and
# volumes are unchanged. For a folder-based installation use the unchanged file of the release package.
x-json-file-logging: &json-file-logging
driver: json-file
options:
max-size: "${DOCKER_LOG_MAX_SIZE:-10m}"
max-file: "${DOCKER_LOG_MAX_FILE:-5}"
# ==========================================================================
# QuoteNode — standalone deployment (docker compose)
# GENERATED by scripts/render-deployment.mjs — do not edit by hand.
# Release v0.9.8-alpha (commit ff74453ca68f3c40bd86a32f0b0b813aaffc7aea, build 28); platforms: linux/amd64.
# API image: ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
# Frontend image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
#
# Settings: the .env file in this directory (start from env.example, the commented catalogue of every
# setting; postgres, backend and backup-worker read it). Start: docker compose up -d
# DOMAIN: public host name for automatic HTTPS, or :80 / http://<address> for plain HTTP on a trusted LAN.
# Only the caddy entry point publishes ports (HTTP_PORT/HTTPS_PORT, default 80/443).
# Upgrades: replace this file with the next release package version; volumes keep the data.
# ==========================================================================
services:
postgres:
# Database (PostgreSQL 18); internal network only, data in the database volume.
image: postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873
# JIT is off by default: for this OLTP workload most queries fall below jit_above_cost,
# so JIT compilation rarely helps and can add latency. Set PG_JIT=on to re-enable.
command: ["postgres", "-c", "jit=${PG_JIT:-off}"]
env_file: stack.env
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_INITDB_ARGS: "--data-checksums"
# postgres:18 refuses to start on a bare /var/lib/postgresql/data mount (new default layout).
# Pin PGDATA to the legacy path so the existing volume mount keeps working; major upgrades go
# through a logical dump/restore, never an in-place upgrade of the data directory.
PGDATA: /var/lib/postgresql/data
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 10
# CPU ceilings are opt-in (*_CPUS): 0 = no ceiling, all host cores. Docker refuses a ceiling above the
# host's core count, so a fixed default would stop the stack on smaller hosts (minimum: 2 cores).
cpus: ${POSTGRES_CPUS:-0}
# Ceiling, not a reservation: PG sits at tens of MB until working set/connections grow.
# Default 512m fits the 4 GB-VM profile; raise POSTGRES_MEM_LIMIT for larger tiers.
mem_limit: ${POSTGRES_MEM_LIMIT:-512m}
restart: unless-stopped
logging: *json-file-logging
# No published host port: the database is reachable only on the internal network.
gotenberg:
# PDF rendering (Chromium) for the backend; internal network only, keeps no data.
image: gotenberg/gotenberg:8@sha256:aa552cc115db488e0f0bcb07446aac13071ad51505b642c84bb894500907b42b
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 5
cpus: ${GOTENBERG_CPUS:-0}
# Chromium PDF rendering: measured ~188 MiB peak rendering a real offer template, so
# 448m keeps ~2.4x headroom. Freed budget goes to backup-worker (closer to its limit).
mem_limit: ${GOTENBERG_MEM_LIMIT:-448m}
restart: unless-stopped
logging: *json-file-logging
backend:
# API server (Java): business logic and web jobs; uploads, PDFs and the GeoIP database live in volumes.
image: ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
# Time Docker gives the backend between SIGTERM and SIGKILL. 60 s = the SMTP handoff hard limit
# (mail.handoff.deadline-ms + end-of-data-allowance-ms = 25 s) + 5 s to record its outcome + the HTTP
# graceful drain phase (30 s). A ceiling, not a delay: an idle backend exits in seconds.
stop_grace_period: 60s
depends_on:
postgres:
condition: service_healthy
gotenberg:
condition: service_healthy
env_file: stack.env
environment:
SPRING_PROFILES_ACTIVE: prod
JOBS_MODE: web
# The caddy edge below is the backend's only HTTP peer, so it is the trusted proxy by default (security
# finding #80); without it every request would appear to come from the edge container. Override only
# for a custom proxy chain.
SECURITY_TRUSTED_PROXIES: ${SECURITY_TRUSTED_PROXIES:-caddy}
BACKUP_LOCAL_DIR: /app/data/backups
volumes:
- backend_uploads:/app/data/uploads
- backend_pdfs:/app/data/pdfs
- backend_backups:/app/data/backups
- backend_geoip:/app/data/geoip
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
interval: 15s
timeout: 10s
retries: 5
start_period: 45s
cpus: ${BACKEND_CPUS:-0}
# Heap auto-scales to 70% of this limit (MaxRAMPercentage); default 1536m → ~1 GB heap,
# fits the 4 GB-VM profile. Raise BACKEND_MEM_LIMIT for heavier load (see resource docs).
mem_limit: ${BACKEND_MEM_LIMIT:-1536m}
restart: unless-stopped
logging: *json-file-logging
backup-worker:
# Scheduled backups: same image as the backend, JOBS_MODE=backup-only; archives go to the backups volume.
image: ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
depends_on:
postgres:
condition: service_healthy
backend:
condition: service_healthy
env_file: stack.env
environment:
SPRING_PROFILES_ACTIVE: prod
JOBS_MODE: backup-only
BACKUP_LOCAL_DIR: /app/data/backups
# Worker runs pg_dump in a shell (out-of-JVM) and never does web/import heap work,
# so it needs little heap. On this small 768m container the ~350 MB fixed non-heap
# cost makes the global MaxRAMPercentage=70 (538 MB heap → 888 MB total) unsafe.
# Cap heap lower so heap_max + non-heap stays well under the limit.
JAVA_OPTS: "-XX:MaxRAMPercentage=45.0 -XX:+UseG1GC -XX:G1PeriodicGCInterval=300000"
volumes:
- backend_uploads:/app/data/uploads
- backend_pdfs:/app/data/pdfs
- backend_backups:/app/data/backups
- backend_geoip:/app/data/geoip
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
interval: 15s
timeout: 10s
retries: 5
# JVM boots a large Spring context (CPU-bound); the grace window must outlast
# cold start to avoid a false-unhealthy restart loop under load.
start_period: 300s
# CPU is a ceiling (idle cost ~0); give the worker enough to boot fast and to run
# pg_dump + age-encryption/compression bursts without throttling. Idles near zero CPU.
cpus: ${WORKER_CPUS:-0}
# Default 832m: measured backup peak (JVM idle + pg_dump + tar + gzip) is ~607 MiB, so
# this keeps a ~27% margin. Do NOT set WORKER_MEM_LIMIT below ~768m or backups risk OOM.
mem_limit: ${WORKER_MEM_LIMIT:-832m}
restart: unless-stopped
logging: *json-file-logging
frontend:
# Web UI: the static build served by Caddy, reached through the caddy entry point.
image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
depends_on:
backend:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
interval: 15s
timeout: 5s
retries: 3
cpus: ${FRONTEND_CPUS:-0}
# Prod frontend is Caddy serving the static build (measured ~46 MiB peak under load); 96m is ample.
# CPU is a free ceiling, so headroom for concurrent connections costs nothing at idle.
mem_limit: ${FRONTEND_MEM_LIMIT:-96m}
restart: unless-stopped
logging: *json-file-logging
caddy:
# Entry point: the only published ports (HTTP_PORT/HTTPS_PORT, default 80/443), TLS for DOMAIN, routing, security headers.
image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
# The released frontend image carries the edge config (frontend/caddy/Caddyfile.edge) and the Cloudflare
# ranges, so the edge needs no host files. Same image digest as the frontend service.
command: ["caddy", "run", "--config", "/etc/caddy/Caddyfile.edge", "--adapter", "caddyfile"]
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_healthy
environment:
# Site address for frontend/caddy/Caddyfile.edge: a public host name enables automatic HTTPS; ":80" or
# "http://host" serves plain HTTP on a trusted LAN. Required: an empty site address is not a valid config.
DOMAIN: ${DOMAIN:?set DOMAIN to the public host name, or :80 for plain HTTP on a LAN}
# Optional: address(es) of an operator reverse proxy in front of this edge (default: trust none).
EDGE_TRUSTED_PROXIES: ${EDGE_TRUSTED_PROXIES:-}
ports:
- "${HTTP_PORT:-80}:80"
- "${HTTPS_PORT:-443}:443"
- "${HTTPS_PORT:-443}:443/udp" # HTTP/3 (QUIC)
volumes:
- caddy_data:/data
- caddy_config:/config
# caddy is the single ingress (TLS, HTTP/3/QUIC, proxying all traffic); give it
# cores for handshake/encryption bursts under load. CPU idle cost ~0.
cpus: ${CADDY_CPUS:-0}
# 96m fits the 4 GB / light-traffic profile. Under heavy TLS load (many concurrent
# handshakes, large QUIC buffers) raise CADDY_MEM_LIMIT — this ingress is untested at scale.
mem_limit: ${CADDY_MEM_LIMIT:-96m}
restart: unless-stopped
logging: *json-file-logging
# Persistent data: database, uploads, generated PDFs, local backup archives, GeoIP database and the entry
# point's certificates/config. Docker prefixes each name with the Compose project name (by default the
# directory name), so keep the project name across upgrades.
volumes:
postgres_data:
backend_uploads:
backend_pdfs:
backend_backups:
backend_geoip:
caddy_data:
caddy_config:
Zum Zurückrollen stellen Sie die Volume-Sicherung zusammen mit der gespeicherten Stack-Definition wieder her. Starten Sie die vorherige Definition nie auf einer Datenbank, die das neue Release bereits migriert hat.
Coolify
Ersetzen Sie die Compose-Definition der Ressource durch die docker-compose.coolify.yml des neuen Pakets (Edit Compose File) und stellen Sie bereit. Coolify lädt die neuen Images, bevor es die laufenden Container stoppt. Siehe Installation mit Coolify.
Installationen aus der Zeit vor Release-Paketen
Haben Sie QuoteNode nach diesen Anleitungen installiert, bevor es Release-Pakete gab (eine handgeschriebene docker-compose.yml mit :latest-Images), aktualisieren Sie im selben Verzeichnis mit denselben Befehlen: upgrade.sh erstellt die Sicherung mit den Werkzeugen des neuen Releases auf dem Compose-Projekt und den Volumes Ihrer Installation, sodass vorher weder ein operator/-Verzeichnis noch ein Backup-Dienst nötig ist. Ergänzen Sie vor prepare diese Einstellungen in .env; die laufende Installation verwendet sie noch nicht:
DOMAINkonfiguriert jetzt den neuen Einstiegspunkt (caddy): Ein öffentlicher Hostname erhält automatisch HTTPS; für einfaches HTTP im LAN oder auf dem Laptop verwenden SieDOMAIN=http://<Adresse>(zum Beispielhttp://192.168.1.20oderhttp://localhost).- Sind die Ports 80/443 belegt, setzen Sie
HTTP_PORT/HTTPS_PORT, statt die Compose-Datei zu bearbeiten.
Das Paket behält die Volume-Namen der früheren Anleitungen (postgres_data, backend_uploads, backend_pdfs), Ihre Daten werden also weiterverwendet. Starten Sie upgrade.sh aus demselben Verzeichnis (bzw. behalten Sie denselben Stack-Namen in Portainer): Ein anderer Projektname würde mit leeren Volumes starten.
Wenn eine Migration das Upgrade stoppt
Eine Migration kann die Ausführung verweigern, wenn sie Daten findet, die sie nicht selbstständig ändern darf. Das Backend startet dann nicht, und diese Migration ändert nichts — sie wird vollständig zurückgerollt und hinterlässt nichts zu reparieren in der Migrationshistorie. Frühere Migrationen desselben Upgrades können bereits angewendet sein; Ihre Datenbank steht also direkt vor dem verweigerten Schritt und nicht auf der Ausgangsversion. Es gibt keine Eile und keinen Datenverlust.
Den Grund lesen Sie im Log:
docker compose logs backend | grep -i "cannot enforce"
Für Zuordnungen von Angebotsabschnitten enthält das Image eine geführte Reparatur, die ohne laufendes Backend funktioniert — sie zeigt die betroffenen Angebote und lässt Sie entscheiden, was mit ihnen geschieht. Siehe Fehlerbehebung bei der Installation.
Verwenden Sie nicht flyway repair oder baseline, um eine verweigerte Migration zu umgehen. Sie reparieren die Daten nicht, und eine blockierte Migration hinterlässt nichts zu reparieren.
Da frühere Migrationen bereits angewendet sein können, erlaubt ein fehlgeschlagener Start allein nie die Rückkehr zu den vorherigen Images — siehe Zurückrollen.
Prüfung nach dem Upgrade
- Öffnen Sie
/health— die Antwort istUP. - Öffnen Sie
/actuator/info: DessencommitShaentsprichtcommitShain der neuenrelease.json. - Melden Sie sich an und prüfen Sie die neue Version unter Admin > Lizenz.
- Erstellen Sie ein Testangebot und erzeugen Sie ein PDF.
- Öffnen Sie einen öffentlichen Link, um das Routing zu prüfen.
- Ist SMTP eingerichtet, senden Sie eine Testbenachrichtigung per E-Mail.
Zurückrollen
Führen Sie niemals docker compose down -v aus — das löscht alle Daten, einschließlich der Datenbank.
upgrade.sh rollback kehrt nur dann zur von prepare gesicherten Definition zurück, wenn das sicher ist: Der Checkpoint muss zu dieser Installation gehören, das Datenbankschema muss genau dem festgehaltenen entsprechen — ein fehlgeschlagener Start beweist das nicht, frühere Migrationen können bereits festgeschrieben sein — und jedes vorherige Image muss noch dasjenige sein, das lief. Andernfalls lehnt es ab und ändert nichts:
../next/operator/upgrade.sh rollback
- Erlaubt: Die gesicherte
docker-compose.yml,.envundrelease.jsonkommen zurück, und die vorherigen Images starten ohne Download; vom neuen Release hinzugefügte Dienste werden entfernt, Volumes bleiben erhalten. - Abgelehnt: Starten Sie die vorherigen Images nicht von Hand. Hat eine Migration abgelehnt, beheben Sie das in der neuen Version (siehe Wenn eine Migration das Upgrade stoppt) oder stellen Sie die Sicherung vor dem Upgrade wieder her — Datenbank und Dateien als eine Einheit — wie unter Sicherung und Wiederherstellung beschrieben. Die Wiederherstellung prüft Archiv und Kompatibilität, bevor sie etwas ändert, und behält eine Sicherheitskopie, bis das Ergebnis verifiziert ist.
- Installationen aus der Zeit vor Release-Paketen rollen genauso zurück. Stellen Sie nach einer Ablehnung die Sicherung aus
../quotenode-backupsmitoperator/restore.shdieses Releases wieder her; das Release aktualisiert die wiederhergestellten Daten beim Start.
Versionsformat
QuoteNode verwendet semantische Versionierung mit Kanal-Suffix:
v0.9.0-alpha— frühe Entwicklungv0.9.0-beta— öffentliche Betav0.9.0-rc— Release Candidatev0.9.0— stabiles Release
Eine Release-Bezeichnung wird nie für andere Images wiederverwendet. release.json und https://quotenode.dev/releases/latest.json enthalten Version, Kanal, Bezeichnung, Commit und die Image-Digests des Release.