# ============================================ # Dish Planner - All-in-One Production Image # ============================================ # This Dockerfile creates a single container with: # - MySQL 8.0 database # - PHP 8.2-FPM (Laravel backend) # - Node.js 20 (React Router frontend) # - Nginx (reverse proxy) # - Supervisor (process manager) # # Build: docker build -f .docker/production/Dockerfile -t codeberg.org/lvl0/dish-planner:latest . # Deploy: See .docker/production/README.md for deployment instructions # ============================================ FROM ubuntu:22.04 # Prevent interactive prompts during build ENV DEBIAN_FRONTEND=noninteractive ENV TZ=UTC # ============================================ # Install System Dependencies # ============================================ RUN apt-get update && apt-get install -y \ # Basic utilities curl \ wget \ git \ unzip \ ca-certificates \ gnupg \ supervisor \ software-properties-common \ # Nginx nginx \ # MySQL Server mysql-server \ && rm -rf /var/lib/apt/lists/* # ============================================ # Install PHP 8.2 from ondrej/php PPA # ============================================ RUN add-apt-repository ppa:ondrej/php -y \ && apt-get update \ && apt-get install -y \ php8.2-fpm \ php8.2-cli \ php8.2-mysql \ php8.2-mbstring \ php8.2-xml \ php8.2-bcmath \ php8.2-curl \ php8.2-zip \ php8.2-gd \ php8.2-intl \ && rm -rf /var/lib/apt/lists/* # ============================================ # Install Node.js 20 # ============================================ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/* # ============================================ # Install Composer # ============================================ COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # ============================================ # Set up working directories # ============================================ WORKDIR /var/www # Create necessary directories RUN mkdir -p /var/www/backend \ /var/www/frontend \ /var/www/storage/logs \ /var/lib/mysql \ /run/php # ============================================ # Copy and Build Backend (Laravel) # ============================================ COPY backend /var/www/backend WORKDIR /var/www/backend # Remove any existing .env files - they will be created at runtime RUN rm -f .env .env.production # Install PHP dependencies (production) RUN composer install --no-dev --optimize-autoloader --no-interaction # Set permissions for Laravel RUN chown -R www-data:www-data /var/www/backend/storage /var/www/backend/bootstrap/cache \ && chmod -R 775 /var/www/backend/storage /var/www/backend/bootstrap/cache # Add www-data to mysql group so it can access MySQL socket RUN usermod -a -G mysql www-data # ============================================ # Copy and Build Frontend (React Router) # ============================================ COPY frontend /var/www/frontend WORKDIR /var/www/frontend # Install all dependencies (including dev for build), build, then remove dev deps RUN npm ci \ && npm run build \ && npm prune --production # ============================================ # Configure Nginx # ============================================ COPY .docker/production/nginx.conf /etc/nginx/sites-available/default RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default \ && rm -f /etc/nginx/sites-enabled/default.old # ============================================ # Configure PHP-FPM # ============================================ RUN sed -i 's/listen = \/run\/php\/php8.2-fpm.sock/listen = 127.0.0.1:9000/' /etc/php/8.2/fpm/pool.d/www.conf # ============================================ # Configure MySQL # ============================================ # Allow MySQL to bind to all interfaces (for easier debugging if needed) RUN sed -i 's/bind-address.*/bind-address = 127.0.0.1/' /etc/mysql/mysql.conf.d/mysqld.cnf || true # ============================================ # Copy Configuration Files # ============================================ COPY .docker/production/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY .docker/production/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # ============================================ # Create volume mount points # ============================================ VOLUME ["/var/lib/mysql", "/var/www/backend/storage"] # ============================================ # Expose HTTP port # ============================================ EXPOSE 80 # ============================================ # Set entrypoint and default command # ============================================ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]