Refactor deployment process and update documentation
- Removed nginx configuration file as it is no longer needed. - Updated README.md to reflect changes in deployment structure. - Enhanced DEPLOYMENT.md with detailed directory structure and user permissions. - Added release.sh and rollback.sh scripts for managing deployments. - Improved N8N.md to clarify file access and document handling. - Adjusted health check and cache flushing procedures in deployment scripts.
This commit is contained in:
+199
-64
@@ -3,14 +3,42 @@
|
||||
Zielsystem: Debian/Ubuntu mit nginx und php8.5-fpm. Postgres und Redis laufen
|
||||
bereits für n8n und werden mitbenutzt (eigene Datenbank, eigene Redis-Nummer).
|
||||
|
||||
## Verzeichnisse auf dem Webserver
|
||||
|
||||
```
|
||||
/var/www/ekdos/
|
||||
├── current -> releases/<sha> was nginx liest
|
||||
├── previous Notiz für rollback.sh
|
||||
├── releases/
|
||||
│ └── <sha>/
|
||||
│ ├── public/ das Vite-Bündel -> nginx root
|
||||
│ └── backend/ PHP + vendor/ -> fastcgi
|
||||
│ ├── .env -> ../../../shared/.env
|
||||
│ └── var/cache/ kompilierter DI-Container, je Veröffentlichung
|
||||
├── shared/
|
||||
│ └── .env überlebt jedes Ausrollen
|
||||
└── deploy/
|
||||
├── release.sh
|
||||
└── rollback.sh
|
||||
```
|
||||
|
||||
Oberfläche und Backend liegen **in derselben Veröffentlichung** und werden mit
|
||||
einem einzigen Symlink-Tausch gemeinsam sichtbar. Eine neue Oberfläche kann
|
||||
daher nie gegen ein altes Backend laufen.
|
||||
|
||||
## 1. Pakete
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y nginx php8.5-fpm php8.5-cli php8.5-pgsql php8.5-redis \
|
||||
php8.5-mbstring php8.5-curl php8.5-intl php8.5-xml
|
||||
php8.5-mbstring php8.5-curl php8.5-intl php8.5-xml \
|
||||
composer rsync curl
|
||||
```
|
||||
|
||||
`composer` wird auf dem Webserver gebraucht: die PHP-Abhängigkeiten werden dort
|
||||
aufgelöst, nicht im Gitea-Runner. Nur dort stimmen PHP-Version und Erweiterungen,
|
||||
sodass die Plattformprüfung von Composer etwas Echtes prüft.
|
||||
|
||||
`php8.5-intl` ist optional, verbessert aber die Erkennung der Kundenrücksprache
|
||||
in Ticketberichten (Unicode-Normalisierung). Ohne die Erweiterung greift ein
|
||||
Rückfall ohne Normalisierung.
|
||||
@@ -29,41 +57,54 @@ Redis braucht nichts weiter -- EK-DOS legt seine Schlüssel unter dem Präfix
|
||||
> angemeldet und jede Ansicht fragt wieder direkt bei n8n an. Die Anwendung
|
||||
> läuft weiter, aber langsamer und mit erneuter Anmeldung.
|
||||
|
||||
## 3. Verzeichnisse
|
||||
## 3. Benutzer und Rechte
|
||||
|
||||
Zwei Konten: `ekdos` führt PHP aus, `deploy` nimmt die Dateien entgegen. Über
|
||||
die gemeinsame Gruppe kommt php-fpm an das, was `deploy` hochlädt.
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /var/www/ekdos/{releases,backend}
|
||||
sudo useradd --system --home /var/www/ekdos --shell /usr/sbin/nologin ekdos
|
||||
sudo chown -R ekdos:ekdos /var/www/ekdos
|
||||
sudo useradd --create-home --shell /bin/bash deploy
|
||||
sudo usermod -aG ekdos deploy
|
||||
|
||||
sudo mkdir -p /var/www/ekdos/{releases,shared,deploy}
|
||||
sudo chown -R deploy:ekdos /var/www/ekdos
|
||||
sudo chmod -R g+rX /var/www/ekdos
|
||||
|
||||
# setgid: alles neu Angelegte erbt die Gruppe ekdos, sonst käme php-fpm
|
||||
# nach dem nächsten Ausrollen nicht mehr an die Dateien.
|
||||
sudo find /var/www/ekdos -type d -exec chmod g+s {} +
|
||||
|
||||
sudo mkdir -p /var/log/php && sudo chown ekdos:ekdos /var/log/php
|
||||
```
|
||||
|
||||
## 4. Backend einrichten
|
||||
`release.sh` lädt php-fpm neu. Dafür genau dieses eine Kommando ohne Passwort:
|
||||
|
||||
```bash
|
||||
cd /var/www/ekdos/backend
|
||||
sudo -u ekdos cp .env.example .env
|
||||
sudo -u ekdos editor .env
|
||||
sudo -u ekdos composer install --no-dev --optimize-autoloader
|
||||
sudo -u ekdos php bin/ekdos migrate
|
||||
sudo -u ekdos php bin/ekdos user:create # erster Administrator
|
||||
sudo -u ekdos php bin/ekdos check
|
||||
echo 'deploy ALL=(root) NOPASSWD: /bin/systemctl reload php8.5-fpm' \
|
||||
| sudo tee /etc/sudoers.d/ekdos-deploy
|
||||
sudo chmod 440 /etc/sudoers.d/ekdos-deploy
|
||||
sudo visudo -c
|
||||
```
|
||||
|
||||
`.env` gehört dem Benutzer `ekdos` und sollte `chmod 600` sein. Sie wird beim
|
||||
Ausrollen ausdrücklich nicht überschrieben.
|
||||
## 4. Konfiguration anlegen
|
||||
|
||||
```bash
|
||||
sudo -u deploy cp backend/.env.example /var/www/ekdos/shared/.env
|
||||
sudo -u deploy editor /var/www/ekdos/shared/.env
|
||||
sudo chown deploy:ekdos /var/www/ekdos/shared/.env
|
||||
sudo chmod 640 /var/www/ekdos/shared/.env
|
||||
```
|
||||
|
||||
`640` mit Gruppe `ekdos`: php-fpm liest sie, sonst niemand. Sie wird beim
|
||||
Ausrollen ausdrücklich nie überschrieben.
|
||||
|
||||
### n8n-Adressen
|
||||
|
||||
| Einstellung | Wert | warum |
|
||||
| ------------------- | --------------------------------- | ----------------------------------------------------------- |
|
||||
| `N8N_PUBLIC_BASE` | `https://n8n.elektro-krueger.eu` | Der Dienst auf Port 5678 ist nur über den CNAME erreichbar |
|
||||
| `N8N_INTERNAL_HOST` | `10.0.11.131` | Jeder weitere n8n-Dienst auf einem anderen Port |
|
||||
|
||||
Alle heutigen `ek-dos-web`-Webhooks laufen über den 5678-Dienst und damit über
|
||||
`N8N_PUBLIC_BASE`. Kommt später ein zweiter n8n-Dienst auf eigenem Port dazu,
|
||||
wird er mit `Endpoints::internal(<port>, '<pfad>')` angesprochen und geht über
|
||||
die RFC1918-Adresse -- er ist nach aussen nicht veröffentlicht.
|
||||
| Einstellung | Wert | warum |
|
||||
| ------------------- | -------------------------------- | ---------------------------------------------------------- |
|
||||
| `N8N_PUBLIC_BASE` | `https://n8n.elektro-krueger.eu` | Der Dienst auf Port 5678 ist nur über den CNAME erreichbar |
|
||||
| `N8N_INTERNAL_HOST` | `10.0.11.131` | Jeder weitere n8n-Dienst auf einem anderen Port |
|
||||
|
||||
## 5. php-fpm
|
||||
|
||||
@@ -75,66 +116,160 @@ ls -l /run/php/ekdos.sock # muss www-data:www-data 0660 gehören
|
||||
```
|
||||
|
||||
Der Pool setzt `opcache.validate_timestamps = 0`. Neuer Quelltext wird deshalb
|
||||
**erst nach einem `systemctl reload php8.5-fpm`** wirksam -- die Ausrollstrecke
|
||||
macht das selbst.
|
||||
**erst nach einem `systemctl reload php8.5-fpm`** wirksam -- `release.sh` macht
|
||||
das selbst.
|
||||
|
||||
## 6. nginx
|
||||
|
||||
```bash
|
||||
sudo cp deploy/nginx/ekdos.conf /etc/nginx/sites-available/ekdos.conf
|
||||
sudo ln -sf /etc/nginx/sites-available/ekdos.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
Die nginx-Konfiguration wird auf dem Server gepflegt und gehört bewusst nicht
|
||||
ins Repository. Was sie leisten muss:
|
||||
|
||||
Kurzfassung: `fastcgi_pass unix:/run/php/ekdos.sock` für `/api/`, alles andere
|
||||
`try_files $uri $uri/ /index.html`. Kein Anwendungsserver, kein Reverse Proxy
|
||||
auf einen Node-Prozess.
|
||||
| Pfad | Ziel |
|
||||
| ------------- | ------------------------------------------------------------------------ |
|
||||
| `/api/` | `fastcgi_pass unix:/run/php/ekdos.sock`, `SCRIPT_FILENAME` auf `/var/www/ekdos/current/backend/public/index.php` |
|
||||
| `/assets/` | `try_files $uri =404` -- kein SPA-Rückfall, sonst wird eine fehlende JS-Datei zu HTML mit Status 200 |
|
||||
| alles andere | `root /var/www/ekdos/current/public`, `try_files $uri $uri/ /index.html` |
|
||||
|
||||
Läuft der Zugriff nur intern über HTTP, kann `SESSION_COOKIE_SECURE=false`
|
||||
gesetzt und der 443-Block entfernt werden. Sobald TLS anliegt: wieder auf `true`.
|
||||
Drei Punkte, die erfahrungsgemäss Ärger machen:
|
||||
|
||||
## 7. Ausrollen
|
||||
- **`HTTP_X_FORWARDED_FOR` auf `$remote_addr` setzen**, nicht auf
|
||||
`$proxy_add_x_forwarded_for`. Letzteres hängt die Adresse nur an einen vom
|
||||
Client mitgeschickten Header an -- damit liesse sich die Anmeldebremse mit
|
||||
einem selbst gesetzten `X-Forwarded-For` umgehen. Steht ein Proxy davor,
|
||||
dessen Netze über `set_real_ip_from` eintragen.
|
||||
- **`add_header` wird nicht vererbt**, sobald eine `location` eine eigene
|
||||
Kopfzeile setzt. Ein Block mit eigenem `Cache-Control` verliert damit alle
|
||||
Sicherheitskopfzeilen des Serverblocks.
|
||||
- **`/api/health` von einer HTTPS-Umleitung ausnehmen.** `release.sh` prüft
|
||||
lokal über HTTP; eine 301 wäre für `curl -f` ein Erfolg, ohne dass PHP je
|
||||
erreicht würde. Alternativ `EKDOS_HEALTH_URL` auf die HTTPS-Adresse setzen.
|
||||
|
||||
Die Gitea-Strecke (`.gitea/workflows/build.yml`) macht das bei jedem Push auf
|
||||
`main`. Nötig sind:
|
||||
Läuft der Zugriff nur intern über HTTP, muss `SESSION_COOKIE_SECURE=false`
|
||||
gesetzt sein -- ein Secure-Cookie wird über reines HTTP nicht gesendet.
|
||||
|
||||
- ein SSH-Schlüssel als Gitea-Secret `DEPLOY_SSH_KEY`
|
||||
- ein Konto `deploy` auf dem Server, das nach `/var/www/ekdos` schreiben darf
|
||||
- `sudo systemctl reload php8.5-fpm` ohne Passwort für dieses Konto
|
||||
## 7. Erstes Ausrollen von Hand
|
||||
|
||||
```
|
||||
deploy ALL=(root) NOPASSWD: /bin/systemctl reload php8.5-fpm
|
||||
```
|
||||
|
||||
Jede Veröffentlichung landet unter `releases/<sha>`; sichtbar wird sie erst
|
||||
durch den Symlink-Tausch von `current`. Die letzten fünf bleiben liegen, ein
|
||||
Rückschritt ist damit ein `ln -sfn`.
|
||||
|
||||
### Von Hand
|
||||
Die Strecke übernimmt das später, aber einmal von Hand zeigt, ob alles steht:
|
||||
|
||||
```bash
|
||||
cd frontend && pnpm install --frozen-lockfile && pnpm build
|
||||
rsync -az --delete frontend/dist/ server:/var/www/ekdos/releases/manuell/
|
||||
ssh server 'cd /var/www/ekdos && ln -sfn releases/manuell current && sudo systemctl reload php8.5-fpm'
|
||||
# auf dem Arbeitsplatz
|
||||
cd frontend && pnpm install && pnpm build && cd ..
|
||||
|
||||
SHA=erste
|
||||
ssh deploy@10.0.11.131 "mkdir -p /var/www/ekdos/releases/$SHA"
|
||||
rsync -az --delete frontend/dist/ deploy@10.0.11.131:/var/www/ekdos/releases/$SHA/public/
|
||||
rsync -az --delete --exclude vendor/ --exclude .env --exclude var/ \
|
||||
backend/ deploy@10.0.11.131:/var/www/ekdos/releases/$SHA/backend/
|
||||
rsync -az --chmod=F755 deploy/release.sh deploy/rollback.sh \
|
||||
deploy@10.0.11.131:/var/www/ekdos/deploy/
|
||||
|
||||
ssh deploy@10.0.11.131 /var/www/ekdos/deploy/release.sh $SHA
|
||||
```
|
||||
|
||||
`release.sh` installiert die Composer-Pakete, schreibt das Schema fort, schaltet
|
||||
den Symlink um, lädt php-fpm neu, verwirft den n8n-Cache und prüft
|
||||
`/api/health`. Bricht etwas vorher ab, bleibt die laufende Fassung unberührt.
|
||||
|
||||
Danach den ersten Administrator anlegen:
|
||||
|
||||
```bash
|
||||
ssh deploy@10.0.11.131 'php /var/www/ekdos/current/backend/bin/ekdos user:create'
|
||||
ssh deploy@10.0.11.131 'php /var/www/ekdos/current/backend/bin/ekdos check'
|
||||
```
|
||||
|
||||
## 8. Gitea-Strecke
|
||||
|
||||
`.gitea/workflows/build.yml` läuft bei jedem Push auf `main`:
|
||||
|
||||
| Auftrag | Container | tut |
|
||||
| ---------------------- | ------------------ | ------------------------------------------------------------- |
|
||||
| `backend-pruefen` | `php:8.5-cli` | `php -l` über alle Dateien, `composer validate` |
|
||||
| `bauen-und-ausrollen` | `node:22-bookworm` | `pnpm typecheck` / `build`, dann rsync über SSH und `release.sh` |
|
||||
|
||||
Bei einem Pull Request wird nur geprüft und gebaut; ausgerollt wird
|
||||
ausschliesslich aus `main`.
|
||||
|
||||
Bauen und Ausrollen liegen bewusst in **einem** Auftrag: das Bündel bleibt im
|
||||
Arbeitsverzeichnis und geht von dort per rsync raus. `upload-artifact` /
|
||||
`download-artifact` würden nur eine Fassungsabhängigkeit einführen (v3 oder v4,
|
||||
je nach Gitea-Version) und damit einen verlässlichen Fehlschlag beim ersten Lauf.
|
||||
|
||||
**Es gibt keinen automatischen Rückschritt.** `release.sh` tauscht den Symlink
|
||||
erst nach Composer und Migration. Scheitert es davor, läuft die alte Fassung
|
||||
unverändert weiter -- ein automatischer Rückschritt würde dann auf die
|
||||
*vorletzte* schalten und aus einem folgenlosen Fehlschlag einen Ausfall machen.
|
||||
Der Lauf berichtet stattdessen, was gerade aktiv ist und ob `/api/health`
|
||||
antwortet; zurückgeschaltet wird bei Bedarf von Hand.
|
||||
|
||||
### Schlüssel einrichten
|
||||
|
||||
Auf dem Arbeitsplatz:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -f gitea-deploy -C 'gitea-runner -> ekdos' -N ''
|
||||
ssh-copy-id -i gitea-deploy.pub deploy@10.0.11.131
|
||||
ssh-keyscan -t ed25519 10.0.11.131
|
||||
```
|
||||
|
||||
In Gitea unter *Settings -> Secrets* zwei Einträge:
|
||||
|
||||
| Secret | Inhalt |
|
||||
| -------------------- | ----------------------------------------------------------- |
|
||||
| `DEPLOY_SSH_KEY` | der Inhalt von `gitea-deploy` (der **private** Schlüssel) |
|
||||
| `DEPLOY_KNOWN_HOSTS` | die Ausgabe von `ssh-keyscan -t ed25519 10.0.11.131` |
|
||||
|
||||
`DEPLOY_KNOWN_HOSTS` ist optional -- fehlt es, übernimmt der Lauf den
|
||||
Fingerabdruck ungeprüft und schreibt einen Hinweis ins Protokoll. Für den
|
||||
Dauerbetrieb setzen.
|
||||
|
||||
Den privaten Schlüssel danach vom Arbeitsplatz löschen; er liegt in Gitea.
|
||||
|
||||
### Lockfiles
|
||||
|
||||
Beide Aufträge bestehen auf Sperrdateien, sonst löst jeder Lauf neu auf und
|
||||
bekommt womöglich andere Fassungen als geprüft:
|
||||
|
||||
```bash
|
||||
cd backend && composer update # erzeugt composer.lock
|
||||
cd frontend && pnpm install # erzeugt pnpm-lock.yaml
|
||||
```
|
||||
|
||||
Beide einchecken.
|
||||
|
||||
## Zurückschalten
|
||||
|
||||
```bash
|
||||
ssh deploy@10.0.11.131 /var/www/ekdos/deploy/rollback.sh --list # was liegt da
|
||||
ssh deploy@10.0.11.131 /var/www/ekdos/deploy/rollback.sh # eine zurück
|
||||
ssh deploy@10.0.11.131 /var/www/ekdos/deploy/rollback.sh 2f9c1ab # auf eine bestimmte
|
||||
```
|
||||
|
||||
Es wird nur der Symlink getauscht und php-fpm neu geladen -- Sekunden. Die
|
||||
letzten fünf Veröffentlichungen bleiben liegen.
|
||||
|
||||
> **Migrationen werden nicht zurückgenommen.** Hat eine Fassung das Schema
|
||||
> geändert, muss die alte damit umgehen können. Bei den bisherigen Migrationen
|
||||
> (nur Tabellen anlegen) ist das der Fall.
|
||||
|
||||
## Prüfen, wenn etwas klemmt
|
||||
|
||||
```bash
|
||||
php backend/bin/ekdos check # Postgres, Redis, n8n
|
||||
curl -sS https://<host>/api/health # ohne Anmeldung erreichbar
|
||||
tail -f /var/log/php/ekdos-error.log # Ausnahmen aus dem Backend
|
||||
php /var/www/ekdos/current/backend/bin/ekdos check # Postgres, Redis, n8n
|
||||
curl -fsS http://127.0.0.1/api/health # ohne Anmeldung erreichbar
|
||||
tail -f /var/log/php/ekdos-error.log # Ausnahmen aus dem Backend
|
||||
tail -f /var/log/nginx/ekdos.error.log
|
||||
```
|
||||
|
||||
| Symptom | meistens |
|
||||
| ------------------------------------------- | --------------------------------------------------------------------- |
|
||||
| 502 auf `/api/` | Socket fehlt oder falsche Rechte; `systemctl status php8.5-fpm` |
|
||||
| Anmeldung wirkt, danach sofort abgemeldet | Redis nicht erreichbar, oder `SESSION_COOKIE_SECURE=true` ohne TLS |
|
||||
| Listen bleiben leer, Meldung „nicht erreichbar" | `N8N_PUBLIC_BASE` falsch, oder der Webhook ist in n8n nicht aktiv |
|
||||
| Angezeigte Daten sind veraltet | Rückfall-Cache greift, weil n8n gerade nicht antwortet |
|
||||
| 503 „noch nicht eingerichtet" | `N8N_INVOICE_SYNC_SECRET` bzw. `N8N_CUSTOMER_KEY` fehlt in `.env` |
|
||||
| Quelltextänderung wirkt nicht | Opcache; `systemctl reload php8.5-fpm` |
|
||||
| Symptom | meistens |
|
||||
| ----------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| 502 auf `/api/` | Socket fehlt oder falsche Rechte; `systemctl status php8.5-fpm` |
|
||||
| 403 auf `/api/`, im Fehlerlog „Permission denied" | setgid fehlt, php-fpm kommt nicht an die neue Veröffentlichung |
|
||||
| Anmeldung wirkt, danach sofort abgemeldet | Redis nicht erreichbar, oder `SESSION_COOKIE_SECURE=true` ohne TLS |
|
||||
| Listen leer, „n8n nicht erreichbar" | `N8N_PUBLIC_BASE` falsch, oder der Webhook ist in n8n nicht aktiv |
|
||||
| Angezeigte Daten sind veraltet | Rückfall-Cache greift, weil n8n gerade nicht antwortet |
|
||||
| 503 „noch nicht eingerichtet" | `N8N_INVOICE_SYNC_SECRET` bzw. `N8N_CUSTOMER_KEY` fehlt in `.env` |
|
||||
| Quelltextänderung wirkt nicht | Opcache; `sudo systemctl reload php8.5-fpm` |
|
||||
| Ausrollen bricht bei „composer install" ab | Erweiterung fehlt; `composer check-platform-reqs` auf dem Server |
|
||||
|
||||
## Alle Benutzer aussperren
|
||||
|
||||
|
||||
+38
@@ -107,3 +107,41 @@ Interne Aufgaben kennen in n8n genau zwei Empfänger: `sascha` und `svenja`. Ein
|
||||
drittes EK-DOS-Konto kann sich anmelden und alle Ansichten nutzen, aber noch
|
||||
keine Aufgaben zugewiesen bekommen. Dafür müsste der n8n-Workflow *Interne
|
||||
Aufgaben* einen freien Empfängerschlüssel annehmen.
|
||||
|
||||
## Wo die Dateien tatsächlich liegen
|
||||
|
||||
EK-DOS-WEB liest **keine einzige Datei**. Weder die Next.js-Fassung noch das
|
||||
PHP-Backend enthalten einen Dateisystemzugriff; der alte Container hatte auch
|
||||
keinen Mount. Es gibt auch keinen PDF-Renderer: nichts wird erzeugt, nur
|
||||
weitergereicht.
|
||||
|
||||
Alle Dokumente kommen als HTTP-Antwort aus n8n:
|
||||
|
||||
| Route | n8n liefert | EK-DOS-WEB tut |
|
||||
| --------------------------------- | ---------------------- | ---------------------------- |
|
||||
| `/api/tickets/digitale-akte` | PDF-Bytes | durchreichen |
|
||||
| `/api/tickets/servicebericht` | PDF-Bytes | durchreichen |
|
||||
| `/api/customers/digitale-akte` | PDF-Bytes | durchreichen |
|
||||
| `/api/customer-invoices/pdf` | PDF-Bytes | Pfad prüfen, durchreichen |
|
||||
| `/api/invoices-create/digitale-akte` | base64 im JSON | dekodieren, durchreichen |
|
||||
| `/api/hours` | JSON-Report | Felder abbilden |
|
||||
|
||||
Der Mount `/mnt/n8n-nas` gehört zum **n8n-Container**, nicht zu dieser
|
||||
Anwendung. Dort wird die Datei gelesen; EK-DOS-WEB fragt nur über HTTP danach.
|
||||
Für den Webserver heisst das: er braucht keinen NAS-Zugang, keine SMB-Zugangs-
|
||||
daten und keinen Mount. Ein Umzug des Webservers auf eine andere Maschine
|
||||
berührt die Dateiablage nicht.
|
||||
|
||||
Zwei Dinge, die häufig hierher vermutet werden, aber nicht hier liegen:
|
||||
|
||||
- **Stundennachweise** sind kein Dokument. `/api/hours` liefert einen JSON-Report,
|
||||
den n8n aus mehreren Quellen zusammensetzt. Es wird keine Datei gelesen.
|
||||
- **Tageszusammenfassung und Tagesübersicht** kommen in der Anwendung nicht vor.
|
||||
„Tageszusammenfassung" ist die Beschriftung von Workflow 9/13 im Schulungs-
|
||||
diagramm; „TAGESÜBERSICHT" ist die Überschrift über der Begrüssung auf der
|
||||
Startseite. Keines von beidem lädt Daten.
|
||||
|
||||
**Zeitgesteuerte Abläufe (Druckaufträge, morgendliche Berichte) gibt es in
|
||||
EK-DOS-WEB nicht.** Es existiert kein Zeitplaner, kein Cron-Eintrag und kein
|
||||
Druckcode -- weder alt noch neu. Solche Abläufe sind Schedule-Trigger in n8n und
|
||||
laufen unabhängig von dieser Anwendung weiter. Der Umbau auf PHP berührt sie nicht.
|
||||
|
||||
Reference in New Issue
Block a user