fedi-feed-router/Dockerfile
myrmidex 831983c87a
All checks were successful
CI / ci (pull_request) Successful in 1m53s
CI / ci (push) Successful in 1m49s
148 - Pin image versions and stop publishing latest
2026-09-26 23:06:30 +02:00

127 lines
2.9 KiB
Docker

# Production Dockerfile - uses pre-built base image
FROM forge.lvl0.xyz/lvl0/fedi-feed-router-base:php8.3-2
# Set working directory
WORKDIR /app
# Set fixed production environment variables
ENV APP_ENV=production \
APP_DEBUG=false \
DB_CONNECTION=mysql \
DB_HOST=db \
DB_PORT=3306 \
SESSION_DRIVER=redis \
CACHE_STORE=redis \
QUEUE_CONNECTION=redis \
LOG_CHANNEL=stack \
LOG_LEVEL=${LOG_LEVEL:-error}
# Copy application code first
COPY . .
# Install PHP dependencies (production only)
RUN composer install --no-dev --no-interaction --optimize-autoloader
# Install ALL Node dependencies (including dev for building)
RUN npm install
# Build frontend assets
RUN npm run build
# Remove node_modules after build to save space
RUN rm -rf node_modules
# Publish Livewire assets
RUN php artisan livewire:publish --assets
# Laravel optimizations (skip config and route cache - they need runtime env vars)
RUN php artisan view:cache \
&& composer dump-autoload --optimize
# Set permissions
RUN chown -R www-data:www-data /app/storage /app/bootstrap/cache
# Configure Caddy
RUN cat > /etc/caddy/Caddyfile <<EOF
{
frankenphp
order php_server before file_server
}
:8000 {
root * /app/public
encode gzip
php_server
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
}
}
EOF
# Expose port
EXPOSE 8000
# Health check
# start-period must outlast the startup script's 60s database wait.
HEALTHCHECK --interval=30s --timeout=3s --start-period=75s --retries=3 \
CMD curl -f http://localhost:8000/up || exit 1
# Create startup script for production
RUN cat > /start-prod.sh <<'EOF'
#!/bin/sh
set -e
# Wait for database to be ready
echo "Waiting for database..."
db_ready=0
for i in $(seq 1 30); do
if mysqladmin ping -h "$DB_HOST" -u "$DB_USERNAME" -p"$DB_PASSWORD" --silent 2>/dev/null; then
echo "Database is ready!"
db_ready=1
break
fi
echo "Waiting for database... ($i/30)"
sleep 2
done
if [ "$db_ready" -ne 1 ]; then
echo "Database unreachable at ${DB_HOST} after 60s; exiting so the restart policy retries." >&2
exit 1
fi
# Cache config with runtime env vars
echo "Caching configuration..."
php artisan config:cache
# Run migrations. A partial schema is worse than a container that refuses to start.
echo "Running migrations..."
php artisan migrate --force
# Run seeders (idempotent - uses updateOrInsert)
echo "Running seeders..."
php artisan db:seed --force
# Restart a worker that dies instead of leaving the queue unconsumed.
supervise() {
while true; do
"$@" || echo "[supervisor] '$*' exited with $?; restarting in 5s." >&2
sleep 5
done
}
supervise php artisan horizon &
supervise php artisan schedule:work &
# Start FrankenPHP
exec frankenphp run --config /etc/caddy/Caddyfile
EOF
RUN chmod +x /start-prod.sh
# Start with our script
CMD ["/start-prod.sh"]