# syntax=docker/dockerfile:1.9 ### Start build prep. ### This should be a separate build container for better reuse. FROM mcr.microsoft.com/playwright/python:v1.52.0-noble AS build # The following does not work in Podman unless you build in Docker # compatibility mode: # You can manually prepend every RUN script with `set -ex` too. SHELL ["sh", "-exc"] # Ensure apt-get doesn't open a menu ENV DEBIAN_FRONTEND=noninteractive COPY --from=ghcr.io/astral-sh/uv:0.7.2 /uv /usr/local/bin/uv # - Silence uv complaining about not being able to use hard links, # - tell uv to byte-compile packages for faster application startups, # - prevent uv from accidentally downloading isolated Python builds, # - pick a Python, and finally declare `/app` as the target for `uv sync`. ENV UV_LINK_MODE=copy \ UV_COMPILE_BYTECODE=1 \ UV_PYTHON_DOWNLOADS=never \ UV_PYTHON=python3.12 \ UV_PROJECT_ENVIRONMENT=/app # Synchronize DEPENDENCIES without the application itself. # This layer is cached until uv.lock or pyproject.toml change, which are # only temporarily mounted into the build container since we don't need # them in the production one. # You can create `/app` using `uv venv` in a separate `RUN` # step to have it cached, but with uv it's so fast, it's not worth # it, so we let `uv sync` create it for us automagically. RUN --mount=type=cache,target=/root/.cache \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync \ --locked \ --no-dev \ --no-install-project # Now install the rest from `/src`: The APPLICATION w/o dependencies. # `/src` will NOT be copied into the runtime container. COPY . /src WORKDIR /src RUN --mount=type=cache,target=/root/.cache \ uv sync \ --locked \ --no-dev \ --no-editable ### End build prep ########################################################################## FROM mcr.microsoft.com/playwright/python:v1.52.0-noble SHELL ["sh", "-exc"] ENV PATH=/app/bin:$PATH ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 ENV HOME=/app WORKDIR /app # Don't run app as root RUN <. STOPSIGNAL SIGINT COPY --from=build --chown=app:app /app /app COPY --chown=app:app --chmod=700 /scripts/entrypoint.sh /entrypoint.sh COPY --chown=app:app --chmod=700 /scripts/deploy.sh /deploy.sh ENTRYPOINT ["/entrypoint.sh"] RUN mkdir -p /app/.cursor-server && chown app:app /app /app/.cursor-server USER app EXPOSE 8000 HEALTHCHECK CMD curl --fail http://localhost:8000/health/ || exit 1 CMD ["granian", "--interface", "wsgi", "pkmntrade_club.django_project.wsgi", "--host", "0.0.0.0", "--port", "8000", "--workers", "1", "--respawn-failed-workers", "--workers-kill-timeout", "60"]