diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f1b833a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,228 @@ +name: CI Pipeline + +on: + push: + branches: + - main + - master + - 'feature/**' + - 'fix/**' + pull_request: + branches: + - main + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + static-analysis: + name: đ Static Analysis & Linting + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: ShellCheck CLI Script + uses: ludeeus/action-shellcheck@master + with: + scandir: '.' + env: + SHELLCHECK_OPTS: -e SC1091 + + - name: Validate Bash Syntax + run: bash -n zenv + + - name: Lint Dockerfile (Hadolint) + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: docker/Dockerfile + failure-threshold: error + ignore: DL3008,DL3015 + + - name: Validate Docker Compose Configuration + run: docker compose config --quiet + + - name: Setup PHP for Syntax Check + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: none + + - name: Validate PHP Syntax (Standalone Dashboard) + run: php -l public/index.php + + security: + name: đĄïž Security & Permissions Audit + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check Script Executable Permissions + run: | + if [ ! -x "./zenv" ]; then + echo "Error: ./zenv is not executable! Run chmod +x zenv" + exit 1 + fi + echo "./zenv executable permission verified" + + - name: Secret Leak Detection (TruffleHog) + uses: trufflesecurity/trufflehog@main + with: + extra_args: --only-verified + + docker-build: + name: đł Docker Build & Cache + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build zenv-app Image + uses: docker/build-push-action@v6 + with: + context: . + file: docker/Dockerfile + push: false + load: true + tags: zenv-app:test + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + UID=1000 + GID=1000 + + integration: + name: đ Integration & Health Checks + needs: [static-analysis, security, docker-build] + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Create .env from Example + run: cp .env.example .env + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Start zenv Stack + run: ./zenv up --build + + - name: Wait for Containers & Health Readiness + run: | + echo "Waiting for services to initialize..." + for i in {1..30}; do + STATUS=$(docker compose ps -q) + if [ -n "$STATUS" ]; then + echo "Containers running, waiting 5 seconds for services..." + sleep 5 + break + fi + sleep 1 + done + + - name: Verify Container Status + run: | + ./zenv ps + RUNNING=$(docker compose ps --services --filter "status=running" | wc -l) + echo "Running services: $RUNNING" + if [ "$RUNNING" -lt 5 ]; then + echo "Error: Less than expected services running!" + docker compose ps + docker compose logs + exit 1 + fi + + - name: Verify Nginx & Standalone Dashboard (HTTP 200) + run: | + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/) + echo "HTTP Status: $HTTP_STATUS" + if [ "$HTTP_STATUS" != "200" ]; then + echo "Error: Expected HTTP 200 from http://localhost/, got $HTTP_STATUS" + docker logs zenv-web + exit 1 + fi + curl -s http://localhost/ | grep -q "zenv Docker Environment" + echo "Dashboard rendered successfully" + + - name: Verify Mailpit Webmail UI + run: | + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8025/) + echo "Mailpit HTTP Status: $HTTP_STATUS" + if [ "$HTTP_STATUS" != "200" ]; then + echo "Error: Mailpit not responding on :8025" + exit 1 + fi + + - name: Verify MinIO S3 API + run: | + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9000/minio/health/live) + echo "MinIO Health Status: $HTTP_STATUS" + if [ "$HTTP_STATUS" != "200" ]; then + echo "Error: MinIO live healthcheck failed" + exit 1 + fi + + - name: Verify Redis Ping + run: | + docker compose exec -T redis redis-cli ping | grep -q "PONG" + echo "Redis PONG verified" + + - name: Verify PHP 8.4 Runtime & Core Extensions + run: | + ./zenv php -v | grep -q "PHP 8.4" + echo "PHP 8.4 verified" + ./zenv php -r " + \$extensions = ['pdo_mysql', 'redis', 'gd', 'intl', 'mbstring', 'zip', 'bcmath']; + foreach (\$extensions as \$ext) { + if (!extension_loaded(\$ext)) { + fwrite(STDERR, \"Missing extension: \$ext\\n\"); + exit(1); + } + } + if (!extension_loaded('Zend OPcache') && !extension_loaded('opcache')) { + fwrite(STDERR, \"Missing extension: opcache\\n\"); + exit(1); + } + echo 'All core extensions loaded successfully!\\n'; + " + + - name: Verify Tooling (Composer, Node.js, NPM) + run: | + ./zenv composer --version + ./zenv node -v + ./zenv npm -v + + - name: Verify Nginx Configuration Syntax inside Container + run: | + docker compose exec -T web nginx -t + + - name: Verify Queue Worker Stability (Package-Mode Sleep Check) + run: | + sleep 5 + STATUS=$(docker inspect --format='{{.State.Status}}' zenv-queue) + echo "zenv-queue status: $STATUS" + if [ "$STATUS" != "running" ]; then + echo "Error: zenv-queue is not running!" + docker logs zenv-queue + exit 1 + fi + docker logs zenv-queue | grep -q "Package mode" + echo "Package mode idle notice verified" + + - name: Teardown Environment + if: always() + run: | + ./zenv down -v diff --git a/.gitignore b/.gitignore index 2e7f973..ad6bcd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,173 @@ -/.phpunit.result.cache -/node_modules -/vendor +# ============================================================================== +# Enterprise .gitignore for zenv â Docker Environment & Laravel 13 / PHP 8.4+ +# ============================================================================== + +# ------------------------------------------------------------------------------ +# 1. Environment & Secrets (Strict Zero-Leak Policy) +# ------------------------------------------------------------------------------ .env +.env.* +!.env.example +!.env.ci +!.env.testing.example +auth.json +*.key +*.pem +*.crt +*.cert +*.pfx +*.p12 +*.rsa +*.pub +/storage/*.key +/storage/oauth-*.key + +# ------------------------------------------------------------------------------ +# 2. Dependencies & Package Managers +# ------------------------------------------------------------------------------ +/vendor/ +/node_modules/ +/npm-debug.log* +/yarn-error.log* +/yarn-debug.log* +/pnpm-debug.log* +.pnpm-store/ + +# ------------------------------------------------------------------------------ +# 3. Laravel Framework & Storage +# ------------------------------------------------------------------------------ +/storage/app/* +!/storage/app/.gitignore +!/storage/app/public/ +/storage/app/public/* +!/storage/app/public/.gitignore + +/storage/framework/cache/* +!/storage/framework/cache/.gitignore +!/storage/framework/cache/data/ +/storage/framework/cache/data/* +!/storage/framework/cache/data/.gitignore + +/storage/framework/sessions/* +!/storage/framework/sessions/.gitignore + +/storage/framework/testing/* +!/storage/framework/testing/.gitignore + +/storage/framework/views/* +!/storage/framework/views/.gitignore + +/storage/logs/* +!/storage/logs/.gitignore + +/storage/pail/ +/storage/clockwork/ +/storage/debugbar/ + +/bootstrap/cache/* +!/bootstrap/cache/.gitignore + +# ------------------------------------------------------------------------------ +# 4. Frontend & Build Artifacts (Vite / Livewire) +# ------------------------------------------------------------------------------ +/public/build/ +/public/hot +/public/storage +.vite/ +.turbo/ +.cache/ + +# ------------------------------------------------------------------------------ +# 5. Testing, Quality Assurance, Profiling & Mutation +# ------------------------------------------------------------------------------ +/.phpunit.cache/ +.phpunit.result.cache +/.pest/ +/coverage/ +*.coverage +/html-coverage/ +.php-cs-fixer.cache +.php_cs.cache +.phpbench/ +.phpactor.json +.phpstan.cache/ +/build/ +infection.log +infection-log.json +infection.summary.log + +# ------------------------------------------------------------------------------ +# 6. Docker, Local Database Dumps & SQLite +# ------------------------------------------------------------------------------ +docker-compose.override.yml +*.sql +*.sql.gz +*.dump +*.sqlite +*.sqlite-journal +*.sqlite-shm +*.sqlite-wal +/database/*.sqlite +/database/*.sqlite-journal +/database/*.sqlite-shm +/database/*.sqlite-wal + +# ------------------------------------------------------------------------------ +# 7. IDEs, Developer Tooling & AI Workspaces +# ------------------------------------------------------------------------------ +# PhpStorm / JetBrains +/.idea/ +*.iws +*.iml +*.ipr + +# VS Code +/.vscode/ +!.vscode/extensions.json +!.vscode/launch.json +!.vscode/tasks.json +!.vscode/settings.json + +# Other Editors (Fleet, Nova, Zed, Sublime, Vim) +/.fleet/ +/.nova/ +/.zed/ +*.sublime-project +*.sublime-workspace +*.swp +*.swo +*~ +.#* + +# Local AI / Scratch files +*.tmp +*.scratch +*.local + +# ------------------------------------------------------------------------------ +# 8. Operating System Artifacts +# ------------------------------------------------------------------------------ +# macOS +.DS_Store +.AppleDouble +.LSOverride +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Windows +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +desktop.ini +$RECYCLE.BIN/ + +# Linux +*~ +.fuse_hidden* +.directory diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e492679 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,105 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- **Enterprise GitHub Actions CI Pipeline**: Comprehensive CI/CD workflow (`.github/workflows/ci.yml`) featuring static analysis (ShellCheck, Bash syntax, Hadolint, Docker Compose validation, PHP syntax), security audit (TruffleHog secret scanning, file permissions), Docker layer caching (`type=gha`), and full-stack end-to-end integration smoke testing (HTTP 200 checks, Redis ping, PHP 8.4 runtime extension verification, and graceful teardown). +- **Standalone Environment Hub & Status Dashboard**: Added `public/index.php` to provide immediate feedback on `http://localhost/` when running `zenv` in standalone or package mode, featuring live healthchecks (PHP-FPM, Nginx, Redis, Mailpit, MinIO, MariaDB host gateway, and Queue status) and a 1-click CLI reference. +- **Enterprise `.gitignore` Configuration**: Comprehensive 8-section rule set covering strict zero-leak secret protection (`.env*`, private keys, certificates), granular Laravel 13 storage preservation, frontend/Vite artifacts, testing & profiling caches (PHPUnit, Pest, PHPStan, Infection), local database dumps/SQLite, and IDE/OS cleanup. +- **Package-Mode Support for Queue Worker**: The `zenv-queue` container dynamically detects whether an `artisan` CLI exists at the project root. When running in Composer package or plugin development contexts, the container logs an informative idle notice and sleeps quietly instead of crashing. + +### Changed + +- Enhanced `./zenv` CLI wrapper with dynamic TTY detection (`-t` only if interactive terminal is allocated) for smooth execution in non-interactive CI/CD environments and shell pipelines. +- Updated framework compatibility and alignment to **Laravel 13** & PHP 8.4+. +- Default Nginx host port changed from `8080` to `80` for direct `http://localhost` access. +- Added Vite HMR Docker configuration (`host: '0.0.0.0'`, `hmr.host: 'localhost'`) to `vite.config.js`. +- Configured Nginx FastCGI buffer sizes (`fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k;`) to prevent HTTP 502 "upstream sent too big header" errors with heavy Filament / Livewire payloads. + +### Fixed + +- Resolved `zenv-queue` container crash and restart loop (`Restarting (1)`) caused by `Could not open input file: artisan` in repositories without a full Laravel skeleton. + +## [1.0.0] - 2026-09-05 + +### Added + +#### Container Architecture + +- **PHP 8.4-FPM Application Container** (`zenv-app`) + with Composer, Node.js 22 LTS, NPM, and PHP CodeSniffer pre-installed. +- **Nginx Reverse Proxy** (`zenv-web`) with optimized `fastcgi_pass` + configuration and Laravel-friendly `try_files` routing. +- **Redis** (`zenv-redis`) for cache, sessions, and queue driver. +- **Mailpit** (`zenv-mailpit`) as local SMTP sandbox with web UI (port 8025). +- **MinIO** (`zenv-minio`) as local S3-compatible object storage with + web console (port 9001). +- **Queue Worker** (`zenv-queue`) running `artisan queue:work` with + `--tries=3 --timeout=90` and auto-restart via `unless-stopped`. +- **Dedicated Docker network** (`zenv-network`, bridge driver) for + inter-container communication. +- **Persistent volumes** for Redis data and MinIO storage. + +#### PHP Extensions + +- `pdo_mysql`, `mbstring`, `zip`, `exif`, `pcntl`, `bcmath`, `gd` + (FreeType + JPEG), `intl`, `opcache`, `redis` (PECL). + +#### UID/GID Resolution + +- Dynamic user creation in Dockerfile matching host `UID`/`GID` to + eliminate file permission conflicts across macOS, Linux, and WSL2. +- Automatic `USER_UID` and `USER_GID` export in CLI script. + +#### Host Database Persistence (Zero Data Loss) + +- Database connectivity via `host.docker.internal:host-gateway` to the + developer's local MariaDB/MySQL instance. +- Container destruction never causes data loss â the database lives + on the host system. + +#### `./zenv` CLI + +- `up` / `down` / `stop` / `restart` / `ps` / `logs` â container lifecycle. +- `artisan` â execute `php artisan` inside the app container. +- `composer` â execute Composer inside the app container. +- `npm` / `npx` â execute Node.js tooling inside the app container. +- `php` â execute arbitrary PHP commands. +- `pest` / `test` â run Pest PHP test suite. +- `mariadb` / `mysql` â open interactive MariaDB console on host. +- `shell` â open Bash session in the app container. +- `init` â initialize a fresh Laravel project. +- `help` â display usage information. +- Automatic Docker Compose version detection (`docker compose` vs. + `docker-compose`). + +#### Configuration + +- `.env.example` with pre-configured `host.docker.internal` database host, + Redis cache/queue/session drivers, Mailpit SMTP, and MinIO S3 credentials. +- `docker/nginx.conf` with security headers (`X-Frame-Options`, + `X-Content-Type-Options`), hidden dotfile protection, and + `fastcgi_hide_header X-Powered-By`. + +#### Documentation + +- `README.md` with Mermaid architecture diagram, service port matrix, + 3-step quickstart guide, CLI cheatsheet, and database persistence + documentation. + +### Security + +- `X-Frame-Options: SAMEORIGIN` and `X-Content-Type-Options: nosniff` + headers set by default in Nginx. +- Dotfile access (`/.`) denied globally except `.well-known`. +- `X-Powered-By` header stripped from PHP responses. +- Non-root container user for PHP-FPM process execution. + +[Unreleased]: https://github.com/allgorithm/zenv/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/allgorithm/zenv/releases/tag/v1.0.0 diff --git a/README.md b/README.md index b94aff8..af3001c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # âĄïž zenv â Enterprise Zero-Config Docker Environment [](https://php.net) -[](https://laravel.com) +[](https://laravel.com) [](https://filamentphp.com) [](https://livewire.laravel.com) [](https://vitejs.dev) [](https://www.docker.com) +[](.github/workflows/ci.yml) [](LICENSE) -**zenv** (Zero-Config Environment) ist ein hochperformantes, professionelles Docker-Entwicklungsfundament fĂŒr moderne **Laravel 12** Enterprise-Anwendungen. Es eliminiert langsame Mounts, Dateirechte-Konflikte (UID/GID) und komplexe Setup-Skripte. +**zenv** (Zero-Config Environment) ist ein hochperformantes, professionelles Docker-Entwicklungsfundament fĂŒr moderne **Laravel 13** Enterprise-Anwendungen. Es eliminiert langsame Mounts, Dateirechte-Konflikte (UID/GID) und komplexe Setup-Skripte. --- @@ -21,7 +22,7 @@ graph TD Client -->|Webmail :8025| Mailpit[zenv-mailpit: Mail Sandbox] Client -->|S3 Console :9001| MinIO[zenv-minio: S3 Storage] - Nginx -->|FastCGI| App[zenv-app: PHP 8.4-FPM / Laravel 12] + Nginx -->|FastCGI| App[zenv-app: PHP 8.4-FPM / Laravel 13] App -->|Redis Protocol :6379| Redis[zenv-redis: Cache / Queue] App -->|Host Gateway| HostDB[(Host MariaDB / Persistent DB)] Queue[zenv-queue: Queue Worker] -->|Jobs| Redis @@ -38,7 +39,7 @@ graph TD | **Mailpit Sandbox** | `zenv-mailpit` | `1025` / `8025` | `8025` | **[http://localhost:8025](http://localhost:8025)** (E-Mail UI) | | **MinIO S3 Storage** | `zenv-minio` | `9000` / `9001` | `9001` | **[http://localhost:9001](http://localhost:9001)** (AWS S3 Emulator) | | **Redis Cache** | `zenv-redis` | `6379` | `6379` | High-Speed Cache & Session Store | -| **Queue Worker** | `zenv-queue` | - | - | Auto-executing `artisan queue:work` | +| **Queue Worker** | `zenv-queue` | - | - | Auto-executing `artisan queue:work` (idles gracefully in Package Mode) | | **Host MariaDB** | *Host System* | `3306` | `3306` | Persistent DB via `host.docker.internal` | --- diff --git a/docker-compose.yml b/docker-compose.yml index daaf8b5..2e572ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: container_name: zenv-web restart: unless-stopped ports: - - "8080:80" + - "80:80" volumes: - .:/var/www/html - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf @@ -83,7 +83,16 @@ services: dockerfile: docker/Dockerfile container_name: zenv-queue restart: unless-stopped - command: php artisan queue:work --verbose --tries=3 --timeout=90 + command: + - sh + - -c + - | + if [ -f artisan ]; then + php artisan queue:work --verbose --tries=3 --timeout=90 + else + echo "Package mode - no artisan found. Queue worker idle." + exec sleep infinity + fi volumes: - .:/var/www/html depends_on: diff --git a/docker/nginx.conf b/docker/nginx.conf index 3837139..6e93e75 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -25,6 +25,9 @@ server { fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; fastcgi_hide_header X-Powered-By; + fastcgi_buffer_size 128k; + fastcgi_buffers 4 256k; + fastcgi_busy_buffers_size 256k; } location ~ /\.(?!well-known).* { diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..0e9e7e2 --- /dev/null +++ b/public/index.php @@ -0,0 +1,756 @@ + true, 'latency' => $latency, 'message' => "Erreichbar ({$latency} ms)"]; + } + return ['status' => false, 'latency' => null, 'message' => 'Nicht erreichbar']; +} + +// Service Checks +$services = []; + +// 1. PHP-FPM +$services['php'] = [ + 'name' => 'PHP 8.4-FPM', + 'status' => true, + 'tag' => 'v' . PHP_VERSION, + 'detail' => 'SAPI: ' . php_sapi_name() . ' | Memory: ' . ini_get('memory_limit'), + 'icon' => 'php', + 'badge' => 'Aktiv', + 'type' => 'runtime' +]; + +// 2. Nginx +$services['nginx'] = [ + 'name' => 'Nginx Webserver', + 'status' => true, + 'tag' => 'Port 80', + 'detail' => $_SERVER['SERVER_SOFTWARE'] ?? 'Nginx Alpine', + 'icon' => 'server', + 'badge' => 'Online', + 'type' => 'web' +]; + +// 3. Redis +$redisStatus = ['status' => false, 'message' => 'Extension fehlt']; +if (extension_loaded('redis')) { + try { + $redis = new Redis(); + $connected = @$redis->connect('redis', 6379, 0.5); + if ($connected && @$redis->ping()) { + $redisStatus = ['status' => true, 'message' => 'Verbunden (PONG) :6379']; + } else { + $redisStatus = ['status' => false, 'message' => 'Keine Verbindung zu redis:6379']; + } + } catch (\Throwable $e) { + $redisStatus = ['status' => false, 'message' => $e->getMessage()]; + } +} +$services['redis'] = [ + 'name' => 'Redis Cache / Queue', + 'status' => $redisStatus['status'], + 'tag' => 'Port 6379', + 'detail' => $redisStatus['message'], + 'icon' => 'database', + 'badge' => $redisStatus['status'] ? 'Verbunden' : 'Fehler', + 'type' => 'cache' +]; + +// 4. Mailpit +$mailpitHttp = checkSocket('mailpit', 8025, 0.5); +$services['mailpit'] = [ + 'name' => 'Mailpit Sandbox', + 'status' => $mailpitHttp['status'], + 'tag' => 'Port 1025 / 8025', + 'detail' => $mailpitHttp['status'] ? 'Webmail UI bereit' : 'Nicht erreichbar', + 'icon' => 'mail', + 'badge' => $mailpitHttp['status'] ? 'Bereit' : 'Offline', + 'url' => 'http://localhost:8025', + 'url_label' => 'Webmail UI öffnen', + 'type' => 'tool' +]; + +// 5. MinIO S3 +$minioHttp = checkSocket('minio', 9000, 0.5); +$services['minio'] = [ + 'name' => 'MinIO S3 Storage', + 'status' => $minioHttp['status'], + 'tag' => 'Port 9000 / 9001', + 'detail' => 'User: minioadmin | Pass: minioadmin', + 'icon' => 'cloud', + 'badge' => $minioHttp['status'] ? 'Bereit' : 'Offline', + 'url' => 'http://localhost:9001', + 'url_label' => 'S3 Console öffnen', + 'type' => 'storage' +]; + +// 6. Queue Worker +$hasArtisan = file_exists(__DIR__ . '/../artisan'); +$services['queue'] = [ + 'name' => 'Queue Worker (zenv-queue)', + 'status' => true, + 'tag' => $hasArtisan ? 'App-Modus' : 'Package-Modus', + 'detail' => $hasArtisan ? 'Artisan Queue Worker aktiv' : 'Ruhezustand (keine artisan-Datei)', + 'icon' => 'cpu', + 'badge' => $hasArtisan ? 'Worker aktiv' : 'Pausiert (Idle)', + 'type' => 'worker' +]; + +// 7. MariaDB Host Gateway +$dbCheck = checkSocket('host.docker.internal', 3306, 0.5); +$services['mariadb'] = [ + 'name' => 'MariaDB (Host-Gateway)', + 'status' => $dbCheck['status'], + 'tag' => 'host.docker.internal:3306', + 'detail' => $dbCheck['status'] ? 'Host MariaDB antwortet (' . $dbCheck['latency'] . ' ms)' : 'Host-Port 3306 nicht erreichbar', + 'icon' => 'hard-drive', + 'badge' => $dbCheck['status'] ? 'Verbunden' : 'Host Offline', + 'type' => 'db' +]; +?> + + +
+ + +Hochperformantes, isoliertes Docker-Entwicklungsfundament fĂŒr Laravel 13 & moderne PHP 8.4+ Enterprise-Projekte.
+