ios-backup
Docker app from louij2's Repository
Overview
Readme
View on GitHubios-backup
Scheduled iPhone/iPad backups to your server, over Wi-Fi. No Mac, no Windows VM.
It writes standard Finder/iTunes (MobileBackup2) backups, so iMazing, Finder or iTunes can open them later, encrypted backups included. Under the hood it's pymobiledevice3.
- Pair once over USB. After that, on your schedule it finds the device on your LAN and runs an incremental backup through an encrypted RemotePairing tunnel, the Wi-Fi route Apple uses for iOS 17 and later. The older Wi-Fi sync route no longer works on current iOS.
- If the device is plugged into the server it uses USB instead, which is quicker for the first full backup.
- A device that's asleep or away is retried every
RETRY_MINUTESforRETRY_WINDOW_HOURS. - Status page and Prometheus
/metricson port 9871. Optional Discord alert when a backup fails.
Run
docker run -d --name ios-backup --network host --privileged --restart unless-stopped \
-v /dev/bus/usb:/dev/bus/usb -v /run/udev:/run/udev:ro \
-v /srv/ios-backups:/backups \
-v /srv/ios-backup/config:/config \
-v /srv/ios-backup/lockdown:/var/lib/lockdown \
-e TZ=Europe/London -e BACKUP_TIMES=03:00 \
louij2/ios-backup:latest
--network host is required for Bonjour discovery. --privileged is needed for the Wi-Fi
tunnel (a TUN interface) and for USB; /dev/bus/usb is only needed for pairing and USB backups. Unraid users can install it from
louij2/unraid-templates.
Pair a device (once)
- Plug the iPhone into the server and unlock it.
docker exec -it ios-backup ios-backup pair, then tap Trust and enter the passcode. This also creates the remote pairing that Wi-Fi backups need.- Optional but recommended: turn on encrypted backups. They also include saved
passwords, Health and Wi-Fi networks:
docker exec -it ios-backup ios-backup pmd3 backup2 encryption on 'YOUR-BACKUP-PASSWORD'Enter the passcode on the phone when it asks. Keep that password: you'll need it to open or restore the backup. - First backup now:
docker exec -it ios-backup ios-backup backup. A full backup over USB takes about 1 to 2 hours per 70 GB.
Then unplug it. From now on it backs up over Wi-Fi on your schedule.
Backups need approving on the phone. With encrypted backups on, iOS 26 shows a passcode prompt when a backup starts on a locked phone, and the backup waits until it's answered. So pick a time you usually have the phone (
BACKUP_DAYS=sun,BACKUP_TIMES=20:00) rather than the middle of the night. A Discord alert (DISCORD_WEBHOOK_URL) and theios_backup_waiting_for_passcodemetric tell you when it's waiting. Whether unencrypted backups skip the prompt is untested.
Private Wi-Fi Address: set it to Fixed (or Off) for your home network on the phone, under Settings → Wi-Fi → (i). A rotating address breaks Wi-Fi sync for every tool, Finder included.
Open the backups with iMazing (Mac)
- In Finder, connect to the share (Go → Connect to Server, e.g.
smb://tower/backups). - In iMazing, open Preferences → Backups and add the backups folder (the one that
holds the
<UDID>folders) as a backup location. - The device's backup shows up in iMazing's backup list. Browse messages, photos and so on, or restore from it. Enter the backup password if it's encrypted.
You can also browse without iMazing:
ios-backup pmd3 backup2 unback /backups/<UDID> --password ... (on a copy).
Configuration
| Variable | Default | |
|---|---|---|
BACKUP_TIMES |
03:00 |
Comma-separated HH:MM, container time zone (TZ) |
BACKUP_DAYS |
– (daily) | Comma-separated days, e.g. sun or mon,thu |
RETRY_MINUTES |
20 |
Retry interval while a device is unreachable |
RETRY_WINDOW_HOURS |
5 |
Stop retrying after this long |
BACKUP_TIMEOUT_HOURS |
8 |
Kill a stuck backup |
DISCORD_WEBHOOK_URL |
– | Alert on failures and when a backup needs approving |
NOTIFY_SUCCESS |
false |
Also post successes |
UDIDS |
– | Only back up these devices; the default is every paired device |
PORT |
9871 |
Status page + /metrics |
RUN_ON_START |
false |
Run a round when the container starts |
USBMUXD |
true |
false = Wi-Fi only |
PUID / PGID |
99 / 100 |
Owner of finished backups (Unraid's nobody:users) |
VERBOSE |
false |
Debug logging from pymobiledevice3 into each run's log |
Commands, all run with docker exec ios-backup ios-backup ...: pair, backup [UDID],
status, and pmd3 ... (passthrough to pymobiledevice3).
Metrics: ios_backup_last_success_timestamp_seconds, ios_backup_last_ok,
ios_backup_size_bytes, ios_backup_last_duration_seconds, ios_backup_running,
ios_backup_progress_percent, ios_backup_usb_connected, ios_backup_wifi_reachable,
ios_backup_waiting_for_passcode,
ios_backup_safe_to_unplug (0 only while a USB backup is running),
all labelled udid/name.
Security
/var/lib/lockdown holds the pair records, and they give full access to the paired
devices. Keep that folder private, and use encrypted backups.
Licence
MIT
Requirements
Categories
Download Statistics
Related apps
Explore more like this
Explore allDetails
louij2/ios-backup:latestRuntime arguments
- Web UI
http://[IP]:[PORT:9871]/- Network
host- Shell
bash- Privileged
- true
- Extra Params
--restart=unless-stopped
Template configuration
Each device gets a UDID folder in standard Finder/iTunes format
- Target
- /backups
- Default
- /mnt/user/backups/ios
- Value
- /mnt/user/backups/ios
State, logs
- Target
- /config
- Default
- /mnt/user/appdata/ios-backup
- Value
- /mnt/user/appdata/ios-backup
Device pair records - these grant full access to the paired devices; keep this folder private
- Target
- /var/lib/lockdown
- Default
- /mnt/user/appdata/ios-backup/lockdown
- Value
- /mnt/user/appdata/ios-backup/lockdown
For USB pairing and USB backups
- Target
- /dev/bus/usb
- Default
- /dev/bus/usb
- Value
- /dev/bus/usb
USB hotplug for usbmuxd
- Target
- /run/udev
- Default
- /run/udev
- Value
- /run/udev
Comma-separated HH:MM (container TZ). Unreachable devices are retried every RETRY_MINUTES for RETRY_WINDOW_HOURS.
- Target
- BACKUP_TIMES
- Default
- 03:00
- Value
- 03:00
Comma-separated days, e.g. sun or mon,thu. Blank = daily. Encrypted backups need approving on the phone, so pick a time you have it.
- Target
- BACKUP_DAYS
Timezone for the schedule
- Default
- Europe/London
- Value
- Europe/London
Status page and /metrics
- Target
- PORT
- Default
- 9871
- Value
- 9871
Optional: alert on failed backups and when a backup needs approving on the phone
- Target
- DISCORD_WEBHOOK_URL
true = also post successful backups
- Target
- NOTIFY_SUCCESS
- Default
- false
- Value
- false
- Target
- RETRY_MINUTES
- Default
- 20
- Value
- 20
- Target
- RETRY_WINDOW_HOURS
- Default
- 5
- Value
- 5
Optional comma list; default = every paired device
- Target
- UDIDS