Deploy APKs to your Android devices over the network, from a web interface.
275
Deploy APKs to your Android devices over the network, from a web interface.
Push an APK to your Android TVs, set-top boxes and phones with a single link, or let APK Installer install every new GitHub release automatically on the devices you choose. Built for sideloaded apps that are not on the Play Store, on devices you don't want to plug in.
.apk, or to an archive (.zip, .tar.gz…) containing onearmeabi-v7a, arm64-v8a…)linux/amd64 and linux/arm64services:
apk-installer:
image: waazaafr/apk-installer:latest
container_name: apk-installer
restart: unless-stopped
network_mode: host
volumes:
- ./data:/data
environment:
TZ: "Europe/Paris"
docker run -d \
--name apk-installer \
--restart unless-stopped \
--network host \
-v ./data:/data \
-e TZ=Europe/Paris \
waazaafr/apk-installer:latest
Then open http://:8934 and create the administrator account.
ℹ️ Host networking is required. Android devices announce their ADB service with mDNS multicast, which does not cross Docker's default bridge network. The app listens directly on port
8934of the host.
On first launch, the web interface asks you to create the administrator account (password of 8 characters or more). It is stored hashed (PBKDF2) in /data/auth.json; sessions last 30 days.
| You want to… | How |
|---|---|
| Set the account from your Docker configuration | Set AUTH_USERNAME and AUTH_PASSWORD: they take precedence and the creation page is disabled |
| Use your reverse proxy's authentication instead | Set AUTH_DISABLED=true |
| Reset a forgotten password | Stop the container, delete /data/auth.json, start it again: the creation page comes back |
| Log every session out | Change the password (or delete /data/session_secret) |
After 5 failed logins, the address is blocked for 5 minutes.
⚠️ The interface can install apps on your devices: even with the login, don't expose it on the internet without HTTPS (e.g. behind a reverse proxy).
5555 by default), or pick it from the discovered devices. The app connects to it right away.Wireless debugging changes its port at every reconnection, and requires a one-time pairing:
💡 A phone is only reachable while its screen is unlocked and wireless debugging is on. Installs that could not be done are retried automatically when it comes back.
In Installation manuelle, paste a direct link to:
.apk file;.zip, .tar.gz, .tgz, .tar, .tar.bz2, .tar.xz) containing an .apk.Select the target devices, then click Installer. Each device is connected right before the install; follow the result in the activity log.
In Suivi GitHub, create a watch:
| Field | Example | Description |
|---|---|---|
| Dépôt GitHub | owner/repo | Repository to follow |
| Motif(s) de fichier | *.apk | Release asset(s) to install, comma-separated |
| Intervalle (secondes) | 86400 | How often the releases are checked (default: once a day) |
| Inclure les pré-releases | off | Also install betas and release candidates |
| Appareils cibles | — | Devices that must run the latest release |
When a release ships one build per architecture, list them all and each device gets the right one:
*armeabi-v7a.apk, *arm64-v8a.apk
How a watch behaves:
Releases are detected through the public https://github.com/<owner>/<repo>/releases.atom feed, then read through the GitHub API (60 requests per hour without a token).
In Notifications, add one or more channels and choose the events to receive:
| Channel | What you need |
|---|---|
| Discord | A webhook URL: Server Settings → Integrations → Webhooks |
| Gotify | Your Gotify server URL, an application token and a priority |
| Email (SMTP) | Server, port, credentials, sender and recipient, STARTTLS on or off |
| Event | Enabled by default |
|---|---|
| New GitHub release detected | ✅ |
| Install failed | ✅ |
| ADB authorization required | ✅ |
| Install succeeded | |
| Device went offline |
| Variable | Default | Description |
|---|---|---|
TZ | Europe/Paris | Time zone of the activity log |
GITHUB_TOKEN | — | GitHub token: raises the API rate limit and allows private repositories |
AUTH_USERNAME | — | Web interface username (with AUTH_PASSWORD; otherwise created on first visit) |
AUTH_PASSWORD | — | Web interface password |
AUTH_DISABLED | false | true to disable the built-in login (authentication done by a reverse proxy) |
| Path | Content |
|---|---|
/data | Account, devices, watches, history, notification channels and the ADB key of this host |
💡 Keep
/data: it holds the ADB key your devices have authorized. If it is lost, every device must accept the authorization prompt (or be paired) again.
The image contains no configuration: it always starts empty, so it can be shared as is. Downloaded files are deleted once installed.
| Port | Service |
|---|---|
8934 | Web interface (on the host, through host networking) |
Requires the adb binary on your machine.
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
APK_INSTALLER_DATA_DIR=./data uvicorn app.main:app --reload --port 8934
AUTH_USERNAME / AUTH_PASSWORD; AUTH_DISABLED for reverse-proxy setups.linux/amd64, linux/arm64); fixed the build on Debian 13 (adb package)./ or special characters.Content type
Image
Digest
sha256:c007064f7…
Size
62 MB
Last updated
about 22 hours ago
docker pull waazaafr/apk-installer