services: kei: image: ghcr.io/rhoopr/kei:latest container_name: kei restart: unless-stopped stop_grace_period: 30s environment: - TZ=${TZ:-UTC} # The image sets MALLOC_ARENA_MAX=2 by default. Keep it unless you are # debugging allocator behavior; it keeps long-running watch containers # from reserving large amounts of virtual address space on glibc hosts. # - MALLOC_ARENA_MAX=2 # Put persistent settings in ./config/config.toml: # # [auth] # username = "you@example.com" # # [download] # directory = "/photos" # # ICLOUD_USERNAME remains supported for automation if you prefer env for # the account name: # - ICLOUD_USERNAME=${ICLOUD_USERNAME} # # Password via environment variable is least secure because it is visible # in `docker inspect`. kei removes it from the process environment after # reading, but prefer one of the credential options below. # - ICLOUD_PASSWORD=${ICLOUD_PASSWORD} # # PUID/PGID: drop privileges to the host user that owns ./config # and /path/to/photos. Required for NAS deployments (Synology # Container Manager, Unraid, TrueNAS Scale) so downstream # indexers (e.g. Synology Photos) can read kei's output. On # Synology, the typical values are PUID=1026 PGID=100. Without # these the container runs as root. # - PUID=1000 # - PGID=1000 # Both UID and GID are repaired recursively on /config and /photos # at every startup. This scans every inode, even when ownership matches. # For a large or pre-owned library, skip /photos repair and manage its # permissions on the host; /config is still repaired: # - KEI_CHOWN_PHOTOS=0 # # If [server].port differs from 9090, match it here for HEALTHCHECK: # - KEI_HEALTHCHECK_PORT=9091 volumes: - ./config:/config - /path/to/photos:/photos # Default command: # kei service run --config /config/config.toml # service run uses a 24h watch fallback when [watch].interval is unset. # If Apple returns a terminal auth error during SRP sign-in, kei exits 4 # and prints the account recovery or stored-password update steps. This # sample still restarts because restart: unless-stopped is set above; use # external monitoring if you want to alert on exit 4. # ── Credential options (pick one) ────────────────────────────── # # Option 1 (recommended): Encrypted credential store # First run: docker exec -it kei kei password set # Subsequent: kei decrypts from /config automatically on each re-auth. # # Option 2: Docker secrets (file-based) # secrets: # - icloud_password # command: >- # service run # --config /config/config.toml # --password-file /run/secrets/icloud_password # # Option 3: External secret manager (zero password on host) # command: >- # service run # --config /config/config.toml # --password-command "cat /run/secrets/icloud_password" # Uncomment for Docker secrets (Option 2): # secrets: # icloud_password: # file: ./icloud_password.txt