iOS Backup Machine
Offline, portable and automatic iPhone backup system running entirely on a Radxa Zero 3W (an upgraded Raspberry Pi Zero W).
When you plug in your iPhone, the system automatically runs an encrypted idevicebackup2 backup to local storage, shows progress and messages on an e-ink display, and logs all activity locally — no iCloud, no iTunes, you own your data.
NEW! Check out apple-juicer is an iOS backup explorer
If you want to inspect the backups created by this device, use Apple Juicer, a browser-based iOS backup explorer. Point it at your backup directory, unlock encrypted backups (password prompt), and browse parsed artifacts such as WhatsApp, Messages, (implementation ongoing: Photos, Notes, Calendar, and Contacts) with search/filter in a web UI.
- Repository: https://github.com/giovi321/apple-juicer
- Documentation: https://giovi321.github.io/apple-juicer/
Objective
A self-contained iOS backup appliance with no reliance on Apple services or computers.
All backups stay local on the microSD card and can be restored anytime using tools from libimobiledevice.
Key features
- Fully automated: starts as soon as an iPhone is plugged in.
- Live feedback: e-ink shows progress, status, and errors.
- Secure: backups use the iPhone’s own encryption credentials.
- Offline and independent: no Apple ID, no iTunes, no Internet.
- Solid: file corruption is prevented by a small UPS.
How it works
Normal operation
- Turn on the iOS Backup Machine (press once the UPS's power button and then keep pressed until all LEDs light up)
- Wait for the boot to complete (you will see a screen refresh)
- Plug in your iPhone → the backup starts automatically.
- The display:
- prompts to unlock the phone if needed
- shows encryption status
- shows progress percentage
- At the end:
- displays success confirmation and timestamp
- shows owner info (persistent on screen even after power off or power loss)
In case you unplug the iPhone the process stops safely and the screen shows the interruption timestamp.
Interactive functions
- If you push the additional button of the PiSugar UPS, it shows for 10 seconds on the e-ink the last backup timestamp and available memory. After 10 seconds it goes back to owner information.
- More to be implemented
UPS integration
- Battery protection: backup stops cleanly if battery <30%.
- Safe shutdown: power loss or UPS switch-off triggers graceful shutdown.
- Prevents data corruption during unexpected disconnections.
General behavior
- Errors appear directly on the display.
- Logs are written under
/var/log/iosbackupmachine/. - On boot, owner info is displayed.
- When idle, the screen shows last backup result, timestamp, disk usage, and owner info.
Hardware
| Component | Purpose | Rationale |
|---|---|---|
| Radxa Zero 3W (8GB eMMC) | Main controller | eMMC is faster and more reliable than a microSD |
| Waveshare 2.13" e-Paper HAT V4 (250×122) | Status display | Persistent output, readable, low power |
| PiSugar 3 | UPS and safe shutdown | Prevents corruption on power loss |
| MicroSD card | Backup storage | Dedicated storage separate from OS |
| 3D printed case | --- | Based on the design by PiSugar and edited for this purpose |
Software
| Component | Role |
|---|---|
| Armbian (Trixie) | Base OS |
| Python 3.13 | Runtime for backup and display scripts |
| libimobiledevice | iPhone communication (idevicebackup2, idevicepair) |
| udev + systemd | Automation and event handling |
Directory layout
/root/
├── 90-iosbackupmachine.rules # Starts backup on iPhone plug-in and stops it when unplugged
├── armbianEnv.txt # Overlays for SPI/I2C
├── Case ios backup machine_v8.stl # 3D printable case
├── config.yaml # Main configuration
├── epdconfig.py # Display configuration
├── iosbackupmachine_launcher.sh # Launch script
├── iosbackupmachine.py # Main program
├── iosbackupmachine.service # Systemd service triggered by udev
├── last-backup.py # Shows last backup info and memory available
├── last-backup.service # Systemd service for above
├── owner-message.py # Shows owner info on the e-ink screen
├── owner-message.service # Systemd service for above
├── [pisugar]config.json # UPS configuration template
├── rtc-sync.service # Syncs the Radxa Zero clock to the RTC at boot
├── shutdown.sh # Shows owner info on screen and turns off device
├── UbuntuMono-Regular.ttf # Font for the display, you can choose your own
├── unplug-notify.py # Handle unplug events
├── unplug-notify.service # Service triggered by unplug rule
└── unplug-notify.sh # Script to call unplug-notify.py
Configuration
Edit /root/config.yaml:
backup_dir: /media/iosbackup/ # where the backup is saved marker_file: .foldermarker # file that tells the script that the microSD card was mounted correctly. if this file is missing, then the microSD card is not mounted and the backup will not run. disk_device: /dev/mmcblk1 # name of the microSD card node, needed to measure the space utilization at the end of the backup orientation: landscape_right # Choose screen orientation (landscape_left or landscape_right) font_path: "/root/UbuntuMono-Regular.ttf" # Choose the font you prefer. Test it first as not all fonts render well on e-ink displays owner_lines: # You can write whatever you wans as long as it fits in the screen (there are no automatic line breaks) - "Property of Titius Caius" - "+33 123 456 7890" - "write@titiuscaius.com" - "Reward if found €€€" error_codes: # No need to change anything below this line
Notes
- The
.foldermarkerfile confirms the SD card is mounted correctly. - Edit
owner_linesto customize contact info shown on the e-ink display. disk_deviceallows monitoring disk usage after backup.
Installation
1. Flash Armbian on the Radxa Zero 3W
Follow the Radxa Zero 3W official guide.
In short:
apt install rkdeveloptool rkdeveloptool db rk356x_spl_loader_ddr1056_v1.12.109_no_check_todly.bin xz -d Armbian_community_25.11.0-trunk.334_Radxa-zero3_trixie_vendor_6.1.115_minimal.img.xz rkdeveloptool wl 0 Armbian_community_25.11.0-trunk.334_Radxa-zero3_trixie_vendor_6.1.115_minimal.img rkdeveloptool rd
2. Enable I2C and SPI
Edit /boot/armbianEnv.txt:
overlays=rk3568-spi3-m1-cs0-spidev rk3568-i2c3-m0
overlay_prefix=rk35xx
Reboot.
3. Install dependencies
apt update apt install -y python3 python3-venv python3-pil python3-periphery libimobiledevice-1.0-6 libimobiledevice-utils usbmuxd
4. Create Python virtual environment
python3 -m venv /root/iosbackupmachine
source /root/iosbackupmachine/bin/activate
pip install Pillow pyyaml python-periphery
deactivate5. Clone repositories and install drivers
cd /root
git clone https://github.com/waveshareteam/e-Paper.git
git clone https://github.com/giovi321/ios-backup-machine.git
cp ios-backup-machine/epdconfig.py e-Paper/RaspberryPi_JetsonNano/python/lib/waveshare_epd/Link the driver into the venv (adjust Python version if needed):
ln -s /root/e-Paper/RaspberryPi_JetsonNano/python/lib/waveshare_epd /root/iosbackupmachine/lib/python3.13/site-packages/
6. Install systemd and udev integrations
cp ios-backup-machine/*.rules /etc/udev/rules.d/ cp ios-backup-machine/*.service /etc/systemd/system/ systemctl daemon-reload systemctl enable boot-message udevadm control --reload-rules
7. Prepare backup storage
mkdir -p /media/iosbackup touch /media/iosbackup/.foldermarker
8. Configure PiSugar UPS
Install from official script and add out config file:
wget https://cdn.pisugar.com/release/pisugar-power-manager.sh bash pisugar-power-manager.sh -c release rm /etc/pisugar-server/config.json cp /root/ios-backup-machine/[pisugar]config.json /etc/pisugar-server/config.json
Set the time of the RTC based on the current time of the Radxa Zero:
apt install netcat-traditional echo "rtc_pi2rtc" | nc -q 1 127.0.0.1 8423
Automatically set the time of the Radxa Zero based on the RTC time at every boot
systemctl enable rtc-sync.serviceFirst run
The first run must be done using idevicebackup2 "stand alone" because you need to set the backup encryption passphrase.
Disable the udev rule 90-iosbackupmachine.rules to prevent the program from starting
mv /etc/udev/rules.d/90-iosbackupmachine.rules /etc/udev/rules.d/90-iosbackupmachine.rules.disabled
udevadm control --reload-rules
plug your iOS device and run
idevicebackup2 encryption on /media/iosbackup
idevicebackup2 backup --full /media/iosbackup
It is going to take quite a lot of time, depending on the memory and memory usage of your iOS device. Now you can re-enable the udev rule to autostart the backup when you plug the iPhone:
mv /etc/udev/rules.d/90-iosbackupmachine.rules.disabled /etc/udev/rules.d/90-iosbackupmachine.rules
udevadm control --reload-rules
Restoring a backup
To restore a backup simply plug your iOS device in a computer, plug the microSD card in the same computer and run:
idevicebackup2 restore --password <your backup password> /media/sdcard/iosbackup/
Logs
All logs are stored under /var/log/iosbackupmachine/.
Each run creates a file:
backup-YYYYMMDD-HHMMSS.log
New features to be implemented
- Add partial refresh of the display (only when showing the backup progress percentage)
- Use iPhone hotspot over USB to give the iOS backup machine internet connectivity
- Add MQTT reporting of backup
- Filter iOS devices connected (i.e., start the backup only when a certain iPhone is connected)
- Add web interface?
License
MIT License
Includes code adapted from Waveshare’s e-Paper library.

