Compare commits
8 Commits
0706f1f6a5
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4082a362a1 | |||
| c650d99bd4 | |||
| e61a0d8867 | |||
| 89f29d60c0 | |||
| ec139f9844 | |||
| f12fbaec94 | |||
| d3c07bbde3 | |||
| 1873d54a5d |
@@ -0,0 +1,33 @@
|
||||
# Abhängigkeiten
|
||||
/vendor/
|
||||
/node_modules/
|
||||
|
||||
# Symfony-Laufzeit
|
||||
/var/cache/
|
||||
/var/log/
|
||||
/var/sessions/
|
||||
|
||||
# Sensible Daten
|
||||
.env.local
|
||||
.env.local.php
|
||||
.env.*.local
|
||||
/config/secrets/
|
||||
|
||||
# Generierte Assets
|
||||
/public/bundles/
|
||||
/public/build/
|
||||
|
||||
# Logs
|
||||
/log/
|
||||
|
||||
# IDE & OS
|
||||
.idea/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Lock-Dateien (groß, wenig Mehrwert)
|
||||
composer.lock
|
||||
symfony.lock
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
@@ -0,0 +1,19 @@
|
||||
# Diese Datei enthält sichere Standardwerte für die Entwicklung.
|
||||
# Für lokale Überschreibungen: .env.local erstellen (wird nicht eingecheckt).
|
||||
|
||||
###> symfony/cache ###
|
||||
REDIS_URL=redis://localhost:6379
|
||||
###< symfony/cache ###
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_DEBUG=true
|
||||
APP_SECRET=
|
||||
APP_SHARE_DIR=var/share
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> symfony/routing ###
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
DEFAULT_URI=http://localhost
|
||||
###< symfony/routing ###
|
||||
+9
-15
@@ -1,15 +1,12 @@
|
||||
### Symfony ###
|
||||
/vendor/
|
||||
/var/
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.pem
|
||||
/public/bundles/
|
||||
/config/secrets/*.php
|
||||
/config/jwt/*.pem
|
||||
|
||||
### Symfony - Environment Dateien ###
|
||||
.env
|
||||
.env.local
|
||||
.env.local.php
|
||||
.env.*.local
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
### PHP ###
|
||||
.php_cs.cache
|
||||
@@ -18,10 +15,7 @@
|
||||
phpunit.xml
|
||||
composer.phar
|
||||
|
||||
### Junie ###
|
||||
.junie/
|
||||
|
||||
### Node / Frontend (usw.) ###
|
||||
### Node / Frontend ###
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
|
||||
Generated
+1
@@ -10,6 +10,7 @@
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.5" />
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
|
||||
Generated
+4
-1
@@ -1,7 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/var" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,92 +1,143 @@
|
||||
# Symfony Podman Template
|
||||
# Symfony Template
|
||||
|
||||
Dieses Projekt ist ein Template für die Symfony-Entwicklung unter Verwendung von Podman. Es bietet eine vollständig vorkonfigurierte Entwicklungsumgebung mit PHP-FPM, Nginx und PostgreSQL, die in einem gemeinsamen Pod ausgeführt werden.
|
||||
Symfony 7.2 Projekttemplate mit Podman-Containern für Entwicklung und Produktion.
|
||||
|
||||
## Features
|
||||
## Stack
|
||||
|
||||
- **Podman Integration**: Optimiert für die lokale Entwicklung in Containern ohne Docker-Zwang.
|
||||
- **Multi-Container Pod**:
|
||||
- `symfony-php`: PHP 8.5 FPM inklusive Symfony CLI und Composer.
|
||||
- `symfony-nginx`: Nginx Webserver, vorkonfiguriert für Symfony.
|
||||
- `symfony-db`: PostgreSQL 16 Datenbank.
|
||||
- **Automatisches Setup**: Ein zentrales Bash-Skript übernimmt die Initialisierung, Image-Erstellung und Container-Steuerung.
|
||||
- **Automatische Umgebungskonfiguration**: Erstellt oder aktualisiert die `.env` Datei mit den korrekten Datenbank-Zugangsdaten.
|
||||
| Komponente | Version |
|
||||
|------------|---------|
|
||||
| PHP-FPM | 8.4 |
|
||||
| Symfony | 8.1 |
|
||||
| Nginx | 1.27 |
|
||||
| Redis | 8 |
|
||||
|
||||
**Dev-Abhängigkeiten:** Symfony Profiler, MakerBundle, DebugBundle, VarDumper, Xdebug
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
Stellen Sie sicher, dass folgende Software auf Ihrem System installiert ist:
|
||||
- [Podman](https://podman.io/)
|
||||
- Bash (zum Ausführen des Setup-Skripts)
|
||||
- Openssl (wird vom Skript zur Generierung des `APP_SECRET` verwendet)
|
||||
- `openssl` (für Secret-Generierung)
|
||||
|
||||
## Installation & Setup
|
||||
## Entwicklungsumgebung
|
||||
|
||||
1. **Projekt vorbereiten**:
|
||||
Klonen Sie das Repository oder laden Sie die Dateien in Ihr Projektverzeichnis.
|
||||
|
||||
2. **Setup-Skript ausführen**:
|
||||
Das Skript `setup-pod.sh` automatisiert den gesamten Prozess:
|
||||
```bash
|
||||
chmod +x setup-pod.sh
|
||||
./setup-pod.sh
|
||||
```
|
||||
|
||||
Was das Skript tut:
|
||||
- Erstellt/aktualisiert die `.env` Datei.
|
||||
- Erstellt einen Pod namens `symfony-dev`.
|
||||
- Baut und startet die PHP- und Nginx-Container.
|
||||
- Startet eine PostgreSQL-Instanz.
|
||||
- Installiert Composer-Abhängigkeiten (falls eine `composer.json` vorhanden ist).
|
||||
- Erstellt die Datenbank und führt Migrationen aus.
|
||||
|
||||
3. **Anwendung aufrufen**:
|
||||
Sobald das Setup abgeschlossen ist, erreichen Sie die Anwendung unter:
|
||||
👉 **[http://localhost:8080](http://localhost:8080)**
|
||||
|
||||
## Datenbank-Details
|
||||
|
||||
Die Standard-Zugangsdaten (konfigurierbar im `setup-pod.sh`) sind:
|
||||
- **DB-Host**: `localhost` (da alle Container im selben Pod laufen)
|
||||
- **DB-Port**: `5432`
|
||||
- **User**: `symfony_user`
|
||||
- **Passwort**: `devpassword`
|
||||
- **Datenbank**: `symfony_db`
|
||||
|
||||
## Arbeiten mit der Umgebung
|
||||
|
||||
### Symfony & Composer Befehle
|
||||
Da PHP in einem Container läuft, müssen Befehle dort ausgeführt werden:
|
||||
```bash
|
||||
# Beispiel: Cache leeren
|
||||
podman exec -it symfony-php php bin/console cache:clear
|
||||
|
||||
# Beispiel: Neue Migration erstellen
|
||||
podman exec -it symfony-php php bin/console make:migration
|
||||
./setup-dev.sh
|
||||
```
|
||||
|
||||
### Logs einsehen
|
||||
Um die Ausgaben der verschiedenen Dienste zu verfolgen:
|
||||
```bash
|
||||
podman logs -f symfony-php
|
||||
podman logs -f symfony-nginx
|
||||
```
|
||||
Das Skript:
|
||||
1. Erstellt `.env.local` mit generiertem `APP_SECRET`
|
||||
2. Baut die Container-Images (`symfony-php`, `symfony-nginx`)
|
||||
3. Startet den Pod `symfony-dev` mit PHP-FPM, Nginx und Redis
|
||||
4. Führt `composer install` aus
|
||||
|
||||
**App:** http://localhost:8080
|
||||
|
||||
### Umgebung verwalten
|
||||
|
||||
### Umgebung stoppen und starten
|
||||
```bash
|
||||
# Pod stoppen
|
||||
# Stoppen / Starten
|
||||
podman pod stop symfony-dev
|
||||
|
||||
# Pod wieder starten
|
||||
podman pod start symfony-dev
|
||||
|
||||
# Entfernen
|
||||
podman pod stop symfony-dev && podman pod rm symfony-dev
|
||||
|
||||
# Neustart (rebuild)
|
||||
./setup-dev.sh
|
||||
```
|
||||
|
||||
### Im Container arbeiten
|
||||
|
||||
```bash
|
||||
# Shell öffnen
|
||||
podman exec -it symfony-php bash
|
||||
|
||||
# Symfony CLI
|
||||
podman exec -it symfony-php php bin/console <befehl>
|
||||
podman exec -it symfony-php php bin/console make:controller HomeController
|
||||
|
||||
# Composer
|
||||
podman exec -it symfony-php composer require <paket>
|
||||
```
|
||||
|
||||
### Xdebug
|
||||
|
||||
Xdebug ist im Dev-Container aktiv und wird per Trigger gestartet (kein automatischer Start).
|
||||
|
||||
| Einstellung | Wert |
|
||||
|-------------|----------------------------|
|
||||
| Modus | `debug` |
|
||||
| Port | `9003` |
|
||||
| Host | `host.containers.internal` |
|
||||
| Trigger | `XDEBUG_SESSION` (Cookie/Query-Parameter) |
|
||||
|
||||
## Produktions-Build
|
||||
|
||||
In der Live-Umgebung wird **nur der PHP-FPM-Container** benötigt. Das Produktions-Image enthält die gesamte App inkl. Vendor-Verzeichnis – kein Volume-Mount erforderlich.
|
||||
|
||||
```bash
|
||||
# Image bauen
|
||||
./build-prod.sh symfony-app 1.0.0
|
||||
|
||||
# Container starten
|
||||
podman run -d \
|
||||
--name symfony-app \
|
||||
-p 9000:9000 \
|
||||
-e APP_ENV=prod \
|
||||
-e APP_SECRET=$(openssl rand -hex 16) \
|
||||
-e REDIS_URL=redis://your-redis-host:6379 \
|
||||
symfony-app:1.0.0
|
||||
|
||||
# Cache warmup
|
||||
podman exec symfony-app php bin/console cache:warmup --env=prod
|
||||
```
|
||||
|
||||
Der Build verwendet einen **Multi-Stage-Build**:
|
||||
- **Stage 1:** Composer installiert nur Produktionsabhängigkeiten (`--no-dev --optimize-autoloader`)
|
||||
- **Stage 2:** Schlankes PHP-FPM Image mit optimiertem OPcache
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
- `config/`: Symfony Konfiguration.
|
||||
- `podman/`: Container-Definitionen (`Containerfile`) und Webserver-Konfiguration.
|
||||
- `public/`: Document Root für Nginx.
|
||||
- `src/`: PHP Quellcode.
|
||||
- `setup-pod.sh`: Das Herzstück der Automatisierung.
|
||||
```
|
||||
.
|
||||
├── build-prod.sh # Produktions-Image bauen
|
||||
├── setup-dev.sh # Entwicklungsumgebung starten
|
||||
├── composer.json
|
||||
├── public/
|
||||
│ └── index.php # Symfony-Einstiegspunkt
|
||||
├── src/
|
||||
│ └── Kernel.php
|
||||
├── config/
|
||||
│ ├── bundles.php
|
||||
│ ├── routes.yaml
|
||||
│ ├── services.yaml
|
||||
│ └── packages/
|
||||
│ ├── cache.yaml # Redis als Cache-Backend
|
||||
│ ├── framework.yaml
|
||||
│ └── routing.yaml
|
||||
└── podman/
|
||||
├── php/ # Entwicklungs-Container
|
||||
│ ├── Containerfile
|
||||
│ └── conf.d/dev.ini # Xdebug & Error-Reporting
|
||||
├── nginx/
|
||||
│ ├── Containerfile
|
||||
│ └── default.conf
|
||||
└── php-prod/ # Produktions-Container
|
||||
├── Containerfile
|
||||
└── conf.d/opcache.ini
|
||||
```
|
||||
|
||||
## Umgebungsvariablen
|
||||
|
||||
| Variable | Beschreibung | Standard |
|
||||
|--------------|--------------------------|----------------------------------|
|
||||
| `APP_ENV` | Symfony-Umgebung | `dev` |
|
||||
| `APP_DEBUG` | Debug-Modus | `true` |
|
||||
| `APP_SECRET` | Kryptografisches Secret | Wird in `.env.local` generiert |
|
||||
| `REDIS_URL` | Redis-Verbindungs-URL | `redis://localhost:6379` |
|
||||
|
||||
`.env` enthält sichere Standardwerte und wird eingecheckt. Lokale Überschreibungen in `.env.local` (nicht eingecheckt).
|
||||
|
||||
## Lizenz
|
||||
Dieses Projekt ist unter der im [LICENSE](LICENSE) File angegebenen Lizenz lizenziert.
|
||||
|
||||
GPL-3.0-only
|
||||
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Projektnamen aus composer.json lesen (Teil nach "/") und bereinigen
|
||||
PROJECT_NAME=$(grep -m1 '"name"' "$PROJECT_DIR/composer.json" \
|
||||
| sed 's/.*"[^/]*\/\([^"]*\)".*/\1/' \
|
||||
| tr '[:upper:]' '[:lower:]' \
|
||||
| sed 's/[^a-z0-9]/-/g')
|
||||
|
||||
IMAGE_NAME="${1:-$PROJECT_NAME}"
|
||||
IMAGE_TAG="${2:-latest}"
|
||||
|
||||
echo "Projekt: $PROJECT_NAME"
|
||||
echo "Baue Produktions-Image: $IMAGE_NAME:$IMAGE_TAG"
|
||||
echo ""
|
||||
|
||||
podman build \
|
||||
--tag "$IMAGE_NAME:$IMAGE_TAG" \
|
||||
--file podman/php-prod/Containerfile \
|
||||
"$PROJECT_DIR"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Build abgeschlossen: $IMAGE_NAME:$IMAGE_TAG"
|
||||
echo ""
|
||||
echo "Container starten:"
|
||||
echo ""
|
||||
echo " podman run -d \\"
|
||||
echo " --name $PROJECT_NAME \\"
|
||||
echo " -p 9000:9000 \\"
|
||||
echo " -e APP_ENV=prod \\"
|
||||
echo " -e APP_SECRET=\$(openssl rand -hex 16) \\"
|
||||
echo " -e REDIS_URL=redis://your-redis-host:6379 \\"
|
||||
echo " $IMAGE_NAME:$IMAGE_TAG"
|
||||
echo ""
|
||||
echo "Cache warmup nach dem Start:"
|
||||
echo " podman exec $PROJECT_NAME php bin/console cache:warmup --env=prod"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "app/symfony",
|
||||
"description": "Symfony Application Template",
|
||||
"type": "project",
|
||||
"license": "GPL-3.0-only",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-redis": "*",
|
||||
"symfony/cache": "8.1.*",
|
||||
"symfony/console": "8.1.*",
|
||||
"symfony/dotenv": "8.1.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/framework-bundle": "8.1.*",
|
||||
"symfony/runtime": "8.1.*",
|
||||
"symfony/yaml": "8.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/debug-bundle": "8.1.*",
|
||||
"symfony/maker-bundle": "^1.67",
|
||||
"symfony/stopwatch": "8.1.*",
|
||||
"symfony/var-dumper": "8.1.*",
|
||||
"symfony/web-profiler-bundle": "8.1.*"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"php-http/discovery": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "8.1.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
];
|
||||
@@ -0,0 +1,9 @@
|
||||
framework:
|
||||
cache:
|
||||
app: cache.adapter.redis
|
||||
default_redis_provider: '%env(REDIS_URL)%'
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
cache:
|
||||
app: cache.adapter.array
|
||||
@@ -0,0 +1,19 @@
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
http_method_override: false
|
||||
handle_all_throwables: true
|
||||
|
||||
session:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
@@ -0,0 +1,8 @@
|
||||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
||||
@@ -0,0 +1,5 @@
|
||||
controllers:
|
||||
resource:
|
||||
path: ../src/Controller/
|
||||
namespace: App\Controller
|
||||
type: attribute
|
||||
@@ -0,0 +1,8 @@
|
||||
when@dev:
|
||||
web_profiler_wdt:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'
|
||||
prefix: /_wdt
|
||||
|
||||
web_profiler_profiler:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.php'
|
||||
prefix: /_profiler
|
||||
@@ -0,0 +1,13 @@
|
||||
parameters:
|
||||
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
@@ -1,9 +1,7 @@
|
||||
FROM docker.io/library/nginx:1.31.1-alpine
|
||||
FROM docker.io/library/nginx:1.27-alpine
|
||||
|
||||
# Kopiere die Konfiguration
|
||||
COPY podman/nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Exponiere Port 80 (wird später im Pod gemappt)
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
@@ -3,16 +3,30 @@ server {
|
||||
server_name localhost;
|
||||
root /var/www/html/public;
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
index index.php;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php$is_args$args;
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_pass localhost:9000; # PHP-FPM im selben Pod
|
||||
fastcgi_pass localhost:9000;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
fastcgi_buffer_size 128k;
|
||||
fastcgi_buffers 4 256k;
|
||||
fastcgi_busy_buffers_size 256k;
|
||||
internal;
|
||||
}
|
||||
|
||||
@@ -20,6 +34,6 @@ server {
|
||||
return 404;
|
||||
}
|
||||
|
||||
error_log /var/log/nginx/project_error.log;
|
||||
error_log /var/log/nginx/project_error.log;
|
||||
access_log /var/log/nginx/project_access.log;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Stage 1: Composer-Abhängigkeiten installieren
|
||||
FROM docker.io/library/composer:2 AS composer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY composer.json composer.lock* ./
|
||||
|
||||
RUN composer install \
|
||||
--no-dev \
|
||||
--no-scripts \
|
||||
--no-interaction \
|
||||
--optimize-autoloader \
|
||||
--prefer-dist
|
||||
|
||||
# Stage 2: PHP-FPM Produktions-Runtime
|
||||
FROM docker.io/library/php:8.4-fpm AS runtime
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libzip-dev \
|
||||
libicu-dev \
|
||||
libsodium-dev \
|
||||
&& docker-php-ext-install \
|
||||
zip \
|
||||
intl \
|
||||
sodium \
|
||||
opcache \
|
||||
&& pecl install redis \
|
||||
&& docker-php-ext-enable redis \
|
||||
&& apt-get purge -y --auto-remove \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY podman/php-prod/conf.d/ /usr/local/etc/php/conf.d/
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# App-Dateien kopieren
|
||||
COPY --chown=www-data:www-data . .
|
||||
|
||||
# Produktions-Vendor aus Stage 1 überschreibt ggf. vorhandenes vendor/
|
||||
COPY --from=composer --chown=www-data:www-data /app/vendor ./vendor
|
||||
|
||||
# Entwicklungs-Artefakte entfernen und Verzeichnisse vorbereiten
|
||||
RUN rm -rf podman/ log/ .git/ .env.local .env.*.local \
|
||||
&& mkdir -p var/cache/prod var/log \
|
||||
&& chown -R www-data:www-data var
|
||||
|
||||
USER www-data
|
||||
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,9 @@
|
||||
; Produktions-OPcache-Konfiguration
|
||||
opcache.enable = 1
|
||||
opcache.memory_consumption = 256
|
||||
opcache.interned_strings_buffer = 16
|
||||
opcache.max_accelerated_files = 20000
|
||||
opcache.revalidate_freq = 0
|
||||
opcache.validate_timestamps = 0
|
||||
opcache.fast_shutdown = 1
|
||||
opcache.enable_cli = 0
|
||||
+22
-20
@@ -1,30 +1,32 @@
|
||||
FROM docker.io/library/php:8.5-fpm
|
||||
FROM docker.io/library/php:8.4-fpm
|
||||
|
||||
# Installiere System-Abhängigkeiten
|
||||
RUN apt-get update && apt-get install -y \
|
||||
# git \
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
curl \
|
||||
# libpng-dev \
|
||||
# libonig-dev \
|
||||
# libxml2-dev \
|
||||
# zip \
|
||||
# unzip \
|
||||
apt-transport-https \
|
||||
gnupg \
|
||||
# && docker-php-ext-install pdo pdo_pgsql mbstring exif pcntl bcmath gd \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | bash \
|
||||
unzip \
|
||||
libzip-dev \
|
||||
libicu-dev \
|
||||
libsodium-dev \
|
||||
&& docker-php-ext-install \
|
||||
zip \
|
||||
intl \
|
||||
sodium \
|
||||
opcache \
|
||||
&& pecl install redis xdebug \
|
||||
&& docker-php-ext-enable redis xdebug \
|
||||
&& apt-get purge -y --auto-remove \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Symfony CLI
|
||||
RUN curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | bash \
|
||||
&& apt-get install -y symfony-cli \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Installiere Composer
|
||||
COPY --from=docker.io/library/composer:2.10.0 /usr/bin/composer /usr/bin/composer
|
||||
COPY --from=docker.io/library/composer:2 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
COPY podman/php/conf.d/ /usr/local/etc/php/conf.d/
|
||||
|
||||
# Arbeitsverzeichnis
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Benutzer für Nicht-Root-Betrieb (optional, aber empfohlen)
|
||||
# Wir nutzen hier den Standard www-data User von PHP-FPM
|
||||
USER www-data
|
||||
|
||||
CMD ["php-fpm"]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
; Entwicklungs-PHP-Konfiguration
|
||||
display_errors = On
|
||||
display_startup_errors = On
|
||||
error_reporting = E_ALL
|
||||
log_errors = On
|
||||
|
||||
; Xdebug (Auslösung per XDEBUG_SESSION Cookie oder Query-Parameter)
|
||||
[xdebug]
|
||||
xdebug.mode = debug
|
||||
xdebug.client_host = host.containers.internal
|
||||
xdebug.client_port = 9003
|
||||
xdebug.start_with_request = trigger
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Projektnamen aus composer.json lesen (Teil nach "/") und bereinigen
|
||||
PROJECT_NAME=$(grep -m1 '"name"' "$PROJECT_DIR/composer.json" \
|
||||
| sed 's/.*"[^/]*\/\([^"]*\)".*/\1/' \
|
||||
| tr '[:upper:]' '[:lower:]' \
|
||||
| sed 's/[^a-z0-9]/-/g')
|
||||
|
||||
POD_NAME="${PROJECT_NAME}-dev"
|
||||
CTR_PHP="${PROJECT_NAME}-php"
|
||||
CTR_NGINX="${PROJECT_NAME}-nginx"
|
||||
CTR_REDIS="${PROJECT_NAME}-redis"
|
||||
IMG_PHP="${PROJECT_NAME}-php"
|
||||
IMG_NGINX="${PROJECT_NAME}-nginx"
|
||||
VOL_REDIS="${PROJECT_NAME}-redis-data"
|
||||
|
||||
echo "Projekt: $PROJECT_NAME"
|
||||
echo "Pod: $POD_NAME"
|
||||
echo ""
|
||||
|
||||
# .env.local erstellen falls nicht vorhanden
|
||||
if [ ! -f "$PROJECT_DIR/.env.local" ]; then
|
||||
echo "Erstelle .env.local mit generiertem APP_SECRET..."
|
||||
cat > "$PROJECT_DIR/.env.local" <<EOF
|
||||
APP_SECRET=$(openssl rand -hex 16)
|
||||
REDIS_URL=redis://localhost:6379
|
||||
EOF
|
||||
echo ".env.local erstellt"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Bestehenden Pod entfernen falls vorhanden
|
||||
if podman pod exists "$POD_NAME" 2>/dev/null; then
|
||||
echo "Entferne bestehenden Pod '$POD_NAME'..."
|
||||
podman pod stop "$POD_NAME" 2>/dev/null || true
|
||||
podman pod rm "$POD_NAME" 2>/dev/null || true
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Pod erstellen
|
||||
echo "Erstelle Pod '$POD_NAME' (Port 8080 -> 80)..."
|
||||
podman pod create --name "$POD_NAME" -p 8080:80
|
||||
echo ""
|
||||
|
||||
# PHP-FPM bauen und starten
|
||||
echo "Baue PHP-FPM Container (inkl. Xdebug, Redis-Extension)..."
|
||||
podman build -t "$IMG_PHP" -f podman/php/Containerfile "$PROJECT_DIR"
|
||||
|
||||
echo "Starte PHP-FPM..."
|
||||
podman run -d \
|
||||
--pod "$POD_NAME" \
|
||||
--name "$CTR_PHP" \
|
||||
-v "$PROJECT_DIR:/var/www/html:Z" \
|
||||
"$IMG_PHP"
|
||||
echo ""
|
||||
|
||||
# Nginx bauen und starten
|
||||
echo "Baue Nginx Container..."
|
||||
podman build -t "$IMG_NGINX" -f podman/nginx/Containerfile "$PROJECT_DIR"
|
||||
|
||||
echo "Starte Nginx..."
|
||||
podman run -d \
|
||||
--pod "$POD_NAME" \
|
||||
--name "$CTR_NGINX" \
|
||||
-v "$PROJECT_DIR:/var/www/html:Z" \
|
||||
"$IMG_NGINX"
|
||||
echo ""
|
||||
|
||||
# Redis starten
|
||||
echo "Starte Redis..."
|
||||
podman run -d \
|
||||
--pod "$POD_NAME" \
|
||||
--name "$CTR_REDIS" \
|
||||
-v "$VOL_REDIS:/data" \
|
||||
docker.io/library/redis:8-alpine \
|
||||
redis-server --appendonly yes
|
||||
echo ""
|
||||
|
||||
# Kurz warten bis Container bereit sind
|
||||
sleep 2
|
||||
|
||||
# Composer install
|
||||
if [ -f "$PROJECT_DIR/composer.json" ]; then
|
||||
echo "Installiere Composer-Abhängigkeiten..."
|
||||
podman exec "$CTR_PHP" composer install --no-interaction
|
||||
echo ""
|
||||
|
||||
echo "Leere Symfony Cache..."
|
||||
podman exec "$CTR_PHP" php bin/console cache:clear --env=dev
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Entwicklungsumgebung bereit!"
|
||||
echo ""
|
||||
echo " App: http://localhost:8080"
|
||||
echo " Redis: localhost:6379 (innerhalb des Pods)"
|
||||
echo ""
|
||||
echo "Nützliche Befehle:"
|
||||
echo " podman exec -it $CTR_PHP bash"
|
||||
echo " podman exec -it $CTR_PHP php bin/console <befehl>"
|
||||
echo " podman exec -it $CTR_PHP composer require <paket>"
|
||||
echo ""
|
||||
echo " podman pod stop $POD_NAME # Umgebung stoppen"
|
||||
echo " podman pod start $POD_NAME # Umgebung starten"
|
||||
echo " podman pod rm $POD_NAME # Umgebung entfernen"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Konfiguration
|
||||
POD_NAME="symfony-dev"
|
||||
PROJECT_DIR="$(pwd)"
|
||||
DB_PASSWORD="devpassword" # Ändere dies!
|
||||
DB_NAME="symfony_db"
|
||||
DB_USER="symfony_user"
|
||||
DB_HOST="localhost"
|
||||
DB_PORT="5432"
|
||||
|
||||
ENV_FILE="$PROJECT_DIR/.env"
|
||||
|
||||
echo "🚀 Starte Symfony Pod Setup..."
|
||||
|
||||
# 1. .env Datei automatisch erstellen/aktualisieren
|
||||
echo "📝 Konfiguriere .env Datei..."
|
||||
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?serverVersion=16&charset=utf8"
|
||||
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
# Datei existiert - DATABASE_URL aktualisieren oder hinzufügen
|
||||
if grep -q "^DATABASE_URL=" "$ENV_FILE"; then
|
||||
sed -i "s|^DATABASE_URL=.*|DATABASE_URL=\"$DATABASE_URL\"|" "$ENV_FILE"
|
||||
echo " ✅ DATABASE_URL aktualisiert"
|
||||
else
|
||||
echo "DATABASE_URL=\"$DATABASE_URL\"" >> "$ENV_FILE"
|
||||
echo " ✅ DATABASE_URL hinzugefügt"
|
||||
fi
|
||||
|
||||
# APP_ENV sicherstellen
|
||||
if ! grep -q "^APP_ENV=" "$ENV_FILE"; then
|
||||
echo "APP_ENV=dev" >> "$ENV_FILE"
|
||||
echo " ✅ APP_ENV hinzugefügt"
|
||||
fi
|
||||
else
|
||||
# Neue Datei erstellen
|
||||
cat > "$ENV_FILE" <<EOF
|
||||
### symfony-pod environment ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=$(openssl rand -hex 16)
|
||||
DATABASE_URL="$DATABASE_URL"
|
||||
### symfony-pod environment ###
|
||||
EOF
|
||||
echo " ✅ .env Datei erstellt"
|
||||
fi
|
||||
|
||||
# 2. Pod erstellen
|
||||
echo "📦 Erstelle Pod '$POD_NAME'..."
|
||||
podman pod create --name $POD_NAME -p 8080:80
|
||||
|
||||
# 3. PHP-FPM Container bauen und starten
|
||||
echo "🐘 Baue und starte PHP-FPM..."
|
||||
podman build -t symfony-php -f podman/php/Containerfile .
|
||||
podman run -d \
|
||||
--pod $POD_NAME \
|
||||
--name symfony-php \
|
||||
-v $PROJECT_DIR:/var/www/html:Z \
|
||||
-e APP_ENV=dev \
|
||||
symfony-php
|
||||
|
||||
# 4. Nginx Container bauen und starten
|
||||
echo "🌐 Baue und starte Nginx..."
|
||||
podman build -t symfony-nginx -f podman/nginx/Containerfile .
|
||||
podman run -d \
|
||||
--pod $POD_NAME \
|
||||
--name symfony-nginx \
|
||||
symfony-nginx
|
||||
|
||||
# 5. PostgreSQL Container starten
|
||||
echo "🐘 Starte PostgreSQL..."
|
||||
podman run -d \
|
||||
--pod $POD_NAME \
|
||||
--name symfony-db \
|
||||
-e POSTGRES_DB=$DB_NAME \
|
||||
-e POSTGRES_USER=$DB_USER \
|
||||
-e POSTGRES_PASSWORD=$DB_PASSWORD \
|
||||
-v symfony-db-data:/var/lib/postgresql/data \
|
||||
docker.io/library/postgres:16-alpine
|
||||
|
||||
# 6. Warten auf DB Start
|
||||
echo "⏳ Warte auf Datenbank-Start..."
|
||||
sleep 5
|
||||
|
||||
# 7. Symfony Abhängigkeiten installieren (falls composer.json existiert)
|
||||
if [ -f "$PROJECT_DIR/composer.json" ]; then
|
||||
echo "📦 Installiere Composer Abhängigkeiten..."
|
||||
podman exec -it symfony-php composer install
|
||||
|
||||
echo "🗄️ Erstelle Datenbank..."
|
||||
podman exec -it symfony-php php bin/console doctrine:database:create --if-not-exists
|
||||
|
||||
echo "🔄 Führe Migrationen aus..."
|
||||
podman exec -it symfony-php php bin/console doctrine:migrations:migrate --no-interaction
|
||||
else
|
||||
echo "ℹ️ Keine composer.json gefunden - überspringe Installation"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Setup abgeschlossen!"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🌍 Deine App ist erreichbar unter: http://localhost:8080"
|
||||
echo "🔑 DB Zugangsdaten:"
|
||||
echo " Host: $DB_HOST (innerhalb des Pods)"
|
||||
echo " Port: $DB_PORT"
|
||||
echo " User: $DB_USER"
|
||||
echo " Pass: $DB_PASSWORD"
|
||||
echo " DB: $DB_NAME"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📝 .env Datei wurde automatisch konfiguriert"
|
||||
echo ""
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
}
|
||||
Reference in New Issue
Block a user