# syntax=docker/dockerfile:1 # UwuDash MK3 - one process serves the UI, the JSON API and the reverse proxy. # # docker build -t uwudash-mk3 . # docker run -d -p 8000:8000 -v uwudash-data:/app/data uwudash-mk3 # # Two stages: the wheel is built from the src layout, then installed into a venv # in a clean image, so the runtime layer carries no build tooling and no second # copy of the source. data/ is a volume: the services store, users.json and # widgets.json live there, so edits survive a restart and the host's internal URLs # never get baked into a layer. ARG PYTHON_VERSION=3.11 # ---------------------------------------------------------------- build wheel FROM python:${PYTHON_VERSION}-slim AS build WORKDIR /app # README.md is part of this layer because pyproject.toml declares # `readme = "README.md"`, which uv_build embeds into the wheel metadata. COPY pyproject.toml uv.lock README.md /app/ # Pinned: pyproject.toml requires the uv_build backend in >=0.13.5,<0.14.0, so an # unpinned upgrade to uv 0.14 would break `uv build` against this manifest. RUN pip install --no-cache-dir "uv==0.13.5" COPY src/uwudash_mk3 /app/src/uwudash_mk3 RUN uv build --out-dir /app/dist # ------------------------------------------------------------------- runtime FROM python:${PYTHON_VERSION}-slim AS runtime WORKDIR /app ENV PYTHONUNBUFFERED=1 \ UWUDASH_HOST=0.0.0.0 \ UWUDASH_PORT=8000 \ UWUDASH_DATA_DIR=/app/data COPY --from=build /app/dist/*.whl /tmp/wheels/ RUN pip install --no-cache-dir "uv==0.13.5" \ && uv venv /app/.venv \ && uv pip install --python /app/.venv/bin/python --no-cache /tmp/wheels/*.whl \ && rm -rf /tmp/wheels \ && useradd -m -u 10001 appuser \ && mkdir -p /app/data \ && chown -R appuser:appuser /app \ && chmod -R g=u /app USER appuser EXPOSE 8000 VOLUME /app/data # /health is the only route that needs no session, so it works with OIDC on. # The port is read from the environment because UWUDASH_PORT is the knob users # actually turn; the hardcoded default matches the ENV above. HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD ["python", "-c", "import os,sys,urllib.request as r;sys.exit(0 if r.urlopen(f'http://127.0.0.1:{os.environ.get(\"UWUDASH_PORT\", \"8000\")}/health').status==200 else 1)"] ENTRYPOINT ["/app/.venv/bin/uwudash-mk3"]