fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled

This commit is contained in:
2025-11-24 21:28:25 +01:00
parent 4eb7134853
commit 77abc65cd7
1327 changed files with 91915 additions and 9909 deletions

View File

@@ -11,99 +11,100 @@
# - Docker Secrets for sensitive configuration
services:
production-app:
php:
image: localhost:5000/framework:latest
container_name: production-app
container_name: production-php
restart: unless-stopped
entrypoint: >
sh -c '
set -e
echo "[Production Entrypoint] Starting initialization..."
entrypoint:
- sh
- -c
- |
set -e
echo "[Production Entrypoint] Starting initialization..."
# Copy Docker Secrets to /tmp for permission workaround
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
if [ -f /run/secrets/app_key ]; then
cp /run/secrets/app_key /tmp/app_key
chmod 644 /tmp/app_key
export APP_KEY_FILE=/tmp/app_key
fi
if [ -f /run/secrets/vault_encryption_key ]; then
cp /run/secrets/vault_encryption_key /tmp/vault_encryption_key
chmod 644 /tmp/vault_encryption_key
export VAULT_ENCRYPTION_KEY_FILE=/tmp/vault_encryption_key
fi
if [ -f /run/secrets/git_token ]; then
cp /run/secrets/git_token /tmp/git_token
chmod 644 /tmp/git_token
GIT_TOKEN=$(cat /tmp/git_token)
export GIT_TOKEN
fi
# Git deployment with authentication
if [ -n "$GIT_REPOSITORY_URL" ] && [ -n "$GIT_TOKEN" ]; then
echo "[Production Entrypoint] Configuring Git deployment..."
# Configure Git credentials
git config --global credential.helper store
echo "https://oauth2:${GIT_TOKEN}@git.michaelschiemer.de" > ~/.git-credentials
cd /var/www/html
# Clone repository if not exists
if [ ! -d .git ]; then
echo "[Production Entrypoint] Cloning repository..."
git clone --branch ${GIT_BRANCH:-main} ${GIT_REPOSITORY_URL} /tmp/repo
mv /tmp/repo/.git .
git reset --hard HEAD
else
echo "[Production Entrypoint] Pulling latest changes..."
git fetch origin ${GIT_BRANCH:-main}
git reset --hard origin/${GIT_BRANCH:-main}
# Copy Docker Secrets to /tmp for permission workaround
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
echo "[Production Entrypoint] Git deployment completed"
else
echo "[Production Entrypoint] Git deployment skipped (no repository configured)"
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
# Install/Update Composer dependencies (production mode)
if [ -f composer.json ]; then
echo "[Production Entrypoint] Installing Composer dependencies (production mode)..."
composer install --no-dev --optimize-autoloader --no-interaction --no-progress
fi
if [ -f /run/secrets/app_key ]; then
cp /run/secrets/app_key /tmp/app_key
chmod 644 /tmp/app_key
export APP_KEY_FILE=/tmp/app_key
fi
# Run database migrations
if [ -f console.php ]; then
echo "[Production Entrypoint] Running database migrations..."
php console.php db:migrate --force || echo "[Production Entrypoint] Migration failed or no migrations pending"
fi
if [ -f /run/secrets/vault_encryption_key ]; then
cp /run/secrets/vault_encryption_key /tmp/vault_encryption_key
chmod 644 /tmp/vault_encryption_key
export VAULT_ENCRYPTION_KEY_FILE=/tmp/vault_encryption_key
fi
# Warm up caches
if [ -f console.php ]; then
echo "[Production Entrypoint] Warming up caches..."
php console.php cache:warm || echo "[Production Entrypoint] Cache warm-up skipped"
fi
if [ -f /run/secrets/git_token ]; then
cp /run/secrets/git_token /tmp/git_token
chmod 644 /tmp/git_token
GIT_TOKEN=$(cat /tmp/git_token)
export GIT_TOKEN
fi
# Set proper permissions
chown -R www-data:www-data /var/www/html/storage /var/www/html/var || true
chmod -R 775 /var/www/html/storage /var/www/html/var || true
# Git deployment with authentication
if [ -n "$GIT_REPOSITORY_URL" ] && [ -n "$GIT_TOKEN" ]; then
echo "[Production Entrypoint] Configuring Git deployment..."
echo "[Production Entrypoint] Initialization complete, starting PHP-FPM..."
exec php-fpm
'
# Configure Git credentials
git config --global credential.helper store
echo "https://oauth2:${GIT_TOKEN}@git.michaelschiemer.de" > ~/.git-credentials
cd /var/www/html
# Clone repository if not exists
if [ ! -d .git ]; then
echo "[Production Entrypoint] Cloning repository..."
git clone --branch ${GIT_BRANCH:-main} ${GIT_REPOSITORY_URL} /tmp/repo
mv /tmp/repo/.git .
git reset --hard HEAD
else
echo "[Production Entrypoint] Pulling latest changes..."
git fetch origin ${GIT_BRANCH:-main}
git reset --hard origin/${GIT_BRANCH:-main}
fi
echo "[Production Entrypoint] Git deployment completed"
else
echo "[Production Entrypoint] Git deployment skipped (no repository configured)"
fi
# Install/Update Composer dependencies (production mode)
if [ -f composer.json ]; then
echo "[Production Entrypoint] Installing Composer dependencies (production mode)..."
composer install --no-dev --optimize-autoloader --no-interaction --no-progress
fi
# Run database migrations
if [ -f console.php ]; then
echo "[Production Entrypoint] Running database migrations..."
php console.php db:migrate --force || echo "[Production Entrypoint] Migration failed or no migrations pending"
fi
# Warm up caches
if [ -f console.php ]; then
echo "[Production Entrypoint] Warming up caches..."
php console.php cache:warm || echo "[Production Entrypoint] Cache warm-up skipped"
fi
# Set proper permissions
chown -R www-data:www-data /var/www/html/storage /var/www/html/var || true
chmod -R 775 /var/www/html/storage /var/www/html/var || true
echo "[Production Entrypoint] Initialization complete, starting PHP-FPM..."
exec php-fpm
environment:
- APP_ENV=production
- APP_DEBUG=false
@@ -115,9 +116,9 @@ services:
- GIT_REPOSITORY_URL=${GIT_REPOSITORY_URL:-https://git.michaelschiemer.de/michael/framework.git}
- GIT_BRANCH=${GIT_BRANCH:-main}
- DB_DRIVER=pgsql
- DB_HOST=${DB_HOST:-postgres-production}
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=${DB_DATABASE:-michaelschiemer_production}
- DB_DATABASE=${DB_DATABASE:-michaelschiemer}
- DB_USERNAME=${DB_USERNAME:-postgres}
- DB_PASSWORD_FILE=/tmp/db_user_password
- REDIS_HOST=production-redis
@@ -132,9 +133,9 @@ services:
- ADMIN_ALLOWED_IPS=${ADMIN_ALLOWED_IPS:-127.0.0.1,::1}
- COMPOSE_PROJECT_NAME=framework-production
volumes:
- production-code:/var/www/html
- production-storage:/var/www/html/storage
- production-logs:/var/www/html/storage/logs
- app-code:/var/www/html
- app-storage:/var/www/html/storage
- app-logs:/var/www/html/storage/logs
- composer-cache:/root/.composer/cache
secrets:
- db_user_password
@@ -143,8 +144,8 @@ services:
- vault_encryption_key
- git_token
networks:
- production-internal
- postgres-production-internal
- app-backend
- app-internal
healthcheck:
test: ["CMD", "php", "-v"]
interval: 30s
@@ -165,19 +166,19 @@ services:
max-size: "10m"
max-file: "5"
production-nginx:
nginx:
image: nginx:alpine
container_name: production-nginx
restart: unless-stopped
depends_on:
production-app:
php:
condition: service_healthy
volumes:
- production-code:/var/www/html:ro
- ./docker/nginx/production.conf:/etc/nginx/conf.d/default.conf:ro
- production-logs:/var/www/html/storage/logs
- app-code:/var/www/html:ro
- ./docker/nginx/default.traefik.conf:/etc/nginx/conf.d/default.conf:ro
- app-logs:/var/www/html/storage/logs
networks:
- production-internal
- app-backend
- traefik-public
labels:
# Traefik Configuration
@@ -252,33 +253,34 @@ services:
image: redis:7-alpine
container_name: production-redis
restart: unless-stopped
entrypoint: >
sh -c '
set -e
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
REDIS_PASSWORD=$(cat /tmp/redis_password)
exec redis-server \
--requirepass "$REDIS_PASSWORD" \
--maxmemory 512mb \
--maxmemory-policy allkeys-lru \
--save 900 1 \
--save 300 10 \
--save 60 10000 \
--appendonly yes \
--appendfsync everysec
else
echo "ERROR: Redis password secret not found"
exit 1
fi
'
entrypoint:
- sh
- -c
- |
set -e
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
REDIS_PASSWORD=$(cat /tmp/redis_password)
exec redis-server \
--requirepass "$REDIS_PASSWORD" \
--maxmemory 512mb \
--maxmemory-policy allkeys-lru \
--save 900 1 \
--save 300 10 \
--save 60 10000 \
--appendonly yes \
--appendfsync everysec
else
echo "ERROR: Redis password secret not found"
exit 1
fi
volumes:
- production-redis-data:/data
- redis-data:/data
secrets:
- redis_password
networks:
- production-internal
- app-backend
healthcheck:
test: ["CMD", "sh", "-c", "redis-cli --no-auth-warning -a $(cat /tmp/redis_password 2>/dev/null || echo '') ping || exit 1"]
interval: 30s
@@ -299,37 +301,38 @@ services:
max-size: "10m"
max-file: "3"
production-queue-worker:
queue-worker:
image: localhost:5000/framework:latest
container_name: production-queue-worker
restart: unless-stopped
entrypoint: >
sh -c '
set -e
echo "[Queue Worker] Starting initialization..."
entrypoint:
- sh
- -c
- |
set -e
echo "[Queue Worker] Starting initialization..."
# Copy Docker Secrets
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
# Copy Docker Secrets
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
echo "[Queue Worker] Starting worker process..."
exec php /var/www/html/worker.php
'
echo "[Queue Worker] Starting worker process..."
exec php /var/www/html/worker.php
environment:
- APP_ENV=production
- APP_DEBUG=false
- DB_HOST=${DB_HOST:-postgres-production}
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=${DB_DATABASE:-michaelschiemer_production}
- DB_DATABASE=${DB_DATABASE:-michaelschiemer}
- DB_USERNAME=${DB_USERNAME:-postgres}
- DB_PASSWORD_FILE=/tmp/db_user_password
- REDIS_HOST=production-redis
@@ -338,17 +341,17 @@ services:
- WORKER_SLEEP_TIME=${WORKER_SLEEP_TIME:-100000}
- WORKER_MAX_JOBS=${WORKER_MAX_JOBS:-10000}
volumes:
- production-code:/var/www/html:ro
- production-storage:/var/www/html/storage
- production-logs:/var/www/html/storage/logs
- app-code:/var/www/html:ro
- app-storage:/var/www/html/storage
- app-logs:/var/www/html/storage/logs
secrets:
- db_user_password
- redis_password
networks:
- production-internal
- postgres-production-internal
- app-backend
- app-internal
depends_on:
production-app:
php:
condition: service_healthy
production-redis:
condition: service_healthy
@@ -367,54 +370,55 @@ services:
max-size: "10m"
max-file: "3"
production-scheduler:
scheduler:
image: localhost:5000/framework:latest
container_name: production-scheduler
restart: unless-stopped
entrypoint: >
sh -c '
set -e
echo "[Scheduler] Starting initialization..."
entrypoint:
- sh
- -c
- |
set -e
echo "[Scheduler] Starting initialization..."
# Copy Docker Secrets
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
# Copy Docker Secrets
if [ -f /run/secrets/db_user_password ]; then
cp /run/secrets/db_user_password /tmp/db_user_password
chmod 644 /tmp/db_user_password
export DB_PASSWORD_FILE=/tmp/db_user_password
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
if [ -f /run/secrets/redis_password ]; then
cp /run/secrets/redis_password /tmp/redis_password
chmod 644 /tmp/redis_password
export REDIS_PASSWORD_FILE=/tmp/redis_password
fi
echo "[Scheduler] Starting scheduler process..."
exec php /var/www/html/scheduler.php
'
echo "[Scheduler] Starting scheduler process..."
exec php /var/www/html/scheduler.php
environment:
- APP_ENV=production
- APP_DEBUG=false
- DB_HOST=${DB_HOST:-postgres-production}
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=${DB_DATABASE:-michaelschiemer_production}
- DB_DATABASE=${DB_DATABASE:-michaelschiemer}
- DB_USERNAME=${DB_USERNAME:-postgres}
- DB_PASSWORD_FILE=/tmp/db_user_password
- REDIS_HOST=production-redis
- REDIS_PORT=6379
- REDIS_PASSWORD_FILE=/tmp/redis_password
volumes:
- production-code:/var/www/html:ro
- production-storage:/var/www/html/storage
- production-logs:/var/www/html/storage/logs
- app-code:/var/www/html:ro
- app-storage:/var/www/html/storage
- app-logs:/var/www/html/storage/logs
secrets:
- db_user_password
- redis_password
networks:
- production-internal
- postgres-production-internal
- app-backend
- app-internal
depends_on:
production-app:
php:
condition: service_healthy
production-redis:
condition: service_healthy
@@ -437,48 +441,56 @@ services:
web:
profiles: [never]
php:
profiles: [never]
php-test:
profiles: [never]
redis:
profiles: [never]
queue-worker:
profiles: [never]
minio:
profiles: [never]
# Networks
networks:
production-internal:
app-backend:
driver: bridge
internal: false
postgres-production-internal:
app-internal:
external: true
name: postgres-production-internal
name: app-internal
traefik-public:
external: true
name: traefik-public
# Volumes
volumes:
production-code:
app-code:
driver: local
production-storage:
app-storage:
driver: local
production-logs:
app-logs:
driver: local
production-redis-data:
redis-data:
driver: local
composer-cache:
driver: local
# Docker Secrets Configuration
# Secrets are inherited from docker-compose.base.yml
# But we need to explicitly define them here to ensure they're available
secrets:
db_user_password:
file: ./deployment/secrets/production/db_password.txt
external: false
redis_password:
file: ./deployment/secrets/production/redis_password.txt
external: false
app_key:
file: ./deployment/secrets/production/app_key.txt
external: false
vault_encryption_key:
file: ./deployment/secrets/production/vault_encryption_key.txt
external: false
git_token:
file: ./deployment/secrets/production/git_token.txt
external: false