FROM ubuntu:24.04 # Prevent interactive prompts during package installation ENV DEBIAN_FRONTEND=noninteractive ENV TZ=UTC # Set versions ENV PHP_VERSION=8.4 ENV NODE_VERSION=20.x ENV COMPOSER_ALLOW_SUPERUSER=1 # Install repository management tools and add custom repositories RUN apt-get update \ && apt-get install -y --no-install-recommends \ software-properties-common \ curl \ ca-certificates \ gnupg \ apt-utils \ && add-apt-repository ppa:ondrej/php \ && curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Install all application packages RUN apt-get update && apt-get install -y \ # Apache2 apache2 \ # PHP and extensions php${PHP_VERSION} \ php${PHP_VERSION}-cli \ php${PHP_VERSION}-fpm \ php${PHP_VERSION}-common \ php${PHP_VERSION}-mysql \ php${PHP_VERSION}-sqlite3 \ php${PHP_VERSION}-zip \ php${PHP_VERSION}-gd \ php${PHP_VERSION}-mbstring \ php${PHP_VERSION}-curl \ php${PHP_VERSION}-xml \ php${PHP_VERSION}-bcmath \ php${PHP_VERSION}-intl \ php${PHP_VERSION}-dom \ # Node.js (from NodeSource repository) nodejs \ # System utilities zip \ cron \ wget \ unzip \ git \ openssl \ sudo \ # Cleanup && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Install Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Configure PHP-FPM pool for performance RUN sed -i 's/pm = dynamic/pm = ondemand/' /etc/php/${PHP_VERSION}/fpm/pool.d/www.conf \ && sed -i 's/pm.max_children = .*/pm.max_children = 20/' /etc/php/${PHP_VERSION}/fpm/pool.d/www.conf \ && sed -i 's/;pm.process_idle_timeout = .*/pm.process_idle_timeout = 10s/' /etc/php/${PHP_VERSION}/fpm/pool.d/www.conf \ && sed -i 's/;pm.max_requests = .*/pm.max_requests = 500/' /etc/php/${PHP_VERSION}/fpm/pool.d/www.conf \ && sed -i 's/memory_limit = .*/memory_limit = 256M/' /etc/php/${PHP_VERSION}/fpm/php.ini \ && sed -i 's/upload_max_filesize = .*/upload_max_filesize = 20M/' /etc/php/${PHP_VERSION}/fpm/php.ini \ && sed -i 's/post_max_size = .*/post_max_size = 20M/' /etc/php/${PHP_VERSION}/fpm/php.ini \ && sed -i 's/max_execution_time = .*/max_execution_time = 60/' /etc/php/${PHP_VERSION}/fpm/php.ini # Configure PHP-FPM to log to file RUN sed -i "s|;error_log = log/php${PHP_VERSION}-fpm.log|error_log = /var/log/php${PHP_VERSION}-fpm.log|" /etc/php/${PHP_VERSION}/fpm/php-fpm.conf \ && sed -i 's|;catch_workers_output = yes|catch_workers_output = yes|' /etc/php/${PHP_VERSION}/fpm/pool.d/www.conf # Enable Apache modules for PHP-FPM RUN a2enmod rewrite \ && a2enmod headers \ && a2enmod expires \ && a2enmod ssl \ && a2enmod proxy \ && a2enmod proxy_fcgi \ && a2enmod setenvif \ && a2enmod remoteip \ && a2dismod mpm_prefork \ && a2enmod mpm_event \ && a2enconf php${PHP_VERSION}-fpm # Configure RemoteIP to trust load balancer RUN echo 'RemoteIPHeader X-Forwarded-For\n\ RemoteIPTrustedProxy 10.0.0.0/8\n\ RemoteIPTrustedProxy 172.16.0.0/12\n\ RemoteIPTrustedProxy 192.168.0.0/16\n\ RemoteIPTrustedProxy 100.64.0.0/10\n\ RemoteIPInternalProxy 10.0.0.0/8\n\ RemoteIPInternalProxy 172.16.0.0/12\n\ RemoteIPInternalProxy 192.168.0.0/16\n\ RemoteIPInternalProxy 100.64.0.0/10' > /etc/apache2/conf-available/remoteip.conf RUN a2enconf remoteip # Configure Apache to listen on port 80 RUN echo 'Listen 80' > /etc/apache2/ports.conf # Create Apache VirtualHost for Laravel RUN echo '\n\ ServerAdmin webmaster@localhost\n\ DocumentRoot /var/www/html/public\n\ \n\ \n\ Options -Indexes +FollowSymLinks\n\ AllowOverride All\n\ Require all granted\n\ \n\ \n\ \n\ SetHandler "proxy:unix:/run/php/php'${PHP_VERSION}'-fpm.sock|fcgi://localhost"\n\ \n\ \n\ ErrorLog ${APACHE_LOG_DIR}/error.log\n\ CustomLog ${APACHE_LOG_DIR}/access.log combined\n\ ' > /etc/apache2/sites-available/000-default.conf # Set ServerName to suppress warnings RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf # Set working directory WORKDIR /var/www/html # Copy application code COPY . . # Install PHP dependencies RUN composer install --no-dev --optimize-autoloader # Copy package files and install Node dependencies COPY package*.json ./ RUN npm ci # Complete Composer installation with autoloader optimization RUN composer dump-autoload --optimize --classmap-authoritative # Build frontend assets RUN npm run build # Clean up Node modules after build RUN rm -rf node_modules # Create necessary directories and set permissions RUN mkdir -p storage/framework/cache/data \ storage/framework/sessions \ storage/framework/views \ storage/logs \ bootstrap/cache \ database \ && touch storage/logs/laravel.log \ && chown -R www-data:www-data /var/www/html \ && chmod -R 775 storage bootstrap/cache database \ && chmod 664 storage/logs/laravel.log # Create PHP-FPM run directory RUN mkdir -p /run/php # Set up Laravel scheduler cron job RUN echo "* * * * * www-data cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1" > /etc/cron.d/laravel-cron \ && chmod 0644 /etc/cron.d/laravel-cron # Expose port 80 EXPOSE 80 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=5 \ CMD curl -f http://localhost/ || exit 1 # Copy and set up entrypoint script COPY docker-entrypoint.sh /var/www/html/docker-entrypoint.sh RUN chmod +x /var/www/html/docker-entrypoint.sh ENTRYPOINT ["/var/www/html/docker-entrypoint.sh"]