File size: 1,553 Bytes
b02f059
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3de8669
 
 
b02f059
 
3de8669
b02f059
 
 
 
3de8669
b02f059
 
3de8669
b02f059
3de8669
 
b02f059
 
 
3de8669
76cb83f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# ==========================================
# Builder Stage
# ==========================================
FROM python:3.13-slim AS builder

# Keep runtime behavior predictable and logs visible in container environments.
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    UV_COMPILE_BYTECODE=1

WORKDIR /app

# Install uv for fast dependency management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

COPY pyproject.toml uv.lock ./

RUN --mount=type=cache,target=/root/.cache \
    uv sync --locked --no-dev --no-install-project

# ==========================================
# Runtime Stage
# ==========================================
FROM python:3.13-slim AS runtime

WORKDIR /app

# Runtime uses a non-root user.
RUN useradd --create-home --shell /usr/sbin/nologin app

# Copy dependencies and application code
COPY --from=builder --chown=app:app /app/.venv /app/.venv
COPY --chown=app:app src ./src
COPY --chown=app:app assets ./assets

# Ensure runtime entrypoints stay executable
RUN find /app/.venv/bin -type f -exec chmod 755 {} +

USER app
EXPOSE 8501

# Same endpoint as compose: verifies the server responds (slim has no curl).
HEALTHCHECK --interval=30s --timeout=5s --start-period=45s --retries=3 \
    CMD ["/app/.venv/bin/python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8501/_stcore/health', timeout=5).read()"]

CMD ["/app/.venv/bin/python", "-m", "streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0", "--server.enableXsrfProtection=false"]