# Stage 1: Frontend Builder (Alpine-based) FROM node:20-alpine AS frontend-builder WORKDIR /app/frontend # Copy package files and install dependencies COPY frontend/package.json frontend/package-lock.json ./ COPY frontend/.npmrc ./ # Install all dependencies (needed for build) RUN npm ci # Copy source and build COPY frontend/ ./ RUN npm run build && \ # Remove source maps to save space find dist -name "*.map" -type f -delete && \ # Remove node_modules after build rm -rf node_modules # Stage 2: Python Dependencies (Slim-based) FROM python:3.13-slim AS python-builder WORKDIR /app # Install uv for fast package management COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv # Install build dependencies temporarily RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ g++ \ && rm -rf /var/lib/apt/lists/* # Copy pyproject.toml and install dependencies COPY backend/pyproject.toml . # Create virtual environment and install dependencies with uv RUN uv venv /opt/venv && \ . /opt/venv/bin/activate && \ uv pip install -r pyproject.toml # Stage 3: Final Runtime Image (Minimal) FROM python:3.13-slim # Install ONLY runtime dependencies (no build tools) RUN apt-get update && apt-get install -y --no-install-recommends \ # FFmpeg for audio processing ffmpeg \ # Curl for health checks curl \ # SQLite3 CLI for database maintenance sqlite3 \ # Clean up && rm -rf /var/lib/apt/lists/* \ && apt-get clean \ && rm -rf /tmp/* /var/tmp/* WORKDIR /app # Copy Python virtual environment from builder COPY --from=python-builder /opt/venv /opt/venv # Copy backend code (only what's needed) COPY backend/main.py ./backend/ COPY backend/alembic.ini ./backend/ COPY backend/alembic/ ./backend/alembic/ COPY backend/app/ ./backend/app/ # Copy startup scripts COPY backend/run-migrations.sh backend/start.sh backend/enable-wal.sh ./backend/ RUN chmod +x ./backend/*.sh # Copy frontend build from builder stage COPY --from=frontend-builder /app/frontend/dist ./backend/static # Create data directories RUN mkdir -p /app/data/music \ /app/data/uploads \ /app/data/temp \ /app/data/cache/artists \ /app/data/cache/artist_images # Environment variables ENV PATH="/opt/venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONPATH=/app/backend \ PYTHONDONTWRITEBYTECODE=1 \ MUSIC_DIR=/app/data/music \ UPLOAD_DIR=/app/data/uploads \ TEMP_DIR=/app/data/temp \ BASE_DIR=/app # Expose port EXPOSE 8000 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8000/ || exit 1 # Set working directory to backend WORKDIR /app/backend # Run migrations and start the application CMD ["/app/backend/start.sh"]