app/.docker/production/Dockerfile

151 lines
4.9 KiB
Docker

# ============================================
# 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"]