Skip to content

michis0806/iCloud-Backup-Docker

Repository files navigation

iCloud Backup Docker

A Docker-based backup service for iCloud Drive, iCloud Photos, iCloud Contacts and iCloud Calendars with a user-friendly web interface.

Features

  • 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 .ics files per calendar via icalendar library (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

Quick Start

# Clone the repository
git clone https://github.com/michis0806/iCloud-Backup-Docker.git
cd iCloud-Backup-Docker

# Start the container
docker compose up -d

The 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).

Version & Build prüfen

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/health

Die /health-Antwort enthält build.version, build.commit und build_date. Zusätzlich wird die Version in der Web-UI im Footer angezeigt.

Configuration

Environment Variables

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.

Volumes

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")

docker-compose.yml

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

Usage

1. Add an Account

  • 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

2. Configure Backup

  • 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 .ics file 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 /archive volume, preserving the folder structure (default for Contacts)
  • Define exclusions (e.g. *.tmp, .DS_Store, node_modules)

3. Run Backup

  • Manual: Click "Backup jetzt starten" (Start backup now)
  • Automatic: Enable schedule with a cron expression (default: daily at 2:00 AM)

Installation on Synology NAS

Option 1: Container Manager (DSM 7.2+)

  1. Install Container Manager from the DSM Package Center (if not already installed)

  2. Create a project:

    • Open Container Manager → ProjectCreate
    • Project name: icloud-backup
    • Path: choose a folder on the NAS (e.g. /volume1/docker/icloud-backup)
    • Use the docker-compose.yml from this repository
  3. 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
  4. 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
  5. Start the project → Container Manager builds and starts the container

  6. Open the web interface at http://<NAS-IP>:8080

Option 2: Docker via SSH (DSM 7.x)

# 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

Option 3: Portainer (if installed)

  1. Open Portainer → StacksAdd stack
  2. Name: icloud-backup
  3. Paste the docker-compose.yml contents
  4. Adjust paths as needed
  5. Deploy the stack

Synology Tips

  • Ports: If port 8080 is already in use, change it in docker-compose.yml e.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-stopped ensures 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

Notes

  • 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/sessions directory
  • 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: 512m by default. For very large photo libraries you may need to increase this.

Tech Stack

  • Backend: Python / FastAPI
  • Frontend: Bootstrap 5 / Alpine.js
  • iCloud API: pyicloud
  • Calendar: icalendar (ICS generation)
  • Configuration: YAML (/config/config.yaml)
  • Scheduler: APScheduler

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages