diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bc9e4d3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,66 @@ +# FreeTable Backend Dockerfile +# Multi-stage build for production + +# ============== Builder Stage ============== +FROM python:3.11-slim as builder + +WORKDIR /app + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +COPY backend/requirements.txt . +RUN pip install --no-cache-dir --user -r requirements.txt + +# ============== Production Stage ============== +FROM python:3.11-slim + +WORKDIR /app + +# Install runtime dependencies only +RUN apt-get update && apt-get install -y --no-install-recommends \ + libpq5 \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user for security +RUN groupadd -r freetable && useradd -r -g freetable freetable + +# Copy installed packages from builder +COPY --from=builder /root/.local /home/freetable/.local + +# Copy application code +COPY --chown=freetable:freetable backend/app ./app +COPY --chown=freetable:freetable backend/requirements.txt . +COPY --chown=freetable:freetable backend/run.py . + +# Set environment variables +ENV PATH=/home/freetable/.local/bin:$PATH \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app + +# Switch to non-root user +USER freetable + +# Expose port +EXPOSE 8000 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8000/health || exit 1 + +# Run with Gunicorn for production +CMD ["sh", "-c", "pip install gunicorn --quiet && exec gunicorn app.main:app \ + --bind 0.0.0.0:8000 \ + --workers 2 \ + --threads 4 \ + --worker-class uvicorn.workers.UvicornWorker \ + --access-logfile - \ + --error-logfile - \ + --capture-output \ + --enable-stdio-inheritance"] \ No newline at end of file