app/Dockerfile

97 lines
1.9 KiB
Docker

# Production Dockerfile with FrankenPHP
FROM dunglas/frankenphp:latest-php8.3-alpine
# Install system dependencies
RUN apk add --no-cache \
nodejs \
npm \
git \
mysql-client
# Install PHP extensions
RUN install-php-extensions \
pdo_mysql \
opcache \
zip \
gd \
intl
# Install Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# 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=database \
CACHE_DRIVER=file \
QUEUE_CONNECTION=database \
LOG_CHANNEL=stack \
LOG_LEVEL=error \
MAIL_MAILER=smtp \
MAIL_ENCRYPTION=tls
# Copy composer files and install PHP dependencies
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-interaction --optimize-autoloader
# Copy package files and install Node dependencies
COPY package*.json ./
RUN npm ci --omit=dev
# Copy application code
COPY . .
# Build frontend assets
RUN npm run build
# Laravel optimizations
RUN php artisan config:cache \
&& php artisan route:cache \
&& php artisan view:cache \
&& php artisan livewire:discover \
&& 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
php_server {
index index.php
}
encode gzip
file_server
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
}
}
EOF
# Expose port
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/up || exit 1
# Start FrankenPHP
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]