[Python] How to build and run multi-stage Dockerfile using Chainguard python image...

Discussão em 'Python' iniciado por Stack, Maio 21, 2025.

  1. Stack

    Stack Membro Participativo

    With very limited knowledge of dockerfile writing, I have a dockerfile where in build stage I use uv to install the dependencies of my service via pyproject.toml but unable to successfully build and run:

    # Stage 1: Builder stage - using Chainguard Python dev container with UV
    FROM cgr.dev/chainguard/python:latest-dev AS builder

    # Set environment variables
    ENV LANG=C.UTF-8 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    UV_LINK_MODE=copy \
    UV_VENV=/app/.venv

    # Set working directory
    WORKDIR /app

    # Copy only dependency specifications first for better caching
    COPY services/predictor/pyproject.toml .

    # Create virtual environment (relocatable)
    RUN uv venv --relocatable $UV_VENV

    RUN uv pip install "legacy-cgi>=2.6.3; python_version >= '3.13'"

    # Generate lock file and install dependencies
    RUN uv lock && uv sync --locked

    # Copy remaining application code
    COPY services/predictor/ .

    # Stage 2: Runtime stage
    FROM cgr.dev/chainguard/python:latest

    # Set environment variables
    ENV PYTHONUNBUFFERED=1 \
    PATH="/app/.venv/bin:$PATH"

    # Set working directory and switch to non-root user
    WORKDIR /app
    USER nonroot:nonroot

    # Copy virtual environment and application code
    COPY --chown=nonroot:nonroot --from=builder /app/.venv /app/.venv
    COPY --chown=nonroot:nonroot --from=builder /app /app

    # Command to run the predictor service
    ENTRYPOINT ["python", "src/predictor/main.py"]


    Here is my pyproject.toml file:

    [project]
    name = "predictor"
    version = "0.1.0"
    description = "Add your description here"
    readme = "README.md"
    authors = [
    { name = "xx", email = "xx@users.noreply.github.com" }
    ]
    requires-python = ">=3.12"
    dependencies = [
    "loguru>=0.7.3",
    "evidently>=0.7.4",
    "great-expectations>=0.18.8",
    "lazypredict>=0.2.16",
    "mlflow>=2.22.0",
    "risingwave-py>=0.0.1",
    "scikit-learn>=1.6.1",
    "htmlmin2>=0.1.13",
    "ydata-profiling>=4.6.3",
    "optuna>=4.3.0",
    "pydantic>=2.0.0",
    "pydantic-settings>=2.0.0",
    ]

    [build-system]
    requires = ["hatchling"]
    build-backend = "hatchling.build"


    Here is the current error but I try to solve it using LLMs I get different error:

    => ERROR [builder 6/7] RUN uv lock && uv sync --locked 3.5s
    ------
    > [builder 6/7] RUN uv lock && uv sync --locked:
    3.435 × Failed to build `htmlmin==0.1.12`
    3.435 ├─▶ The build backend returned an error
    3.435 ╰─▶ Call to `setuptools.build_meta:__legacy__.build_wheel` failed (exit
    3.435 status: 1)
    3.435
    3.435 [stderr]
    3.435 Traceback (most recent call last):
    3.435 File "<string>", line 14, in <module>
    3.435 requires = get_requires_for_build({})
    3.435 File
    3.435 "/home/nonroot/.cache/uv/builds-v0/.tmpfCTrF5/lib/python3.13/site-packages/setuptools/build_meta.py",
    3.435 line 331, in get_requires_for_build_wheel
    3.435 return self._get_build_requires(config_settings, requirements=[])
    3.435 ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    3.435 File
    3.435 "/home/nonroot/.cache/uv/builds-v0/.tmpfCTrF5/lib/python3.13/site-packages/setuptools/build_meta.py",
    3.435 line 301, in _get_build_requires
    3.435 self.run_setup()
    3.435 ~~~~~~~~~~~~~~^^
    3.435 File
    3.435 "/home/nonroot/.cache/uv/builds-v0/.tmpfCTrF5/lib/python3.13/site-packages/setuptools/build_meta.py",
    3.435 line 512, in run_setup
    3.435 super().run_setup(setup_script=setup_script)
    3.435 ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
    3.435 File
    3.435 "/home/nonroot/.cache/uv/builds-v0/.tmpfCTrF5/lib/python3.13/site-packages/setuptools/build_meta.py",
    3.435 line 317, in run_setup
    3.435 exec(code, locals())
    3.435 ~~~~^^^^^^^^^^^^^^^^
    3.435 File "<string>", line 4, in <module>
    3.435 sys.path.pop(0)
    3.435 ~~~~~~~~~~~~^^^
    3.435 File
    3.435 "/home/nonroot/.cache/uv/sdists-v9/pypi/htmlmin/0.1.12/bBKQO8_Em8IEyD8Blau4W/src/htmlmin/__init__.py",
    3.435 line 28, in <module>
    3.435 from .main import minify, Minifier
    3.435 File
    3.435 "/home/nonroot/.cache/uv/sdists-v9/pypi/htmlmin/0.1.12/bBKQO8_Em8IEyD8Blau4W/src/htmlmin/main.py",
    3.435 line 28, in <module>
    3.435 import cgi
    3.435 ModuleNotFoundError: No module named 'cgi'
    3.435
    3.435 hint: This usually indicates a problem with the package or the build
    3.435 environment.
    3.435 help: `htmlmin` (v0.1.12) was included because `predictor` (v0.1.0)
    3.435 depends on `ydata-profiling>=4.6.3` (v4.16.1) which depends on
    3.435 `htmlmin==0.1.12`
    ------ predictor.Dockerfile:23
    -------------------- 21 | 22 | # Generate lock file and install dependencies 23 | >>> RUN uv lock && uv sync --locked 24 | 25 | # Copy remaining application code
    -------------------- ERROR: failed to solve: process "/bin/sh -c uv lock && uv sync --locked" did not complete successfully: exit code: 1


    How to have a multi-stage build dockerfile such that I can use secure chainguard python image for dockerizing such service? I tried a lot but unable to find a concrete runnable solution for months

    Continue reading...

Compartilhe esta Página