# How to Manage User and Group IDs for Correct File Permissions in the docker-icloudpd Container

> Learn to manage user and group IDs in docker-icloudpd for correct file permissions. Set IDs in icloudpd.conf to sync with host UID/GID and ensure proper file ownership.

- Repository: [boredazfcuk/docker-icloudpd](https://github.com/boredazfcuk/docker-icloudpd)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Set the `user_id` and `group_id` variables in [`/config/icloudpd.conf`](https://github.com/boredazfcuk/docker-icloudpd/blob/main//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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main//config/icloudpd.conf). On first start, [`init_config.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) populates this file with defaults, and on every subsequent start, [`launcher.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) via `write_variable user user` |
| `user_id` | UID for the container user | `1000` | Written by [`init_config.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) via `write_variable user_id 1000` |
| `group` | Primary group name | `group` | Written by [`init_config.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) via `write_variable group group` |
| `group_id` | GID for the primary group | `1000` | Written by [`init_config.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) via `write_variable group_id 1000` |

### User and Group Creation Process

During container initialization, [`launcher.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/launcher.sh) executes a strict sequence to establish the runtime identity:

1. **Security Validation**: The script explicitly forbids running as root inside the container. If `user_id=0` or `group_id=0` is detected, [`launcher.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/launcher.sh) forces the value to `1000` and logs a warning.

2. **Group Creation**: The `create_group` function initializes `/etc/group` and executes `groupadd --gid "${group_id}" "${group}"` to register the group with the specified GID.

3. **User Creation**: The `create_user` function prepares `/etc/passwd` and runs `useradd "${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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/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:

```bash
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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/init_config.sh) script captures these and persists them to [`/config/icloudpd.conf`](https://github.com/boredazfcuk/docker-icloudpd/blob/main//config/icloudpd.conf):

```bash
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:

```yaml
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:

```bash

# 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:

```bash
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_id` and `group_id` variables in [`/config/icloudpd.conf`](https://github.com/boredazfcuk/docker-icloudpd/blob/main//config/icloudpd.conf).
- The **[`launcher.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/launcher.sh)** script enforces non-root IDs (rejecting 0), creates the user/group with `useradd`/`groupadd`, and recursively `chown`s 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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main//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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/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:

```bash
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`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/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`.