ARG NODE_VERSION=24 ARG PYTHON_VERSION=3.14 ############ # build ui # ############ ARG NODE_VERSION FROM node:${NODE_VERSION} AS build-ui # install ui dependencies WORKDIR /usr/local/src/advent22_ui RUN --mount=type=bind,source=ui/package.json,target=package.json \ --mount=type=bind,source=ui/yarn.lock,target=yarn.lock \ --mount=type=bind,source=ui/.yarn/releases,target=.yarn/releases \ --mount=type=bind,source=ui/.yarnrc.yml,target=.yarnrc.yml \ --mount=type=cache,id=ui,target=/root/.yarn \ \ yarn install --immutable --check-cache; # copy and build ui COPY ui ./ RUN --mount=type=cache,id=ui,target=/root/.yarn \ set -ex; \ \ yarn dlx update-browserslist-db@latest; \ yarn build --outDir /opt/advent22/ui; \ # exclude webpack-bundle-analyzer output rm -f /opt/advent22/ui/stats.html; ############### # install app # ############### ARG PYTHON_VERSION FROM dhi.io/python:${PYTHON_VERSION}-dev AS install-app COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ # env setup WORKDIR /opt/advent22 ENV UV_COMPILE_BYTECODE=1 \ UV_NO_DEV=1 \ UV_LINK_MODE="copy" RUN --mount=type=bind,source=api/uv.lock,target=api/uv.lock \ --mount=type=bind,source=api/pyproject.toml,target=api/pyproject.toml \ --mount=type=bind,source=api/.python-version,target=api/.python-version \ --mount=type=cache,id=api,target=/root/.cache/uv \ set -ex; \ \ # prepare data directory mkdir data; \ chown nobody:nobody data; \ chmod u=rwx,g=rx,o=rx data; \ \ # install api deps uv sync \ --project api/ \ --locked \ --no-install-project \ --no-editable \ ; # install api COPY api api/ RUN --mount=type=cache,id=api,target=/root/.cache/uv \ \ uv sync \ --project api/ \ --locked \ --no-editable \ ; # add prepared ui COPY --from=build-ui /opt/advent22/ui ui/ #################### # production image # #################### ARG PYTHON_VERSION FROM dhi.io/python:${PYTHON_VERSION} AS production ENV PATH="/opt/advent22/api/.venv/bin:$PATH" EXPOSE 8000 CMD [ "advent22" ] ARG PYTHON_VERSION COPY --from=install-app /opt/python/lib/python${PYTHON_VERSION} /opt/python/lib/python${PYTHON_VERSION}/ COPY --from=install-app /opt/advent22 /opt/advent22/ WORKDIR /opt/advent22/data VOLUME [ "/opt/advent22/data" ] # run as unprivileged user USER nobody