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:
@@ -0,0 +1,4 @@
|
|||||||
|
**/node_modules
|
||||||
|
data
|
||||||
|
.git
|
||||||
|
*.log
|
||||||
+18
@@ -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"]
|
||||||
@@ -26,14 +26,15 @@ LAN. Add to the home screen and it behaves like an installed app.
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Node.js 18+ and `adb` (Android platform-tools) installed **on the machine
|
- Docker and Docker Compose on any always-on machine on your home network (a
|
||||||
running the server** — not on the phone.
|
Pi, NAS, old laptop, home server).
|
||||||
- macOS: `brew install android-platform-tools`
|
- The TV and that machine on the same local network.
|
||||||
- Debian/Ubuntu: `sudo apt install android-tools-adb` (or
|
|
||||||
`android-sdk-platform-tools`)
|
`adb` does **not** need to run on bare metal — it's a plain TCP client that
|
||||||
- Windows: download "SDK Platform-Tools" from developer.android.com and
|
dials out to the TV's IP once network/wireless debugging is on, so it works
|
||||||
put `adb.exe` on PATH
|
fine from inside a container with normal bridge networking. No host
|
||||||
- The TV and this server on the same local network.
|
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
|
## Set up the TV
|
||||||
|
|
||||||
@@ -51,32 +52,74 @@ LAN. Add to the home screen and it behaves like an installed app.
|
|||||||
## Run the server
|
## Run the server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd server
|
docker compose up -d --build
|
||||||
npm install
|
|
||||||
npm start
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This serves the app at `http://<this-machine's-LAN-IP>:8787`. Open that URL
|
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
|
on your phone, add your TV by IP in Settings (⚙), then optionally "Add to
|
||||||
Home Screen" for a full-screen, app-like remote.
|
Home Screen" for a full-screen, app-like remote.
|
||||||
|
|
||||||
Override the port with `PORT=9000 npm start`, or point at a non-default
|
Saved TVs persist in `./data/devices.json` on the host (bind-mounted into
|
||||||
`adb` binary with `ADB_BIN=/path/to/adb npm start`.
|
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
|
## Development
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd server
|
cd server
|
||||||
|
npm install
|
||||||
npm test
|
npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
Runs the server's unit tests (command construction, input validation,
|
Runs the server's unit tests (command construction, input validation,
|
||||||
device persistence) using Node's built-in test runner — no real TV
|
device persistence) using Node's built-in test runner — no real TV, and no
|
||||||
required.
|
Docker, required. Useful for iterating on server code before rebuilding the
|
||||||
|
image.
|
||||||
|
|
||||||
## Project layout
|
## 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)
|
server/ Express app + ADB bridge (source of truth for control logic)
|
||||||
src/adb.js Thin wrapper around the `adb` CLI (connect/pair/keyevent/…)
|
src/adb.js Thin wrapper around the `adb` CLI (connect/pair/keyevent/…)
|
||||||
src/keycodes.js Android KeyEvent constants used by the remote buttons
|
src/keycodes.js Android KeyEvent constants used by the remote buttons
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
tv-adb-remote:
|
||||||
|
build: .
|
||||||
|
image: tv-adb-remote
|
||||||
|
ports:
|
||||||
|
- "8787:8787"
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
environment:
|
||||||
|
- PORT=8787
|
||||||
|
restart: unless-stopped
|
||||||
Reference in New Issue
Block a user