Make Docker Compose the default way to run the server

adb only needs plain outbound TCP to the TV, so it runs fine in a
container with normal bridge networking (no host networking or
privileged mode). Bundles adb into the image via Dockerfile, adds
docker-compose.yml with a persisted data/ volume, and documents two
ways to fold this into another docker-compose-based repo (vendored
build context vs. a published image).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSVyYcrjrbmrMKT85G4fyn
This commit is contained in:
Claude
2026-09-26 14:54:49 +00:00
parent 6db1db70a0
commit e89683840a
4 changed files with 91 additions and 15 deletions
+58 -15
View File
@@ -26,14 +26,15 @@ LAN. Add to the home screen and it behaves like an installed app.
## Requirements
- Node.js 18+ and `adb` (Android platform-tools) installed **on the machine
running the server** — not on the phone.
- macOS: `brew install android-platform-tools`
- Debian/Ubuntu: `sudo apt install android-tools-adb` (or
`android-sdk-platform-tools`)
- Windows: download "SDK Platform-Tools" from developer.android.com and
put `adb.exe` on PATH
- The TV and this server on the same local network.
- Docker and Docker Compose on any always-on machine on your home network (a
Pi, NAS, old laptop, home server).
- The TV and that machine on the same local network.
`adb` does **not** need to run on bare metal — it's a plain TCP client that
dials out to the TV's IP once network/wireless debugging is on, so it works
fine from inside a container with normal bridge networking. No host
networking, USB passthrough, or privileged mode required. The container
image bundles `adb` itself, so nothing else needs installing on the host.
## Set up the TV
@@ -51,32 +52,74 @@ LAN. Add to the home screen and it behaves like an installed app.
## Run the server
```sh
cd server
npm install
npm start
docker compose up -d --build
```
This serves the app at `http://<this-machine's-LAN-IP>:8787`. Open that URL
on your phone, add your TV by IP in Settings (⚙), then optionally "Add to
Home Screen" for a full-screen, app-like remote.
Override the port with `PORT=9000 npm start`, or point at a non-default
`adb` binary with `ADB_BIN=/path/to/adb npm start`.
Saved TVs persist in `./data/devices.json` on the host (bind-mounted into
the container), so they survive `docker compose down`/rebuilds. Override the
port by changing the `PORT` environment variable and the left side of the
`ports` mapping in `docker-compose.yml`.
### Adding this as a service in another docker-compose stack
If you're folding this into a larger compose project rather than running it
standalone, you have two straightforward options:
1. **Vendor the source** (git submodule or subtree at, say,
`services/tv-adb-remote/`) and point that stack's compose file at it:
```yaml
services:
tv-adb-remote:
build: ./services/tv-adb-remote
ports:
- "8787:8787"
volumes:
- ./services/tv-adb-remote/data:/app/data
restart: unless-stopped
```
2. **Build and push an image** (e.g. to GHCR or Docker Hub) from this repo's
CI, then reference it by tag instead of a build context — no vendored
source in the other repo at all:
```yaml
services:
tv-adb-remote:
image: ghcr.io/<you>/tv-adb-remote:latest
ports:
- "8787:8787"
volumes:
- ./tv-adb-remote-data:/app/data
restart: unless-stopped
```
This fits a "docker nearly exclusively" stack best if most of its other
services are already referenced as prebuilt images rather than local
build contexts — ask if you want a GitHub Actions workflow added here to
publish the image on push.
Either way, the only two things the other repo's compose file needs to get
right are the port mapping and a persistent volume for `/app/data`.
## Development
```sh
cd server
npm install
npm test
```
Runs the server's unit tests (command construction, input validation,
device persistence) using Node's built-in test runner — no real TV
required.
device persistence) using Node's built-in test runner — no real TV, and no
Docker, required. Useful for iterating on server code before rebuilding the
image.
## Project layout
```
Dockerfile Bundles adb + the server into one image
docker-compose.yml Standalone run config (port 8787, data/ volume)
server/ Express app + ADB bridge (source of truth for control logic)
src/adb.js Thin wrapper around the `adb` CLI (connect/pair/keyevent/…)
src/keycodes.js Android KeyEvent constants used by the remote buttons