How to Manage User and Group IDs for Correct File Permissions in the docker-icloudpd Container
Set the user_id and group_id variables in /config/icloudpd.conf to match your host user's UID and GID, and the container will automatically create a local Linux user and enforce ownership on all downloaded iCloud files.
The boredazfcuk/docker-icloudpd container creates a dedicated local user to own all downloaded photos and videos. By aligning this container-side user's UID and GID with your host system, you eliminate permission conflicts on bind-mounted volumes and ensure seamless read-write access from the host.
How the Container Handles User and Group IDs
The permission system relies on four core variables stored in /config/icloudpd.conf. On first start, init_config.sh populates this file with defaults, and on every subsequent start, launcher.sh reads these values to construct the container's user environment.
Configuration Variables
| Variable | Purpose | Default | Source |
|---|---|---|---|
user |
Container-side username | user |
Written by init_config.sh via write_variable user user |
user_id |
UID for the container user | 1000 |
Written by init_config.sh via write_variable user_id 1000 |
group |
Primary group name | group |
Written by init_config.sh via write_variable group group |
group_id |
GID for the primary group | 1000 |
Written by init_config.sh via write_variable group_id 1000 |
User and Group Creation Process
During container initialization, launcher.sh executes a strict sequence to establish the runtime identity:
-
Security Validation: The script explicitly forbids running as root inside the container. If
user_id=0orgroup_id=0is detected,launcher.shforces the value to1000and logs a warning. -
Group Creation: The
create_groupfunction initializes/etc/groupand executesgroupadd --gid "${group_id}" "${group}"to register the group with the specified GID. -
User Creation: The
create_userfunction prepares/etc/passwdand runsuseradd "${user}" --uid "${user_id}" --gid "${group_id}"to create the user with the configured UID mapped to the previously created group.
Permission Enforcement on Download Directories
After user creation, launcher.sh invokes permission-setting functions (such as set_owner_and_permissions_downloads) to ensure the download trees match the configured identity. The script walks download_path, jpeg_path, and video_path, executing chown and chmod operations:
find "${download_path}" ! -type l ! -user "${user_id}" -exec chown "${user_id}" {} +
find "${download_path}" -type d -exec chmod "${directory_permissions}" '{}' +
find "${download_path}" -type f -exec chmod "${file_permissions}" '{}' +
All files subsequently created by the iCloud downloader (/opt/icloudpd/bin/icloudpd) inherit this container-side UID/GID, which the host kernel interprets directly on bind-mounted volumes.
Step-by-Step Configuration Examples
Docker Run with Environment Variables
Pass the IDs as environment variables on the first run. The init_config.sh script captures these and persists them to /config/icloudpd.conf:
docker run -d \
--name icloudpd \
-e TZ=Europe/London \
-e USER=user \
-e USER_ID=1000 \
-e GROUP=users \
-e GROUP_ID=1000 \
-v icloudpd_config:/config \
-v /home/youruser/iCloud:/home/user/iCloud \
boredazfcuk/icloudpd
Docker Compose Configuration
The repository provides an example compose file. Specify the IDs under the environment key:
version: "3.8"
services:
icloudpd:
image: boredazfcuk/icloudpd
container_name: icloudpd
environment:
TZ: Europe/London
USER_ID: 1000
GROUP_ID: 1000
volumes:
- icloudpd_config:/config
- /home/youruser/iCloud:/home/user/iCloud
restart: unless-stopped
volumes:
icloudpd_config:
Manual Configuration File Editing
If the container has already initialized, edit the configuration directly:
# Extract the config file, edit, and replace
docker cp icloudpd:/config/icloudpd.conf ./icloudpd.conf
cat > ./icloudpd.conf <<EOF
user=user
user_id=1000
group=group
group_id=1000
download_path=/home/user/iCloud
EOF
docker cp ./icloudpd.conf icloudpd:/config/icloudpd.conf
docker restart icloudpd
Verifying Permissions from the Host
After the container restarts, confirm the ownership aligns with your host user:
ls -ln /home/youruser/iCloud
You should see file ownership set to 1000 1000 (or whatever UID/GID you configured). If the IDs match your host user's /etc/passwd entry, you will have full read-write access without sudo.
Summary
- The docker-icloudpd container creates a local Linux user inside the container to own all downloaded files.
- UID and GID are controlled via the
user_idandgroup_idvariables in/config/icloudpd.conf. - The
launcher.shscript enforces non-root IDs (rejecting 0), creates the user/group withuseradd/groupadd, and recursivelychowns the download directories. - Matching the container's UID/GID to the host user's IDs ensures seamless file access on bind-mounted volumes without permission errors.
Frequently Asked Questions
What happens if I set USER_ID or GROUP_ID to 0?
The container explicitly forbids running as root for security reasons. If launcher.sh detects user_id=0 or group_id=0 in the configuration, it forcibly rewrites the value to 1000 and logs a warning. This prevents the downloader from executing with elevated privileges inside the container.
Can I change the UID/GID after the container has already downloaded files?
Yes. Simply update the user_id and group_id values in /config/icloudpd.conf (either by editing the file directly or passing new environment variables if the config hasn't been persisted yet) and restart the container. The launcher.sh script will detect the change and recursively chown all files in the download, JPEG, and video directories to the new ownership.
How do I find my host user's UID and GID to match the container?
Run the id command on your host system:
id yourusername
The output will show uid=1000(yourusername) and gid=1000(yourgroupname). Use these numeric values for the USER_ID and GROUP_ID environment variables (or in icloudpd.conf) so the container creates files that your host user naturally owns.
Why does the container create a local user instead of using the host's user directly?
Docker containers run isolated from the host's user database. The container cannot directly reference host UIDs/GIDs by name, but the Linux kernel maps numeric IDs directly between container and host on bind-mounted volumes. By creating a local user with the same numeric UID/GID as the host user, the container ensures file ownership appears correct on both sides without requiring privileged access to the host's /etc/passwd.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →