android-backup

android-backup

Docker app from louij2's Repository

Overview

Backs up Android phones and tablets to your array over ADB, with no root and no app on the device. Plug a device in, or give it a Wi-Fi address, and it gets one backup per day: shared storage (photos, downloads, documents), every user-installed APK, contacts as vCard, SMS and call log in SMS Backup & Restore format, and settings. Files deleted on the phone are kept in the backup. Private app data (logins, app databases) can't be backed up without root. Status page + Prometheus /metrics on port 9872, optional Discord alerts.

android-backup

Backs up your Android phones and tablets to your server over ADB. No root and no app on the device. Plug a device in and it's backed up, or give it the device's Wi-Fi address.

Any authorised device that's connected gets one backup every BACKUP_INTERVAL_HOURS (default 24), so a drawer full of old phones only needs plugging in one at a time.

What you get

<backups>/<model>-<serial>/

Folder Contents Restore with
files/ Everything in shared storage: photos, downloads, documents, Android/media, Android/data Copy back
apks/<package>/<versionCode>/ Every user-installed app, including split APKs adb install-multiple
snapshots/<date>/contacts.vcf Contacts, without photos Any contacts app
snapshots/<date>/sms.xml, calls.xml SMS text messages and call log SMS Backup & Restore format
snapshots/<date>/ Package list, settings, getprop Reference
  • files/ never deletes. A file deleted on the phone stays in the backup, so the folder only grows. A file changed on the phone overwrites the old copy.
  • The last KEEP_SNAPSHOTS days of snapshots are kept (default 30).
  • A file is copied again if its size or modification time has changed. Unplugging mid-run is safe, and the next run picks up where it left off.

What it can't do

Private app data can't be backed up without root. That means logins, app databases and chat histories kept inside apps. adb backup doesn't help: Android 12 and later exclude almost every app from it. After a restore, apps come back but start logged out. Apps that keep their own exports in shared storage are covered by files/.

MMS messages and contact photos aren't included. The backups aren't encrypted, so keep them on a private share. snapshots/ holds your messages and contacts in plain text.

Run

docker run -d --name android-backup --restart unless-stopped -p 9872:9872 \
  --device-cgroup-rule='c 189:* rmw' -v /dev/bus/usb:/dev/bus/usb \
  -v /srv/android-backups:/backups \
  -v /srv/android-backup/config:/config \
  -e TZ=Europe/London \
  louij2/android-backup:latest

The device-cgroup rule and the /dev/bus/usb mount let devices be plugged in at any time without --privileged.

Add a device over USB

  1. On the device, open Settings > About and tap Build number seven times.
  2. In Developer options, turn on USB debugging.
  3. Also turn on Disable adb authorization timeout, if it's there. Otherwise Android forgets the server after 7 days without a connection and asks again.
  4. Plug it in and tap Allow with "Always allow" ticked. The status page shows when a device is waiting for this.

Check it worked with docker exec android-backup android-backup adb devices -l.

Add a device over Wi-Fi

Authorise it over USB first, then:

docker exec android-backup android-backup adb -s <serial> tcpip 5555

Add <device ip>:5555 to ADB_TARGETS. Android forgets tcpip 5555 when it reboots, so repeat that command after a reboot. Anyone on the network can then reach the device's ADB port, but they still can't use it unless the device has authorised their key.

Settings

Variable Default
BACKUP_INTERVAL_HOURS 24 Minimum time between good backups of a device
RETRY_MINUTES 60 Wait after a failed attempt
ADB_TARGETS Comma list of host:port to connect to
SERIALS Comma list; only back up these devices
EXCLUDE caches, thumbnails, Android/obb/ Regex matched against paths relative to /sdcard
KEEP_SNAPSHOTS 30 Dated snapshots to keep per device
DISCORD_WEBHOOK_URL Alert on failed backups
NOTIFY_SUCCESS false Also post successful backups
PUID / PGID 99 / 100 Owner of the finished backup

Status and metrics

  • http://server:9872/: status page with a "Back up now" button per device
  • /metrics: Prometheus, including android_backup_last_success_timestamp_seconds, android_backup_last_ok, android_backup_files_failed and android_backup_safe_to_unplug
  • POST /api/backup?serial=<serial>: start a backup; leave out serial for every connected device

Command line

docker exec android-backup android-backup backup [serial...]
docker exec android-backup android-backup status
docker exec android-backup android-backup adb devices -l

License

MIT

Requirements

USB debugging turned on on each device, and "Allow" tapped once when it's first connected.

Download Statistics

64
Total Downloads

Related apps

Explore more like this

Explore all

Details

Repository
louij2/android-backup:latest
Last Updated2026-11-05
First Seen2026-11-05

Runtime arguments

Web UI
http://[IP]:[PORT:9872]/
Network
bridge
Shell
bash
Privileged
false
Extra Params
--restart=unless-stopped --device-cgroup-rule='c 189:* rmw'

Template configuration

Web UIPorttcp

Status page and /metrics

Target
9872
Default
9872
Value
9872
BackupsPathrw

Each device gets a model-serial folder. It holds messages and contacts in plain text, so use a private share.

Target
/backups
Default
/mnt/user/backups/android
Value
/mnt/user/backups/android
ConfigPathrw

State, logs and the adb key devices trust; keep this folder private

Target
/config
Default
/mnt/user/appdata/android-backup
Value
/mnt/user/appdata/android-backup
USB devicesPathrw

For devices plugged into the server

Target
/dev/bus/usb
Default
/dev/bus/usb
Value
/dev/bus/usb
Backup interval (hours)Variable

Minimum time between good backups of a device

Target
BACKUP_INTERVAL_HOURS
Default
24
Value
24
Wi-Fi devicesVariable

Optional comma list of host:port, e.g. 192.168.1.50:5555. See the README for setup.

Target
ADB_TARGETS
TZVariable

Timezone for logs and snapshot dates

Default
Europe/London
Value
Europe/London
Discord webhookVariable

Optional: alert on failed backups

Target
DISCORD_WEBHOOK_URL
Notify on successVariable

true = also post successful backups

Target
NOTIFY_SUCCESS
Default
false
Value
false
Retry minutesVariable

Wait after a failed attempt

Target
RETRY_MINUTES
Default
60
Value
60
Snapshots to keepVariable

Dated contacts/SMS/settings snapshots per device

Target
KEEP_SNAPSHOTS
Default
30
Value
30
Only these serialsVariable

Optional comma list; default = every authorised device

Target
SERIALS