Skip to content

icloud-photos-sync Logo

iCloud Photos Sync

GitHub release (latest by date) npm Docker Pulls

Back up your complete iCloud Photos Library to your own disk or NAS, and keep it in sync.
Runs unattended in Docker. A small web UI handles the Apple sign-in, including MFA codes and Advanced Data Protection.

Quick start · Get Started guide · CLI reference


Quick start

You need Docker with docker compose and an Apple ID with two-factor authentication.

1. Create a folder for the library and a docker-compose.yml next to it.

mkdir library
services:
  photos-sync:
    image: steilerdev/icloud-photos-sync:latest
    container_name: photos-sync
    restart: unless-stopped
    user: "1000:1000"                  # your user's `id -u`:`id -g`, needs write access to ./library
    environment:
      APPLE_ID_USER: "<iCloud username>"
      APPLE_ID_PWD: "<iCloud password>"
      TZ: "Europe/Berlin"
      SCHEDULE: "0 2 * * *"            # sync every night at 2:00
      ENABLE_CRASH_REPORTING: true     # optional, helps fixing bugs
    ports:
      - 80:80                          # web UI
    volumes:
      - ./library:/opt/icloud-photos-library

2. Start it.

docker compose up -d

3. Sign in through the web UI. Open http://<your-host> and select Renew Authentication. Apple sends a code to your trusted devices; enter it in the web UI. Then select Sync Now to start the first sync, or wait for the schedule.

That's it. From now on the library syncs on the schedule. Apple asks for a new MFA code about every 30 days: select Enable Notifications in the web UI to get a push notification when that happens.

Good to know:

  • Advanced Data Protection: turn on Access iCloud Data on the Web and approve the request that shows up on your device during the first sync. See Advanced Data Protection.
  • No plain-text password: use APPLE_ID_PWD_FILE with Docker secrets, or leave the password out and enter it on startup. See Installation.
  • Large libraries: the first sync of a large library takes hours and may need a higher open-file limit. See Ad-Hoc Sync.

Where are my photos? Every photo and video is in library/_All-Photos (and library/_Shared-Photos for the iCloud Shared Library), named by its iCloud checksum. Your iCloud folders and albums appear as folders next to it, linking to those files. A readable, date-based layout with the original file names is planned for v6 (#354).

Without Docker: npm install -g icloud-photos-sync (Node.js 26 or newer), then run icloud-photos-sync --help. See the Get Started guide for all options.

Features

  • Complete library: all originals plus their edits, the iCloud Shared Photo Library and, optionally, the Hidden album
  • Your folders and albums mirrored locally, without storing any photo twice
  • Advanced Data Protection supported
  • MFA made easy: codes through trusted devices, SMS or voice, entered in the web UI. The trust token is cached, so syncs run unattended for about 30 days.
  • Efficient incremental sync: only new and changed assets are downloaded; large libraries are supported
  • Web UI: sync status, ad-hoc syncs, live logs and push notifications. It can be installed as an app (PWA).
  • Safe deletes: assets deleted in iCloud can go to a trash folder instead of being removed
  • Archiving: keep an album locally forever and, optionally, delete its non-favorite photos from iCloud to free up storage
  • Monitoring: Influx and Prometheus metrics, health check pings
  • Secure operation: credentials from files (Docker secrets), shell-free image based on Docker Hardened Images, optional Node.js permission model

icloud-photos-sync is an independent project, and is not affiliated, endorsed, recommended by or otherwise affiliated with Apple Inc.

Why

The only official way to keep a local copy of the full library is a Mac that keeps Photos.app running with Download Originals enabled, and those files can't easily be used outside Photos.app. This project syncs the library to a plain folder on any Linux host or NAS. Read more about the motivation and the maintainer's own workflow.

Documentation

Limitations

This application uses an undocumented iCloud API, which comes with a few limitations:

  • Live Photos: only the still image is synced, not the video part (#121).
  • iCloud Shared Photo Library: the API doesn't tell where shared assets sit in your folders and albums. Shared assets therefore only appear in _Shared-Photos and can't be archived.
  • File types: supported file types are hard-coded, because no complete list is available. If you see an Unknown filetype descriptor warning, please report it.
  • Security keys can't be used as the second factor.

Please also check the open and known issues and existing feature requests.

OS Support

The Docker image is available for linux/amd64 and linux/arm64. The npm package runs wherever Node.js 26 runs, except Windows.

OS Support Debian OS Support Ubuntu OS Support MacOS OS Support Windows

Contributing & Feedback

Please check the contributing guidelines to learn how to engage with this project.

Test Coverage (Lines) Test Coverage (Functions) Code of Conduct

Acknowledgments

Special thanks to: - @konraddysput for help on the Backtrace integration. - @timvahlbrock for their interest in this project and contributions in getting it updated. - All current and past sponsors of this project.

Release Workflow

Nightly Release Status Beta Release Status Production Release Status

Monitoring Workflow

API Status