82 lines
3.0 KiB
Docker
82 lines
3.0 KiB
Docker
# Base image
|
|
FROM python:3.11-slim AS base
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
|
PIP_NO_CACHE_DIR=on
|
|
|
|
WORKDIR /app
|
|
|
|
# System deps (build tools + libpq for Postgres)
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
build-essential gcc g++ curl netcat-traditional libpq-dev git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Build context is uploader-bot/, so use paths relative to it
|
|
# Copy dependency manifest if exists; otherwise generate minimal requirements
|
|
COPY ./requirements.txt /app/requirements.txt
|
|
RUN if [ ! -s /app/requirements.txt ]; then \
|
|
echo "fastapi==0.104.1" >> /app/requirements.txt && \
|
|
echo "uvicorn[standard]==0.24.0" >> /app/requirements.txt && \
|
|
echo "pydantic==2.4.2" >> /app/requirements.txt && \
|
|
echo "pydantic-settings==2.0.3" >> /app/requirements.txt && \
|
|
echo "SQLAlchemy==2.0.23" >> /app/requirements.txt && \
|
|
echo "alembic==1.12.1" >> /app/requirements.txt && \
|
|
echo "asyncpg==0.29.0" >> /app/requirements.txt && \
|
|
echo "redis==5.0.1" >> /app/requirements.txt && \
|
|
echo "aiofiles==23.2.1" >> /app/requirements.txt && \
|
|
echo "python-jose[cryptography]==3.3.0" >> /app/requirements.txt && \
|
|
echo "python-multipart==0.0.6" >> /app/requirements.txt && \
|
|
echo "httpx==0.25.2" >> /app/requirements.txt && \
|
|
echo "websockets==12.0" >> /app/requirements.txt && \
|
|
echo "docker==6.1.3" >> /app/requirements.txt && \
|
|
echo "structlog==23.2.0" >> /app/requirements.txt && \
|
|
echo "ed25519==1.5" >> /app/requirements.txt ; \
|
|
fi
|
|
|
|
# Install python deps
|
|
RUN pip install --upgrade pip setuptools wheel \
|
|
&& pip install -r /app/requirements.txt
|
|
|
|
# Copy application code (relative to uploader-bot/)
|
|
COPY ./app /app/app
|
|
COPY ./alembic /app/alembic
|
|
COPY ./alembic.ini /app/alembic.ini
|
|
|
|
# Optional files: bootstrap and keys if they exist (do not fail build)
|
|
# Use a shell step to copy conditionally
|
|
RUN mkdir -p /app/keys && \
|
|
if [ -f "/app/bootstrap.json" ]; then :; \
|
|
elif [ -f "/workspace/bootstrap.json" ]; then cp /workspace/bootstrap.json /app/bootstrap.json || true; \
|
|
elif [ -f "/src/bootstrap.json" ]; then cp /src/bootstrap.json /app/bootstrap.json || true; \
|
|
fi
|
|
|
|
# Runtime dirs and user
|
|
RUN mkdir -p /app/storage /app/logs \
|
|
&& adduser --disabled-password --gecos "" appuser \
|
|
&& chown -R appuser:appuser /app
|
|
USER appuser
|
|
|
|
# Expose API port
|
|
EXPOSE 8000
|
|
|
|
# Healthcheck script to avoid adding curl dependency
|
|
RUN printf '%s\n' \
|
|
"#!/usr/bin/env python3" \
|
|
"import sys,urllib.request" \
|
|
"try:" \
|
|
" with urllib.request.urlopen('http://127.0.0.1:8000/health',timeout=2) as r:" \
|
|
" sys.exit(0 if r.getcode()==200 else 1)" \
|
|
"except Exception:" \
|
|
" sys.exit(1)" > /app/healthcheck.py && chmod +x /app/healthcheck.py
|
|
|
|
# Environment defaults (overridable)
|
|
ENV HOST=0.0.0.0 \
|
|
PORT=8000 \
|
|
UVICORN_HOST=0.0.0.0 \
|
|
UVICORN_PORT=8000
|
|
|
|
# Start command
|
|
CMD ["uvicorn", "app.fastapi_main:app", "--host", "0.0.0.0", "--port", "8000"] |