Migrate omsorgapp to browser SPA, add Docker/CI build setup
Docker-Images bauen und veröffentlichen / build (, omsorgCore/Dockerfile, omsorgcore) (push) Successful in 3s
Docker-Images bauen und veröffentlichen / build (, omsorgWeb/Dockerfile, omsorgweb) (push) Failing after 4s
Docker-Images bauen und veröffentlichen / build (VITE_OMSORG_CORE_URL=${{ vars.OMSORG_CORE_PUBLIC_URL }}, omsorgapp/Dockerfile, omsorgapp) (push) Successful in 3s

- omsorgapp: drop Electron, run as a plain Vite/React browser app; refresh
  token moves to an HttpOnly cookie (omsorgCore), CORS added for the new
  browser origin, document download/preview switched to Blob-based browser
  APIs.
- Add Dockerfiles for omsorgCore, omsorgapp, and omsorgWeb, a docker-compose.yml
  wiring Postgres/MySQL/all three apps together, and a Gitea Actions workflow
  that builds and pushes images to the repo's container registry on push to
  main and on version tags.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix Kemmler
2026-08-10 17:42:45 +02:00
co-authored by Claude Sonnet 5
parent e9e96a57dc
commit 598dfcd38a
461 changed files with 59753 additions and 2859 deletions
+7
View File
@@ -0,0 +1,7 @@
# Debians Standard-apache2.conf setzt AllowOverride None für /var/www/ - ohne diese Datei würden
# sämtliche .htaccess-Regeln der App (HTTPS-Redirect, Security-Header, Deny-All auf lib/uploads/...,
# Blockade von config.php/config.secret.php) stillschweigend ignoriert. Das wäre ein echtes
# Sicherheitsloch (config.secret.php wäre sonst direkt per HTTP abrufbar).
<Directory /var/www/html>
AllowOverride All
</Directory>
+80
View File
@@ -0,0 +1,80 @@
<?php
// Läuft beim Container-Start (siehe docker-entrypoint.sh), bevor Apache startet.
//
// lib/config.php ist bewusst NICHT im Git-Repo (Root-.gitignore: **/mitarbeiter-app*/lib/config.php)
// - ein frischer CI-Checkout hat die Datei also gar nicht. Dieses Skript legt beim Start eine
// Docker-taugliche Variante an, aber NUR falls noch keine vorhanden ist (z.B. weil eine echte
// config.php per Bind-Mount/Secret bereitgestellt wurde) - überschreibt nie eine vorhandene Datei.
// lib/config.secret.php wird IMMER aus den aktuellen Env-Vars neu geschrieben (enthält nur
// Geheimwerte, kein Grund es zu erhalten).
function envOrDefault(string $name, string $default = ''): string
{
$value = getenv($name);
return ($value !== false && $value !== '') ? $value : $default;
}
function writeIfMissing(string $path, string $contents): void
{
if (is_file($path)) {
return;
}
file_put_contents($path, $contents);
}
function writeSecret(string $path, array $data): void
{
$data = array_filter($data, static fn($value) => $value !== null && $value !== '');
if (empty($data)) {
// Kein Geheimwert gesetzt - config.php's array_merge() fällt einfach auf seine
// eigenen Defaults zurück (is_file()-Check dort).
if (is_file($path)) {
unlink($path);
}
return;
}
file_put_contents($path, "<?php\nreturn " . var_export($data, true) . ";\n");
}
// --- mitarbeiter-app-legacy (MySQL + SMTP) ---
$legacyDir = __DIR__ . '/../mitarbeiter-app-legacy/lib';
$dbDsn = sprintf(
'mysql:host=%s;dbname=%s;charset=utf8mb4',
envOrDefault('DB_HOST', 'mysql'),
envOrDefault('DB_NAME', 'omsorg_web')
);
writeIfMissing($legacyDir . '/config.php', "<?php\n"
. "// Docker-generierte Defaults (omsorgWeb/docker/bootstrap-config.php) - Geheimwerte kommen\n"
. "// aus config.secret.php, ebenfalls zur Laufzeit generiert.\n"
. "\$secret = is_file(__DIR__ . '/config.secret.php') ? (require __DIR__ . '/config.secret.php') : [];\n\n"
. "return array_merge([\n"
. " 'db_driver' => 'mysql',\n"
. " 'db_dsn' => " . var_export($dbDsn, true) . ",\n"
. " 'db_user' => '',\n"
. " 'db_password' => '',\n"
. " 'omsorg_core_url' => " . var_export(envOrDefault('OMSORG_CORE_URL', 'http://localhost:5245'), true) . ",\n"
. " 'mail_from' => " . var_export(envOrDefault('MAIL_FROM', 'no-reply@omsorg-pflegedienste.de'), true) . ",\n"
. " 'mail_info' => " . var_export(envOrDefault('MAIL_INFO', 'info@omsorg-pflegedienste.de'), true) . ",\n"
. " 'mail_sabrina' => " . var_export(envOrDefault('MAIL_SABRINA'), true) . ",\n"
. " 'smtp_host' => " . var_export(envOrDefault('SMTP_HOST'), true) . ",\n"
. " 'smtp_port' => " . (int) envOrDefault('SMTP_PORT', '587') . ",\n"
. " 'smtp_user' => " . var_export(envOrDefault('SMTP_USER'), true) . ",\n"
. " 'smtp_password' => '',\n"
. "], \$secret);\n");
writeSecret($legacyDir . '/config.secret.php', [
'db_user' => envOrDefault('DB_USER'),
'db_password' => envOrDefault('DB_PASSWORD'),
'smtp_password' => envOrDefault('SMTP_PASSWORD'),
]);
// --- mitarbeiter-app (Rewrite, kein MySQL, nur omsorgCore) ---
$newDir = __DIR__ . '/../mitarbeiter-app/lib';
writeIfMissing($newDir . '/config.php', "<?php\n"
. "// Docker-generierte Defaults (omsorgWeb/docker/bootstrap-config.php).\n"
. "\$secret = is_file(__DIR__ . '/config.secret.php') ? (require __DIR__ . '/config.secret.php') : [];\n\n"
. "return array_merge([\n"
. " 'omsorg_core_url' => " . var_export(envOrDefault('OMSORG_CORE_URL', 'http://localhost:5245'), true) . ",\n"
. "], \$secret);\n");
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
set -eu
php /var/www/html/docker/bootstrap-config.php
exec apache2-foreground