Unable to initialize pants in ubuntu:24.10 docker image
Describe the bug
My team is utilizing pants to package python executables for separate services in a monorepo microservice architecture of FastAPI ran on Ubuntu docker containers, locally using docker compose and deployed to GCP Cloud Run. We are attempting to create an integration testing solution where we can execute pants test :: on our repo code in a docker compose environment.
When we create out Docker images we create and run the containers as a less privileged user than root. We then attempt to run pants help goals against our repo code that was copied to the docker container, which doesnt cause an issue when running as root. however, when running pants help goals as the less privileged user we receive the following error...
` => ERROR [db-migration runner-image 12/12] RUN /usr/local/bin/pants help goals 30.0s
[db-migration runner-image 12/12] RUN /usr/local/bin/pants help goals: 9.920 Bootstrapping Pants 2.21.0 9.920 Installing pantsbuild.pants==2.21.0 into a virtual environment at /home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0 29.50 New virtual environment successfully created at /home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0 29.86 Traceback (most recent call last): 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/bin/pants", line 19, in
29.86 sys.exit(entry_point()) 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/bin/pants_loader.py", line 112, in main 29.86 PantsLoader.main() 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/bin/pants_loader.py", line 108, in main 29.86 cls.run_default_entrypoint() 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/bin/pants_loader.py", line 91, in run_default_entrypoint 29.86 exit_code = runner.run(start_time) 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/bin/pants_runner.py", line 84, in run 29.86 with initialize_stdio(global_bootstrap_options), stdio_destination( 29.86 File "/home/myuser/.cache/nce/67912efc04f9156d8f5b48a0348983defb964de043b8c13ddc6cc8a002f8e691/cpython-3.9.18+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz/python/lib/python3.9/contextlib.py", line 119, in enter 29.86 return next(self.gen) 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/init/logging.py", line 165, in initialize_stdio 29.86 with initialize_stdio_raw( 29.86 File "/home/myuser/.cache/nce/67912efc04f9156d8f5b48a0348983defb964de043b8c13ddc6cc8a002f8e691/cpython-3.9.18+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz/python/lib/python3.9/contextlib.py", line 119, in enter 29.86 return next(self.gen) 29.86 File "/home/myuser/.cache/nce/ab1acf935c4cc43338c604ae7d0f6aa2419f2415d94eb9cae381601dbba70a61/bindings/venvs/2.21.0/lib/python3.9/site-packages/pants/init/logging.py", line 202, in initialize_stdio_raw 29.86 raw_stdin, sys.stdout, sys.stderr = native_engine.stdio_initialize( 29.86 Exception: Could not initialize logging: Error opening pantsd logfile: Permission denied (os error 13)
failed to solve: process "/bin/sh -c /usr/local/bin/pants help goals" did not complete successfully: exit code: 1 `
This only occurs when running as the less privileged user and does not fail when running as root. Ideally I'd like to run a chown command to allow reads on the "pantsd logfile" that is unable to be accessed, but I'm not familiar with what or where that path is and the error logs don't give any indication of that path from what I can tell.
Whats also confusing is that our pants.toml file and our ubuntu image both are configured to use python 3.12 and the environment this is being ran is 3.9 according to the logs it seems.
I'd like some help possibly debugging this and some help with understanding best practices for installing the pants cli onto an ubuntu docker container.
Attached is a copy of our Dockerfile and pants.toml files.
Thanks! Nick
Pants version 2.21.0
OS ubuntu
Additional info Add any other information about the problem here, such as attachments or links to gists, if relevant.
Dockerfile ` # --platform=linux/amd64 needed for production # Later on separate dev to be platform agnostic and # prod would build linux/amd64 images # using ubuntu LTS version # https://luis-sena.medium.com/creating-the-perfect-python-dockerfile-51bdec41f1c8
# why are we using a builder-image? FROM --platform=linux/amd64 ubuntu:24.10 AS builder-image
# avoid stuck build due to user prompt
# why are we setting debian frontend? I thought we were using ubuntu... ARG DEBIAN_FRONTEND=noninteractive
# why are we installing python3.12-dev, python3.12-venv, gcc, and libpq-dev?
RUN apt-get update && apt-get install --no-install-recommends -y python3.12 python3.12-dev python3.12-venv gcc libpq-dev &&
apt-get clean && rm -rf /var/lib/apt/lists/*
# create and activate virtual environment # using final folder name to avoid path issues with packages RUN python3.12 -m venv /home/myuser/venv ENV PATH="/home/myuser/venv/bin:$PATH"
# install requirements COPY requirements.txt . RUN pip3 install --upgrade pip
RUN pip3 install --no-cache-dir -r requirements.txt
FROM --platform=linux/amd64 ubuntu:24.10 AS runner-image
RUN apt-get update && apt-get install --no-install-recommends -y python3.12 python3.12-dev python3.12-venv gcc libpq-dev &&
apt-get clean && rm -rf /var/lib/apt/lists/*
# need to install pants in order to execute integration test pants commands RUN apt-get update && apt-get -y install curl RUN mkdir -p /test/.cache/pants/lmdb_store/immutable/files RUN curl --proto '=https' --tlsv1.2 -fsSL https://static.pantsbuild.org/setup/get-pants.sh | bash -s -- --bin-dir /usr/local/bin
RUN useradd --create-home myuser RUN chown -R myuser /home/myuser/.cache/nce RUN chown -R myuser /test/.cache/pants/lmdb_store/immutable/files COPY --from=builder-image /home/myuser/venv /home/myuser/venv
RUN mkdir /home/myuser/app WORKDIR /home/myuser/app COPY . .
USER myuser RUN /usr/local/bin/pants help goals
EXPOSE 8080
# make sure all messages always reach console ENV PYTHONUNBUFFERED=1
# activate virtual environment ENV VIRTUAL_ENV=/home/myuser/venv ENV PATH="/home/myuser/venv/bin:/home/myuser/app:/home/myuser/app/src:$PATH"
ENV PYTHONPATH "${PYTHONPATH}:/home/myuser/app"
CMD [ "dist/src.foo/foo_app.pex" ] `
pants.toml ` [GLOBAL] pants_version = "2.21.0"
backend_packages = [ "pants.backend.python", "pants.backend.python.lint.black", "pants.backend.python.lint.flake8", "pants.backend.python.lint.isort", "pants.backend.build_files.fmt.black", ]
[python] interpreter_constraints = ["==3.12.*"]
[source] root_patterns = [ "src", ]
[test] use_coverage = true output = "all" force = true debug = true
[pytest] args = ["-vv -s --cache-clear"]
[flake8] config = ".flake8" `
This is just a file ownership problem. RUN mkdir /home/myuser/app and COPY . . are run as root, so is created as root. You never chown it. Simply move the USER myuser statement up to create that folder as myuser. (You also don't need to create the folder with RUN, having WORKDIR is sufficient (make sure it's after the USER))
Pants itself runs under python3.9, which is why you're seeing that.
minimal reproducer dockerfile:
FROM --platform=linux/amd64 ubuntu:24.10
RUN apt-get update && apt-get -y install curl
RUN curl --proto '=https' -fsSL https://static.pantsbuild.org/setup/get-pants.sh | bash -s -- --bin-dir /usr/local/bin
RUN useradd --create-home myuser
# this will make it work
# USER myuser
WORKDIR /home/myuser/app
COPY . .
# changing user this late makes it broken
USER myuser
RUN /usr/local/bin/pants help goals
also these statements don't seem necessary:
-
RUN mkdir -p /test/.cache/pants/lmdb_store/immutable/files -
RUN chown -R myuser /home/myuser/.cache/nce -
RUN chown -R myuser /test/.cache/pants/lmdb_store/immutable/files
Also do Environments cover your usecase of running integration tests in a docker container?
still receiving the same error, heres my updated dockerfile based on your feedback
`
FROM --platform=linux/amd64 ubuntu:24.10 AS runner-image
RUN apt-get update && apt-get install --no-install-recommends -y python3.12 python3.12-dev python3.12-venv gcc libpq-dev &&
apt-get clean && rm -rf /var/lib/apt/lists/*
# need to install pants in order to execute integration test pants commands RUN apt-get update && apt-get -y install curl RUN curl --proto '=https' --tlsv1.2 -fsSL https://static.pantsbuild.org/setup/get-pants.sh | bash -s -- --bin-dir /usr/local/bin
RUN useradd --create-home myuser USER myuser
WORKDIR /home/myuser/app COPY . .
RUN /usr/local/bin/pants help goals
CMD [ "dist/src.foo/foo_app.pex" ]`
ah, I see it now. COPY . . is copying the local context in. COPY operates as root unless --chown is passed. This includes the .pants.d directory, so the user in the container can't write to that dir. You probably want to add that to your .dockerignore, and probably the rest of the Pants paths that are in your gitignore.
that worked! Thanks for all the help.