A Docker-based backup service for iCloud Drive, iCloud Photos, iCloud Contacts and iCloud Calendars with a user-friendly web interface.
- Multi-Account Support – Manage and back up multiple iCloud accounts
- iCloud Drive Backup – Simple mode (folder selection via checkboxes) or advanced mode (manual path configuration)
- iCloud Photos Backup – Including optional family library
- iCloud Contacts Backup – Individual VCF files (vCard 3.0), combined VCF, and raw JSON with change detection
- iCloud Calendar Backup – Standard
.icsfiles per calendar viaicalendarlibrary (7-year date range) - Sync Policy – Choose per backup type what happens to locally deleted files: keep, delete, or archive to a dedicated mount
- Exclusions – Flexible exclusion patterns (glob patterns, paths)
- Scheduled Backups – Configurable via cron expressions
- 2FA Support – Two-factor authentication directly through the web UI (device push & SMS)
- Pushover Notifications – Push notifications for backup errors and expiring tokens via Pushover, configurable in the web UI
- Cached iCloud Storage – Storage breakdown is refreshed automatically after every backup and cached on disk
- Password Protection – Web UI secured with password authentication
- Dark Mode UI – Modern, responsive web interface
- Etag Caching – Only changed folders are re-scanned
- Live Progress – Real-time progress display during running backups
- Backup Duration – Shows end time (in your browser's timezone) and duration of the last backup
- Log Viewer – Built-in log viewer in the web interface
# Clone the repository
git clone https://github.com/michis0806/iCloud-Backup-Docker.git
cd iCloud-Backup-Docker
# Start the container
docker compose up -dThe web interface is available at: http://localhost:8080
On first startup, a random password is logged to the console:
docker logs icloud-backup
# Look for: "Kein AUTH_PASSWORD gesetzt. Generiertes Passwort: <your-password>"
To set a fixed password, add AUTH_PASSWORD to your environment (see Configuration).
Damit du auf der Synology sofort siehst, ob der richtige Build läuft:
# 1) Welche Image-Tags gibt es lokal?
docker images michis0806/icloud-backup-docker
# 2) Welche Build-Metadaten hat der laufende Container?
docker inspect icloud-backup --format '{{ index .Config.Env }}' | tr ' ' '\n' | rg '^APP_'
# 3) Was meldet die App selbst?
curl -s http://<NAS-IP>:8080/healthDie /health-Antwort enthält build.version, build.commit und build_date.
Zusätzlich wird die Version in der Web-UI im Footer angezeigt.
| Variable | Default | Description |
|---|---|---|
AUTH_PASSWORD |
(random, logged) | Password for the web UI. If not set, a random password is generated and printed to the log on startup. |
SECRET_KEY |
(uses AUTH_PASSWORD) | Secret for session cookie signing. Falls back to AUTH_PASSWORD if not set. |
WEB_PORT |
8080 |
Web UI port |
BACKUP_PATH |
./backups |
Host path for backup files |
ARCHIVE_PATH |
./archive |
Host path for archived files (used when sync policy is set to "archive") |
CONFIG_PATH |
./config |
Host path for configuration & sessions |
LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARNING, ERROR) |
TZ |
Europe/Berlin |
Timezone |
Notification settings (Pushover) are configured in the web UI under Einstellungen and stored in
/config/config.yaml. They are no longer set via environment variables.
| Container Path | Description |
|---|---|
/backups |
Backup destination directory |
/config |
Configuration, session tokens, etag caches |
/archive |
Archive directory for files removed from iCloud (when sync policy = "archive") |
version: "3.8"
services:
icloud-backup:
build: .
# Or use the pre-built image:
# image: michis0806/icloud-backup-docker:latest
container_name: icloud-backup
restart: unless-stopped
mem_limit: 512m
ports:
- "${WEB_PORT:-8080}:8080"
volumes:
- ${BACKUP_PATH:-./backups}:/backups
- ${CONFIG_PATH:-./config}:/config
- ${ARCHIVE_PATH:-./archive}:/archive
environment:
- TZ=${TZ:-Europe/Berlin}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
# Notifications (Pushover) are configured in the web UI
# under "Einstellungen" and stored in /config/config.yaml.
# - AUTH_PASSWORD=my-secure-password
# - SECRET_KEY=... # Optional; falls back to AUTH_PASSWORD if not set- Open the web interface and log in
- Click "Account hinzufügen" (Add Account)
- Enter your Apple ID and your regular account password (app-specific passwords are not supported by pyicloud)
- Confirm the 2FA code from your Apple device, or request an SMS code to a trusted phone number
- Click "Konfigurieren" (Configure) on the desired account
- Select backup types: iCloud Drive, Photos, Contacts, and/or Calendars
- Drive (Simple): Select folders via checkboxes
- Drive (Advanced): Enter paths manually (one path per line)
- Photos: Optionally include family library
- Contacts: Individual VCF files per contact + combined VCF + raw JSON backup
- Calendars: One
.icsfile per calendar with all events (5 years back, 2 years forward) - Sync policy (per Drive / Photos / Contacts): Choose what happens when files are deleted in iCloud:
- Keep – local files stay untouched (default for Photos)
- Delete – local files are removed (default for Drive)
- Archive – files are moved to the
/archivevolume, preserving the folder structure (default for Contacts)
- Define exclusions (e.g.
*.tmp,.DS_Store,node_modules)
- Manual: Click "Backup jetzt starten" (Start backup now)
- Automatic: Enable schedule with a cron expression (default: daily at 2:00 AM)
-
Install Container Manager from the DSM Package Center (if not already installed)
-
Create a project:
- Open Container Manager → Project → Create
- Project name:
icloud-backup - Path: choose a folder on the NAS (e.g.
/volume1/docker/icloud-backup) - Use the
docker-compose.ymlfrom this repository
-
Prepare volumes:
# Via SSH or File Station: mkdir -p /volume1/docker/icloud-backup/config mkdir -p /volume1/docker/icloud-backup/backups mkdir -p /volume1/docker/icloud-backup/archive -
Adjust docker-compose.yml (paths for Synology):
version: "3.8" services: icloud-backup: image: michis0806/icloud-backup-docker:latest container_name: icloud-backup restart: unless-stopped mem_limit: 512m ports: - "8080:8080" volumes: - /volume1/docker/icloud-backup/backups:/backups - /volume1/docker/icloud-backup/config:/config - /volume1/docker/icloud-backup/archive:/archive environment: - TZ=Europe/Berlin - AUTH_PASSWORD=my-secure-password
-
Start the project → Container Manager builds and starts the container
-
Open the web interface at
http://<NAS-IP>:8080
# Connect via SSH
ssh admin@<NAS-IP>
# Create directory and docker-compose.yml
mkdir -p /volume1/docker/icloud-backup && cd /volume1/docker/icloud-backup
# Create docker-compose.yml with the content above
# Start the container
sudo docker compose up -d- Open Portainer → Stacks → Add stack
- Name:
icloud-backup - Paste the
docker-compose.ymlcontents - Adjust paths as needed
- Deploy the stack
- Ports: If port 8080 is already in use, change it in
docker-compose.ymle.g."8085:8080" - Permissions: The container runs as root. Backup directories must be writable.
- Firewall: You may need to allow the port in the DSM firewall (Control Panel → Security → Firewall)
- Auto-start:
restart: unless-stoppedensures the container restarts automatically after a NAS reboot - Backup target: Consider using a shared folder that is also backed up with Synology Hyper Backup for a double backup
- 2FA session tokens expire after approximately 1 month (~30 days) and need to be renewed
- Use your regular Apple ID password. App-specific passwords do not work with pyicloud – the iCloud web services it uses reject them, so authentication will fail. Enter the normal account password; it is only used once for the initial login.
- The password is not stored – only pyicloud's session tokens in the
/config/sessionsdirectory - Etag cache files are stored in
/config/and significantly speed up repeated backups - Special characters in folder names: Folders with
#,%,?,&or+in their name may cause download errors. The backup service includes fallback strategies, but renaming the folder is the safest fix. - Memory limit: The container is configured with
mem_limit: 512mby default. For very large photo libraries you may need to increase this.
- Backend: Python / FastAPI
- Frontend: Bootstrap 5 / Alpine.js
- iCloud API: pyicloud
- Calendar: icalendar (ICS generation)
- Configuration: YAML (
/config/config.yaml) - Scheduler: APScheduler
MIT