Compare commits

..
3 Commits
Author SHA1 Message Date
Outis 1fa6d5188a Merge pull request #1 from outis1one/claude/intelligent-edison-zpskno
Add local ADB web remote for Android TV (Docker-first)
2026-10-02 16:24:55 -04:00
Claude 371013a13c Pin container name/hostname in docker-compose.yml
Fixed container_name/hostname (rather than Compose's default
project-derived name) so other tooling can reference this container
by a stable name — needed when this service is embedded in a larger
compose-based stack that wires containers together by name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSVyYcrjrbmrMKT85G4fyn
2026-09-26 17:54:58 +00:00
Claude e89683840a 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
2026-09-26 14:54:49 +00:00
4 changed files with 95 additions and 15 deletions
+4
View File
@@ -0,0 +1,4 @@
**/node_modules
data
.git
*.log
+18
View File
@@ -0,0 +1,18 @@
FROM node:22-bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends android-tools-adb \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install deps first so this layer is cached unless package.json changes.
COPY server/package.json server/package-lock.json ./server/
RUN cd server && npm ci --omit=dev
COPY server ./server
COPY public ./public
WORKDIR /app/server
EXPOSE 8787
CMD ["node", "src/index.js"]
+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
+15
View File
@@ -0,0 +1,15 @@
name: tv-adb-remote
services:
tv-adb-remote:
build: .
image: tv-adb-remote
container_name: tv-adb-remote
hostname: tv-adb-remote
ports:
- "8787:8787"
volumes:
- ./data:/app/data
environment:
- PORT=8787
restart: unless-stopped