Skip to content

Commit 6d7ebb0

Browse files
committed
🔨 Fix Docker permission errors with bind mounts
Bind-mounted project dirs failed on `buildozer init` with permission denied because container UID/GID didn't match the host. Add a lean entrypoint that maps the container user to the host UID/GID execs buildozer, fixing writes to `/home/user/hostcwd`. See command used and error output: ``` docker run --volume "$(pwd)":/home/user/hostcwd kivy/buildozer init Traceback (most recent call last): File "/home/user/.venv/bin/buildozer", line 8, in <module> sys.exit(main()) ^^^^^^ File "/home/user/.venv/lib/python3.12/site-packages/buildozer/scripts/client.py", line 16, in main Buildozer().run_command(sys.argv[1:]) File "/home/user/.venv/lib/python3.12/site-packages/buildozer/__init__.py", line 672, in run_command getattr(self, cmd)(*args) File "/home/user/.venv/lib/python3.12/site-packages/buildozer/__init__.py", line 711, in cmd_init buildops.file_copy(join(dirname(__file__), 'default.spec'), 'buildozer.spec') File "/home/user/.venv/lib/python3.12/site-packages/buildozer/buildops.py", line 108, in file_copy copyfile(source, target) File "/usr/lib/python3.12/shutil.py", line 262, in copyfile with open(dst, 'wb') as fdst: ^^^^^^^^^^^^^^^ PermissionError: [Errno 13] Permission denied: 'buildozer.spec' ```
1 parent fe16e3e commit 6d7ebb0

File tree

5 files changed

+53
-15
lines changed

5 files changed

+53
-15
lines changed

.github/workflows/docker.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ jobs:
5656
tags: ${{ env.DOCKERHUB_IMAGE }}:latest
5757
# Run the locally built image to test it
5858
- name: Docker run
59-
run: docker run ${{ env.DOCKERHUB_IMAGE }} --version
59+
run: |
60+
docker run ${{ env.DOCKERHUB_IMAGE }} --version
61+
docker run --rm --volume "$PWD":/home/user/hostcwd ${{ env.DOCKERHUB_IMAGE }} init
6062
6163
update-readme:
6264
runs-on: ubuntu-24.04

.github/workflows/test_python.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
steps:
6969
- uses: actions/checkout@v5
7070
- name: Requirements
71-
run: pip install -U sphinx sphinxawesome_theme
71+
run: pip install --upgrade sphinx sphinxawesome_theme
7272
- name: Check links
7373
run: sphinx-build -b linkcheck docs/source docs/build
7474
- name: Generate documentation

Dockerfile

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# In order to give the container access to your current working directory
1111
# it must be mounted using the --volume option.
1212
# Run with (e.g. `buildozer --version`):
13-
# docker run \
13+
# docker run --interactive --tty --rm \
1414
# --volume "$HOME/.buildozer":/home/user/.buildozer \
1515
# --volume "$PWD":/home/user/hostcwd \
1616
# kivy/buildozer --version
@@ -70,19 +70,16 @@ RUN apt update -qq > /dev/null \
7070
zip \
7171
zlib1g-dev
7272

73-
# prepares non root env
74-
RUN useradd --create-home --shell /bin/bash ${USER}
75-
# with sudo access and no password
76-
RUN usermod -append --groups sudo ${USER}
77-
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
73+
# Create home directory and virtual environment
74+
RUN mkdir -p ${HOME_DIR} \
75+
&& python3 -m venv ${HOME_DIR}/.venv
7876

79-
USER ${USER}
8077
WORKDIR ${WORK_DIR}
81-
COPY --chown=user:user . ${SRC_DIR}
78+
COPY . ${SRC_DIR}
79+
COPY --chmod=755 entrypoint.sh /usr/local/bin/entrypoint.sh
8280

8381
# installs buildozer and dependencies from a virtual environment
8482
ENV PATH="${HOME_DIR}/.venv/bin:${PATH}"
85-
RUN python3 -m venv ${HOME_DIR}/.venv && \
86-
pip3 install --upgrade "Cython<3.0" wheel pip ${SRC_DIR}
83+
RUN pip install --upgrade "Cython<3.0" wheel pip ${SRC_DIR}
8784

88-
ENTRYPOINT ["buildozer"]
85+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,19 @@ docker buildx build --platform=linux/amd64 --tag=kivy/buildozer .
7575
- Run with:
7676

7777
```bash
78-
docker run --volume "$(pwd)":/home/user/hostcwd kivy/buildozer --version
78+
docker run --interactive --tty --rm \
79+
--volume "$PWD":/home/user/hostcwd \
80+
kivy/buildozer --version
7981
```
8082

8183
### Example Build with Caching
8284
- Build and keep downloaded SDK and NDK in `~/.buildozer` directory:
8385

8486
```bash
85-
docker run -v $HOME/.buildozer:/home/user/.buildozer -v $(pwd):/home/user/hostcwd kivy/buildozer android debug
87+
docker run --interactive --tty --rm \
88+
--volume "$PWD":/home/user/hostcwd \
89+
--volume "$HOME/.buildozer":/home/user/.buildozer \
90+
kivy/buildozer android debug
8691
```
8792

8893
The image is published to both Docker Hub and GitHub Container Registry and can be pulled from both:

entrypoint.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
# Map container user to host UID/GID (from /home/user/hostcwd) so writes to the
3+
# bind-mounted project work. Then exec Buildozer from the venv as that user.
4+
5+
set -euo pipefail
6+
7+
DEFAULT_USER_NAME="user"
8+
DEFAULT_USER_HOME="/home/$DEFAULT_USER_NAME"
9+
10+
# Read UID/GID from bind mount; default to 1000:1000 if absent
11+
HOST_UID="$(stat -c %u "$DEFAULT_USER_HOME/hostcwd" 2>/dev/null || echo 1000)"
12+
HOST_GID="$(stat -c %g "$DEFAULT_USER_HOME/hostcwd" 2>/dev/null || echo 1000)"
13+
14+
# Create group with host GID if it doesn't exist
15+
if ! getent group $HOST_GID > /dev/null 2>&1; then
16+
groupadd --gid $HOST_GID hostgroup
17+
fi
18+
19+
# Check if UID already exists
20+
if getent passwd $HOST_UID > /dev/null 2>&1; then
21+
# UID exists, get the existing username
22+
USER_NAME="$(getent passwd $HOST_UID | cut -d: -f1)"
23+
else
24+
# UID doesn't exist, create new user
25+
USER_NAME="$DEFAULT_USER_NAME"
26+
useradd --uid $HOST_UID --gid $HOST_GID --home "$DEFAULT_USER_HOME" --shell /bin/bash --no-create-home "$DEFAULT_USER_NAME"
27+
fi
28+
29+
# Ensure home directory and venv ownership
30+
chown --recursive $HOST_UID:$HOST_GID "$DEFAULT_USER_HOME"
31+
32+
# Switch to the user and execute buildozer
33+
BUILDOZER="$DEFAULT_USER_HOME/.venv/bin/buildozer"
34+
exec sudo --preserve-env --user "$USER_NAME" HOME="${DEFAULT_USER_HOME}" PATH="$DEFAULT_USER_HOME/.venv/bin:$PATH" -- "$BUILDOZER" "$@"

0 commit comments

Comments
 (0)