28 lines
1.3 KiB
Docker
28 lines
1.3 KiB
Docker
# Staging-only standalone ASGI container.
|
|
# The test stage gates the final image: build fails if HTTP/security regressions fail.
|
|
FROM python:3.11-slim AS api-base
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONPATH=/app/src/api \
|
|
PORT=10000
|
|
WORKDIR /app
|
|
COPY deploy/docker/api-requirements.txt /tmp/api-requirements.txt
|
|
RUN python -m pip install --no-cache-dir -r /tmp/api-requirements.txt \
|
|
&& useradd --system --uid 10001 --create-home bearingapi
|
|
COPY --chown=bearingapi:bearingapi src/api/ /app/src/api/
|
|
|
|
FROM api-base AS verify-api
|
|
RUN python -m pip install --no-cache-dir pytest==9.0.2 httpx==0.28.1
|
|
COPY tests/test_api_startup_safety.py /app/tests/test_api_startup_safety.py
|
|
RUN python -m pytest -q /app/tests/test_api_startup_safety.py \
|
|
&& printf 'PASS: FastAPI HTTP/CORS/analogue safeguards\n' > /tmp/api-verified.txt
|
|
|
|
FROM api-base AS runtime
|
|
COPY --from=verify-api /tmp/api-verified.txt /tmp/api-verified.txt
|
|
USER bearingapi
|
|
EXPOSE 10000
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
CMD python -c "import os; from urllib.request import urlopen; urlopen('http://127.0.0.1:'+os.getenv('PORT','10000')+'/health',timeout=3).close()" || exit 1
|
|
CMD ["sh", "-c", "exec uvicorn main:app --app-dir src/api --host 0.0.0.0 --port ${PORT:-10000} --proxy-headers"]
|