Deployment-Rules for second server
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# Produktions-Image für endeavour (KeyHelp-Server, siehe docs/implement-endeavour.md).
|
||||
# Unabhängig von docker/prod.Dockerfile, das der bestehende Server weiter nutzt.
|
||||
#
|
||||
# Targets:
|
||||
# app – PHP-FPM mit Code, vendor/ und gebauten Assets
|
||||
# web – nginx, liefert public/ aus und reicht PHP an "app" weiter
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# base: PHP 8.5 mit den Extensions, die mareike braucht
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM php:8.5-fpm-alpine AS base
|
||||
|
||||
ARG UID=2000
|
||||
ARG GID=2000
|
||||
|
||||
RUN apk add --no-cache \
|
||||
imagemagick \
|
||||
libpng \
|
||||
libxml2 \
|
||||
libzip \
|
||||
oniguruma \
|
||||
&& apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
imagemagick-dev \
|
||||
libpng-dev \
|
||||
libxml2-dev \
|
||||
libzip-dev \
|
||||
oniguruma-dev \
|
||||
&& pecl install imagick \
|
||||
&& docker-php-ext-enable imagick \
|
||||
&& docker-php-ext-install mysqli pdo_mysql mbstring zip exif pcntl gd \
|
||||
&& apk del .build-deps \
|
||||
&& rm -rf /tmp/pear
|
||||
|
||||
# Nutzer mit der UID/GID des Host-Nutzers, damit das eingebundene storage/ beschreibbar ist.
|
||||
# Existiert die GID im Image schon, wird die vorhandene Gruppe verwendet.
|
||||
RUN if getent group "${GID}" > /dev/null; then \
|
||||
GROUP_NAME="$(getent group "${GID}" | cut -d: -f1)"; \
|
||||
else \
|
||||
addgroup -S -g "${GID}" mareike && GROUP_NAME=mareike; \
|
||||
fi \
|
||||
&& adduser -S -D -H -u "${UID}" -G "${GROUP_NAME}" mareike
|
||||
|
||||
COPY --chmod=0755 docker/php/composer.phar /usr/bin/composer
|
||||
COPY docker/endeavour/php.ini /usr/local/etc/php/conf.d/zz-mareike.ini
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# vendor: Composer-Abhängigkeiten (ohne Dev-Pakete)
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM base AS vendor
|
||||
|
||||
RUN apk add --no-cache git unzip
|
||||
|
||||
COPY composer.json composer.lock ./
|
||||
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist --no-interaction --no-progress
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# assets: Vite-Build (Vite importiert aus app/, daher der volle Quellcode)
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM node:24-alpine AS assets
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --no-audit --no-fund
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# app: PHP-FPM
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM base AS app
|
||||
|
||||
COPY . .
|
||||
COPY --from=vendor /var/www/html/vendor ./vendor
|
||||
COPY --from=assets /app/public/build ./public/build
|
||||
|
||||
# Der Code gehört root; beschreibbar sind nur storage/ und bootstrap/cache/.
|
||||
RUN composer dump-autoload --optimize --no-dev --no-interaction \
|
||||
&& mkdir -p \
|
||||
storage/app/private \
|
||||
storage/app/public \
|
||||
storage/framework/cache/data \
|
||||
storage/framework/sessions \
|
||||
storage/framework/views \
|
||||
storage/logs \
|
||||
storage/temp \
|
||||
&& chown -R mareike: storage bootstrap/cache
|
||||
|
||||
USER mareike
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# web: nginx vor PHP-FPM
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM nginx:stable-alpine AS web
|
||||
|
||||
COPY docker/endeavour/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=app /var/www/html/public /var/www/html/public
|
||||
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,36 @@
|
||||
# Build-Kontext für docker/endeavour/Dockerfile.
|
||||
# BuildKit nutzt diese Datei anstelle der .dockerignore im Projektroot, die für den bestehenden Server
|
||||
# unverändert bleibt. Wichtig: keine .env ins Image – sie wird zur Laufzeit eingebunden.
|
||||
|
||||
.git
|
||||
.ai
|
||||
.junie
|
||||
.claude
|
||||
.idea
|
||||
.fleet
|
||||
.vscode
|
||||
.zed
|
||||
|
||||
.env
|
||||
.env.*
|
||||
|
||||
node_modules
|
||||
vendor
|
||||
public/build
|
||||
public/hot
|
||||
public/storage
|
||||
|
||||
storage/*
|
||||
bootstrap/cache/*.php
|
||||
|
||||
tests
|
||||
.phpunit.cache
|
||||
.phpunit.result.cache
|
||||
|
||||
docker/ssl
|
||||
docker/logs
|
||||
docker-compose.yaml
|
||||
|
||||
_ide_helper.php
|
||||
_ide_helper_models.php
|
||||
gitlog.log
|
||||
@@ -0,0 +1,42 @@
|
||||
# Compose-Stack für endeavour (KeyHelp-Server, siehe docs/implement-endeavour.md).
|
||||
# Wird über /opt/mareike/bin/deploy.sh gesteuert, das die MAREIKE_*-Variablen setzt.
|
||||
|
||||
name: mareike
|
||||
|
||||
x-logging: &logging
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: docker/endeavour/Dockerfile
|
||||
target: app
|
||||
args:
|
||||
UID: ${MAREIKE_UID:-2000}
|
||||
GID: ${MAREIKE_GID:-2000}
|
||||
image: mareike-endeavour-app:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${MAREIKE_ENV_FILE:-/opt/mareike/shared/.env}:/var/www/html/.env:ro
|
||||
- ${MAREIKE_STORAGE:-/opt/mareike/storage}:/var/www/html/storage
|
||||
# Socket der KeyHelp-MariaDB auf dem Host (DB_SOCKET=/run/mysqld/mysqld.sock)
|
||||
- ${MAREIKE_DB_SOCKET_DIR:-/run/mysqld}:/run/mysqld
|
||||
logging: *logging
|
||||
|
||||
web:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: docker/endeavour/Dockerfile
|
||||
target: web
|
||||
image: mareike-endeavour-web:latest
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- app
|
||||
ports:
|
||||
# Nur lokal erreichbar – nach außen geht es ausschließlich über den KeyHelp-Webserver.
|
||||
- "127.0.0.1:${MAREIKE_HTTP_PORT:-8080}:80"
|
||||
logging: *logging
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Deployment von mareike auf endeavour (KeyHelp-Server), siehe docs/implement-endeavour.md.
|
||||
#
|
||||
# Liegt auf dem Server als KOPIE unter /opt/mareike/bin/deploy.sh – nicht direkt aus src/ ausführen,
|
||||
# weil der git-Checkout sonst das laufende Skript austauscht.
|
||||
#
|
||||
# Aufruf (als root):
|
||||
# deploy.sh [REF] Tag, Branch oder Commit ausrollen (Default: main)
|
||||
# deploy.sh artisan … php artisan im laufenden app-Container
|
||||
# deploy.sh compose … docker compose mit der endeavour-Konfiguration (z. B. "compose logs -f")
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
MAREIKE_BASE="${MAREIKE_BASE:-/opt/mareike}"
|
||||
MAREIKE_USER="${MAREIKE_USER:-mareike-docker}"
|
||||
SRC="$MAREIKE_BASE/src"
|
||||
|
||||
export MAREIKE_ENV_FILE="$MAREIKE_BASE/shared/.env"
|
||||
export MAREIKE_STORAGE="$MAREIKE_BASE/storage"
|
||||
export MAREIKE_HTTP_PORT="${MAREIKE_HTTP_PORT:-8080}"
|
||||
export MAREIKE_DB_SOCKET_DIR="${MAREIKE_DB_SOCKET_DIR:-/run/mysqld}"
|
||||
MAREIKE_UID="$(id -u "$MAREIKE_USER")"
|
||||
MAREIKE_GID="$(id -g "$MAREIKE_USER")"
|
||||
export MAREIKE_UID MAREIKE_GID
|
||||
|
||||
compose() {
|
||||
docker compose -f "$SRC/docker/endeavour/compose.yaml" "$@"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
artisan)
|
||||
shift
|
||||
compose exec app php artisan "$@"
|
||||
exit
|
||||
;;
|
||||
compose)
|
||||
shift
|
||||
compose "$@"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
REF="${1:-main}"
|
||||
|
||||
if [[ ! -f "$MAREIKE_ENV_FILE" ]]; then
|
||||
echo "Fehlt: $MAREIKE_ENV_FILE (Vorlage: docker/endeavour/env.production.example)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> Quellcode auf '$REF' bringen"
|
||||
git -C "$SRC" fetch --tags --prune --force origin
|
||||
if git -C "$SRC" show-ref --verify --quiet "refs/remotes/origin/$REF"; then
|
||||
git -C "$SRC" checkout --force -B "$REF" "origin/$REF"
|
||||
else
|
||||
git -C "$SRC" checkout --force --detach "$REF"
|
||||
fi
|
||||
git -C "$SRC" clean -fd
|
||||
|
||||
echo "==> storage/ vorbereiten"
|
||||
for dir in \
|
||||
"" \
|
||||
app app/private app/public \
|
||||
framework framework/cache framework/cache/data framework/sessions framework/views \
|
||||
logs temp
|
||||
do
|
||||
install -d -m 0775 -o "$MAREIKE_USER" -g "$MAREIKE_GID" "$MAREIKE_STORAGE/$dir"
|
||||
done
|
||||
|
||||
echo "==> Images bauen"
|
||||
compose build --pull
|
||||
|
||||
echo "==> Datenbank migrieren"
|
||||
compose run --rm --no-deps app php artisan migrate --force
|
||||
|
||||
echo "==> Container starten"
|
||||
compose up -d --remove-orphans
|
||||
compose exec -T app php artisan view:clear
|
||||
|
||||
docker image prune -f > /dev/null
|
||||
|
||||
echo "==> mareike $(cat "$SRC/version") ($(git -C "$SRC" rev-parse --short HEAD)) läuft."
|
||||
@@ -0,0 +1,65 @@
|
||||
# Vorlage für /opt/mareike/shared/.env auf endeavour.
|
||||
# Nach dem Kopieren alle <...>-Platzhalter ersetzen. Diese Datei kommt NIE ins Image und NIE ins Repo.
|
||||
# Keine ${...}-Verweise auf andere Variablen verwenden, Werte ausschreiben.
|
||||
|
||||
APP_NAME=mareike
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
# Erzeugen mit: echo "base64:$(openssl rand -base64 32)" – danach NIE mehr ändern (verschlüsselte Daten!)
|
||||
APP_KEY=
|
||||
# Domain des Dach-Tenants "lv"
|
||||
APP_URL=https://<lv-subdomain>.meine-anmeldung.digital
|
||||
# Kein ASSET_URL: Assets kommen von der jeweiligen Tenant-Domain selbst.
|
||||
|
||||
APP_LOCALE=de
|
||||
APP_FALLBACK_LOCALE=de
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=daily
|
||||
LOG_DAILY_DAYS=30
|
||||
LOG_LEVEL=warning
|
||||
|
||||
# KeyHelp-MariaDB auf dem Host, per Unix-Socket (Verzeichnis /run/mysqld ist in den Container gemountet)
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_SOCKET=/run/mysqld/mysqld.sock
|
||||
DB_DATABASE=<datenbankname-aus-keyhelp>
|
||||
DB_USERNAME=<datenbanknutzer-aus-keyhelp>
|
||||
DB_PASSWORD=<passwort>
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_SECURE_COOKIE=true
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
CACHE_STORE=database
|
||||
QUEUE_CONNECTION=sync
|
||||
FILESYSTEM_DISK=local
|
||||
|
||||
# Versand über ein KeyHelp-Postfach (STARTTLS auf 587)
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_SCHEME=smtp
|
||||
MAIL_HOST=<hostname-des-mailservers>
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=<noreply@meine-anmeldung.digital>
|
||||
MAIL_PASSWORD=<passwort>
|
||||
MAIL_FROM_ADDRESS=<noreply@meine-anmeldung.digital>
|
||||
MAIL_FROM_NAME=mareike
|
||||
|
||||
# Empfänger der Admin-Benachrichtigungen (z. B. neue Registrierungen)
|
||||
APP_ADMIN_MAIL=<admin@meine-anmeldung.digital>
|
||||
APP_ADMIN_NAME="<Name>"
|
||||
|
||||
# Maximale Größe hochgeladener Belege in MB (php.ini erlaubt bis 64)
|
||||
MAX_INVOICE_FILE_SIZE=16
|
||||
|
||||
# WebDAV-Ablage: unbedingt ein EIGENER Ordner, getrennt vom bestehenden Server
|
||||
WEBDAV_HOST=<https://cloud.example.org/remote.php/dav/files/<nutzer>/<eigener-ordner>/>
|
||||
WEBDAV_USER=<nutzer>
|
||||
WEBDAV_PASS=<app-passwort>
|
||||
|
||||
# Prüfdienst für erweiterte Führungszeugnisse
|
||||
COC_CHECK_URL=<https://efzcheck.example.org/api/v1/check-efz>
|
||||
|
||||
# MUSS leer bleiben: "bdp-lv-sachsen" würde beim Seeden die Sachsen-Tenants und deren Personen einspielen.
|
||||
PROVIDER=
|
||||
@@ -0,0 +1,54 @@
|
||||
# nginx im Container "web" auf endeavour.
|
||||
# TLS terminiert der KeyHelp-Webserver auf dem Host und reicht per Proxy an 127.0.0.1:8080 weiter.
|
||||
|
||||
# Echte Client-IP aus X-Forwarded-For übernehmen, aber nur von Docker-internen Adressen
|
||||
# (der Proxy auf dem Host erreicht den Container über das Bridge-Gateway).
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
root /var/www/html/public;
|
||||
index index.php;
|
||||
|
||||
server_tokens off;
|
||||
client_max_body_size 70m;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
# Vite-Assets sind versioniert (Hash im Dateinamen) und dürfen lange gecacht werden.
|
||||
location /build/assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
|
||||
# Nach außen läuft alles über HTTPS (KeyHelp). So erzeugt Laravel https-URLs,
|
||||
# ohne dass im App-Code trustProxies gesetzt werden muss.
|
||||
fastcgi_param HTTPS on;
|
||||
fastcgi_param REQUEST_SCHEME https;
|
||||
fastcgi_param SERVER_PORT 443;
|
||||
|
||||
fastcgi_read_timeout 300;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known) {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
; PHP-Einstellungen für endeavour (Container "app").
|
||||
|
||||
; Uploads: Obergrenze für MAX_INVOICE_FILE_SIZE (MB, Default 16) in der .env, POST etwas größer für die
|
||||
; Formulardaten.
|
||||
upload_max_filesize = 64M
|
||||
post_max_size = 70M
|
||||
|
||||
memory_limit = 512M
|
||||
max_execution_time = 120
|
||||
|
||||
expose_php = Off
|
||||
date.timezone = Europe/Berlin
|
||||
|
||||
; OPcache ist ab PHP 8.5 fest eingebaut. Zeitstempel werden weiter geprüft, weil Blade kompilierte
|
||||
; Views in storage/ unter gleichem Dateinamen neu schreibt.
|
||||
opcache.enable = 1
|
||||
opcache.memory_consumption = 128
|
||||
opcache.max_accelerated_files = 20000
|
||||
opcache.validate_timestamps = 1
|
||||
opcache.revalidate_freq = 2
|
||||
Reference in New Issue
Block a user