fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled

- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Display\ValueObjects\DisplayOptions;
/**
* Formatter for Byte Value Objects with human-readable formatting
*/
final readonly class ByteFormatter implements ValueObjectFormatterInterface
{
public function supports(object $valueObject): bool
{
return $valueObject instanceof Byte;
}
public function formatConsole(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Byte) {
return (string) $valueObject;
}
$humanReadable = $valueObject->toHumanReadable(2);
$bytes = $valueObject->toBytes();
// Color-code by size range
$color = match (true) {
$bytes < 1024 => ConsoleColor::WHITE, // Bytes
$bytes < 1024 * 1024 => ConsoleColor::GREEN, // KB
$bytes < 1024 * 1024 * 1024 => ConsoleColor::YELLOW, // MB
$bytes < 1024 * 1024 * 1024 * 1024 => ConsoleColor::BRIGHT_YELLOW, // GB
default => ConsoleColor::BRIGHT_RED, // TB+
};
return ConsoleStyle::create(color: $color)->apply($humanReadable);
}
public function formatHtml(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Byte) {
return htmlspecialchars((string) $valueObject);
}
$humanReadable = $valueObject->toHumanReadable(2);
$bytes = $valueObject->toBytes();
// CSS class based on size range
$cssClass = match (true) {
$bytes < 1024 => 'display-byte-size',
$bytes < 1024 * 1024 => 'display-kb-size',
$bytes < 1024 * 1024 * 1024 => 'display-mb-size',
$bytes < 1024 * 1024 * 1024 * 1024 => 'display-gb-size',
default => 'display-tb-size',
};
return '<span class="' . $cssClass . '">' . htmlspecialchars($humanReadable) . '</span>';
}
}

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Display\ValueObjects\DisplayOptions;
/**
* Formatter for ClassName Value Objects with namespace highlighting
*/
final readonly class ClassNameFormatter implements ValueObjectFormatterInterface
{
public function supports(object $valueObject): bool
{
return $valueObject instanceof ClassName;
}
public function formatConsole(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof ClassName) {
return (string) $valueObject;
}
$namespace = $valueObject->getNamespace();
$shortName = $valueObject->getShortName();
if ($namespace === '') {
// Global namespace - just show class name
return ConsoleStyle::create(color: ConsoleColor::BRIGHT_CYAN)->apply($shortName);
}
// Namespace in gray, class name highlighted
$namespaceStyle = ConsoleStyle::create(color: ConsoleColor::GRAY);
$classNameStyle = ConsoleStyle::create(color: ConsoleColor::BRIGHT_CYAN);
return $namespaceStyle->apply($namespace . '\\') . $classNameStyle->apply($shortName);
}
public function formatHtml(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof ClassName) {
return htmlspecialchars((string) $valueObject);
}
$namespace = $valueObject->getNamespace();
$shortName = $valueObject->getShortName();
if ($namespace === '') {
return '<span class="display-class-name">' . htmlspecialchars($shortName) . '</span>';
}
return '<span class="display-namespace">' . htmlspecialchars($namespace . '\\') . '</span>' .
'<span class="display-class-name">' . htmlspecialchars($shortName) . '</span>';
}
}

View File

@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Display\ValueObjects\DisplayOptions;
use Stringable;
/**
* Formatter for email-like strings (Value Objects that represent emails)
*/
final readonly class EmailFormatter implements ValueObjectFormatterInterface
{
public function supports(object $valueObject): bool
{
// Check if it's a Stringable that looks like an email
if (! $valueObject instanceof Stringable) {
return false;
}
$stringValue = (string) $valueObject;
// Simple email validation
return filter_var($stringValue, FILTER_VALIDATE_EMAIL) !== false;
}
public function formatConsole(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Stringable) {
return (string) $valueObject;
}
$email = (string) $valueObject;
$parts = explode('@', $email, 2);
if (count($parts) !== 2) {
return (string) $valueObject;
}
[$localPart, $domain] = $parts;
$localStyle = ConsoleStyle::create(color: ConsoleColor::BRIGHT_CYAN);
$atStyle = ConsoleStyle::create(color: ConsoleColor::GRAY);
$domainStyle = ConsoleStyle::create(color: ConsoleColor::WHITE);
return $localStyle->apply($localPart) . $atStyle->apply('@') . $domainStyle->apply($domain);
}
public function formatHtml(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Stringable) {
return htmlspecialchars((string) $valueObject);
}
$email = (string) $valueObject;
$parts = explode('@', $email, 2);
if (count($parts) !== 2) {
return htmlspecialchars((string) $valueObject);
}
[$localPart, $domain] = $parts;
return '<span class="display-email-local">' . htmlspecialchars($localPart) . '</span>' .
'<span class="display-email-at">@</span>' .
'<span class="display-email-domain">' . htmlspecialchars($domain) . '</span>';
}
}

View File

@@ -0,0 +1,98 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Display\ValueObjects\DisplayOptions;
use App\Framework\Filesystem\ValueObjects\FilePath;
/**
* Formatter for FilePath Value Objects with path highlighting
*/
final readonly class FilePathFormatter implements ValueObjectFormatterInterface
{
public function supports(object $valueObject): bool
{
return $valueObject instanceof FilePath;
}
public function formatConsole(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof FilePath) {
return (string) $valueObject;
}
$path = $valueObject->toString();
$directory = $valueObject->getDirectory();
$filename = $valueObject->getFilename();
$extension = $valueObject->getExtension();
if ($directory === '') {
// Just filename
if ($extension !== '') {
$basename = substr($filename, 0, -strlen($extension) - 1);
$fileStyle = ConsoleStyle::create(color: ConsoleColor::WHITE);
$extStyle = ConsoleStyle::create(color: ConsoleColor::CYAN);
return $fileStyle->apply($basename) . $extStyle->apply('.' . $extension);
}
return ConsoleStyle::create(color: ConsoleColor::WHITE)->apply($filename);
}
// Directory in gray, filename highlighted, extension in cyan
$dirStyle = ConsoleStyle::create(color: ConsoleColor::GRAY);
$fileStyle = ConsoleStyle::create(color: ConsoleColor::WHITE);
$extStyle = ConsoleStyle::create(color: ConsoleColor::CYAN);
$output = $dirStyle->apply($directory . DIRECTORY_SEPARATOR);
if ($extension !== '') {
$basename = substr($filename, 0, -strlen($extension) - 1);
$output .= $fileStyle->apply($basename) . $extStyle->apply('.' . $extension);
} else {
$output .= $fileStyle->apply($filename);
}
return $output;
}
public function formatHtml(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof FilePath) {
return htmlspecialchars((string) $valueObject);
}
$path = $valueObject->toString();
$directory = $valueObject->getDirectory();
$filename = $valueObject->getFilename();
$extension = $valueObject->getExtension();
if ($directory === '') {
if ($extension !== '') {
$basename = substr($filename, 0, -strlen($extension) - 1);
return '<span class="display-filename">' . htmlspecialchars($basename) . '</span>' .
'<span class="display-extension">.' . htmlspecialchars($extension) . '</span>';
}
return '<span class="display-filename">' . htmlspecialchars($filename) . '</span>';
}
$output = '<span class="display-directory-path">' . htmlspecialchars($directory . DIRECTORY_SEPARATOR) . '</span>';
if ($extension !== '') {
$basename = substr($filename, 0, -strlen($extension) - 1);
$output .= '<span class="display-filename">' . htmlspecialchars($basename) . '</span>' .
'<span class="display-extension">.' . htmlspecialchars($extension) . '</span>';
} else {
$output .= '<span class="display-filename">' . htmlspecialchars($filename) . '</span>';
}
return $output;
}
}

View File

@@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Display\ValueObjects\DisplayOptions;
/**
* Formatter for Timestamp Value Objects with formatted date/time
*/
final readonly class TimestampFormatter implements ValueObjectFormatterInterface
{
public function supports(object $valueObject): bool
{
return $valueObject instanceof Timestamp;
}
public function formatConsole(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Timestamp) {
return (string) $valueObject;
}
$formatted = $valueObject->format('Y-m-d H:i:s');
$now = time();
$diff = abs($valueObject->toTimestamp() - $now);
// Color-code by recency
$color = match (true) {
$diff < 60 => ConsoleColor::GREEN, // Less than 1 minute
$diff < 3600 => ConsoleColor::YELLOW, // Less than 1 hour
$diff < 86400 => ConsoleColor::BRIGHT_YELLOW, // Less than 1 day
$diff < 604800 => ConsoleColor::WHITE, // Less than 1 week
default => ConsoleColor::GRAY, // Older
};
$relative = $this->getRelativeTime($valueObject->toTimestamp(), $now);
return ConsoleStyle::create(color: $color)->apply($formatted) .
' ' . ConsoleStyle::create(color: ConsoleColor::GRAY)->apply('(' . $relative . ')');
}
public function formatHtml(object $valueObject, DisplayOptions $options): string
{
if (! $valueObject instanceof Timestamp) {
return htmlspecialchars((string) $valueObject);
}
$formatted = $valueObject->format('Y-m-d H:i:s');
$now = time();
$diff = abs($valueObject->toTimestamp() - $now);
// CSS class based on recency
$cssClass = match (true) {
$diff < 60 => 'display-timestamp-recent',
$diff < 3600 => 'display-timestamp-hour',
$diff < 86400 => 'display-timestamp-day',
$diff < 604800 => 'display-timestamp-week',
default => 'display-timestamp-old',
};
$relative = $this->getRelativeTime($valueObject->toTimestamp(), $now);
return '<span class="' . $cssClass . '">' . htmlspecialchars($formatted) . '</span>' .
' <span class="display-timestamp-relative">(' . htmlspecialchars($relative) . ')</span>';
}
private function getRelativeTime(int $timestamp, int $now): string
{
$diff = $now - $timestamp;
if ($diff < 0) {
$diff = abs($diff);
$future = true;
} else {
$future = false;
}
return match (true) {
$diff < 60 => $future ? 'in ' . $diff . 's' : $diff . 's ago',
$diff < 3600 => $future ? 'in ' . (int) ($diff / 60) . 'm' : (int) ($diff / 60) . 'm ago',
$diff < 86400 => $future ? 'in ' . (int) ($diff / 3600) . 'h' : (int) ($diff / 3600) . 'h ago',
$diff < 604800 => $future ? 'in ' . (int) ($diff / 86400) . 'd' : (int) ($diff / 86400) . 'd ago',
$diff < 2592000 => $future ? 'in ' . (int) ($diff / 604800) . 'w' : (int) ($diff / 604800) . 'w ago',
default => $future ? 'in the future' : 'long ago',
};
}
}

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace App\Framework\Display\ValueObjectFormatters;
use App\Framework\Display\ValueObjects\DisplayOptions;
/**
* Interface for custom Value Object formatters
*/
interface ValueObjectFormatterInterface
{
/**
* Check if this formatter supports the given Value Object
*/
public function supports(object $valueObject): bool;
/**
* Format Value Object for console output
*/
public function formatConsole(object $valueObject, DisplayOptions $options): string;
/**
* Format Value Object for HTML output
*/
public function formatHtml(object $valueObject, DisplayOptions $options): string;
}