127 lines
No EOL
3 KiB
Docker
127 lines
No EOL
3 KiB
Docker
# Build stage - Install dependencies and build wheels
|
|
FROM python:3.11-slim AS builder
|
|
|
|
# Install build dependencies
|
|
RUN apt-get update && apt-get install -y \
|
|
build-essential \
|
|
curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Poetry
|
|
RUN pip install poetry==1.8.2
|
|
|
|
# Set Poetry configuration
|
|
ENV POETRY_NO_INTERACTION=1 \
|
|
POETRY_VENV_IN_PROJECT=1 \
|
|
POETRY_CACHE_DIR=/tmp/poetry_cache
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy dependency files
|
|
COPY pyproject.toml poetry.lock ./
|
|
|
|
# Install dependencies into venv
|
|
RUN poetry config virtualenvs.in-project true && \
|
|
poetry lock --no-update || true && \
|
|
poetry install --only=main --no-root && \
|
|
rm -rf $POETRY_CACHE_DIR
|
|
|
|
# Base runtime stage
|
|
FROM python:3.11-slim AS base
|
|
|
|
# Install runtime system dependencies
|
|
RUN apt-get update && apt-get install -y \
|
|
ffmpeg \
|
|
curl \
|
|
tini \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& apt-get clean
|
|
|
|
# Create non-root user
|
|
RUN groupadd --gid 1000 app \
|
|
&& useradd --uid 1000 --gid app --shell /bin/bash --create-home app
|
|
|
|
# Set working directory
|
|
WORKDIR /app
|
|
|
|
# Copy virtual environment from builder stage
|
|
COPY --from=builder --chown=app:app /app/.venv /app/.venv
|
|
|
|
# Ensure venv is in PATH
|
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
|
|
# Copy application code
|
|
COPY --chown=app:app . .
|
|
|
|
# Switch to non-root user
|
|
USER app
|
|
|
|
# Production API stage
|
|
FROM base AS production
|
|
|
|
# Set environment variables for production
|
|
ENV APP_ENV=prod \
|
|
PYTHONPATH=/app \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
CMD curl -f http://localhost:8000/health || exit 1
|
|
|
|
# Expose port
|
|
EXPOSE 8000
|
|
|
|
# Use tini as init system for proper signal handling
|
|
ENTRYPOINT ["tini", "--"]
|
|
|
|
# Default command for API server
|
|
CMD ["gunicorn", "-c", "gunicorn_conf.py"]
|
|
|
|
# Worker stage for Celery workers
|
|
FROM base AS worker
|
|
|
|
# Set environment variables for worker
|
|
ENV APP_ENV=prod \
|
|
PYTHONPATH=/app \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
C_FORCE_ROOT=1
|
|
|
|
# Health check for worker (check if Celery is responding)
|
|
HEALTHCHECK --interval=60s --timeout=15s --start-period=10s --retries=3 \
|
|
CMD python -c "from celery import Celery; app=Celery('app'); print('Worker healthy')" || exit 1
|
|
|
|
# Use tini as init system for proper signal handling
|
|
ENTRYPOINT ["tini", "--"]
|
|
|
|
# Default command for Celery worker
|
|
CMD ["celery", "-A", "app.tasks", "worker", "--loglevel=info", "--concurrency=1"]
|
|
|
|
# Development stage with dev dependencies
|
|
FROM builder AS development
|
|
|
|
# Install all dependencies including dev
|
|
RUN poetry install --no-root && rm -rf $POETRY_CACHE_DIR
|
|
|
|
# Install additional dev tools
|
|
RUN apt-get update && apt-get install -y \
|
|
git \
|
|
vim \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy application code
|
|
COPY --chown=app:app . .
|
|
|
|
# Switch to non-root user
|
|
USER app
|
|
|
|
# Set environment for development
|
|
ENV APP_ENV=dev \
|
|
PYTHONPATH=/app \
|
|
PYTHONUNBUFFERED=1
|
|
|
|
EXPOSE 8000
|
|
|
|
# Development command with hot reload
|
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] |