clone

a desktop tv and program guide for over-the-air broadcasts: what's on air, what your tuner gets, live tv, recordings

main
airwaves / docs / self-hosting.md
self-hosting.md 9.6K rendered
1# Running Airwaves without an antenna23This sets up an Airwaves server for its own channels only, with no antenna or tuner:45- **Jellyfin channels**: series, movies and collections from a Jellyfin server, on a6 schedule, with a guide.7- **YouTube channels**: the uploads of YouTube channels you pick, streamed as they air.8 Nothing is downloaded.9- **Folder channels**: a folder of your own videos, on a loop.10- **The weather channel**: a WeatherStar 4000+ style local forecast (US locations).1112You watch them in the Airwaves desktop app, and, if you turn it on, in Jellyfin, Emby,13Channels DVR or VLC through the emulated HDHomeRun.1415It runs in Docker on a computer that stays on: a Linux PC or mini PC, a NAS that runs16Docker, a Mac or Windows PC with Docker Desktop, or a Raspberry Pi 4 or 5 with a 64-bit17OS. Both amd64 (Intel, AMD) and arm64 (Apple Silicon, Raspberry Pi) work. Each channel18someone is watching costs one 720p video encode, so a small computer manages a viewer or19two; nothing runs while no one watches.2021## What you need2223- Docker with Compose: [Docker Desktop](https://www.docker.com/products/docker-desktop/)24 on a Mac or Windows PC, or Docker Engine on Linux. `docker compose version` should say25 v2.24 or newer.26- git, to fetch Airwaves and update it.27- About 1.5 GB of disk for the images, plus room for any videos of your own.28- The Airwaves desktop app on the computer you watch on.2930## Set it up31321. **Get Airwaves** and go to its standalone setup:3334 ```sh35 git clone https://github.com/FelineStateMachine/airwaves.git airwaves36 cd airwaves/deploy/standalone37 ```38392. **Write your settings.** Copy the example file, then open `.env` in a text editor:4041 ```sh42 cp .env.example .env43 ```4445 Every setting is explained in the file. The ones to look at first:4647 - `AIRWAVES_ZIP`: your ZIP code, so the weather is yours (or `AIRWAVES_LAT` and48 `AIRWAVES_LON` for a precise spot). Leave it empty to go without weather.49 - `TZ`: your time zone, such as `America/Chicago`.50 - `AIRWAVES_ADMIN_PASSWORD`: a password for the admin page. Set one unless this51 computer is only on a home network you trust (see [Keeping it private](#keeping-it-private)).52 - `PUID` and `PGID` (Linux): the user and group that own the `data` and `channels`53 folders. `id -u` and `id -g` print yours; the default, 1000, is usually right.54553. **Make the folders** it keeps things in, next to `compose.yml`:5657 ```sh58 mkdir -p data channels59 ```60614. **Start it.** The first time builds the images, which takes a few minutes (longer on62 a Raspberry Pi):6364 ```sh65 docker compose up -d --build66 ```6768 It starts again by itself after a reboot, as long as Docker does (in Docker Desktop's69 settings, turn on starting it when you sign in). To see what it's doing:7071 ```sh72 docker compose logs -f airwavesd73 ```7475 The first lines say what's on, for example:7677 ```78 airwavesd 0.2.0 listening on :808979 antenna: off, custom channels only80 location: ZIP 8030281 weather channel: WeatherStar display at http://weatherstar:8080 (port 8090 for the app), on while it answers82 custom channels: /channels83 admin page: /admin/, with a password84 app API token: off85 yt-dlp: /data/tools/yt-dlp, kept up to date86 HDHomeRun: off87 weather channel: on, WeatherStar display at http://weatherstar:808088 ```8990 Press Ctrl-C to stop following the log; Airwaves keeps running.91925. **Open the admin page** in a browser: `http://<this computer>:8089/admin/`, for93 example `http://192.168.1.20:8089/admin/` or, on the computer itself,94 `http://localhost:8089/admin/`. With a password set, the browser asks for it (any user95 name will do).96976. **Add channels** on the admin page with **New channel**:9899 - **YouTube**: search for a channel or paste its link. Airwaves lists its uploads100 (a few seconds for most channels, minutes for very large ones), then the channel101 joins the lineup.102 - **Jellyfin**: first sign in to your Jellyfin server in the panel on the left (with a103 Quick Connect code from any signed-in Jellyfin app, or a user and password). Then104 pick the series, movies and collections the channel plays. A Jellyfin user just for105 Airwaves, allowed only what the channels need, is a good idea.106 - **A folder of videos**: make a folder in `channels` named with a number and a name,107 such as `channels/2.1 Cartoons`, and put videos in it (mp4, mkv, webm, mov, m4v or108 ts). It joins the lineup within a minute.109110 Every channel gets a number, a name, a call sign, a category, a description and a111 logo, all on the admin page. The weather channel is 1.1 unless you change it.1121137. **Point the Airwaves app at it.** In the app's Settings, set **Airwaves server** to114 this computer's address, such as `192.168.1.20` or `nas.local` (port 8089 is assumed;115 add `:<port>` if you changed `PORT`). With `AIRWAVES_TOKEN` set, enter it as the116 token. The guide then shows your channels. Without an antenna the app has no117 Reception or Recordings view. A browser works too, with nothing to install: open118 `http://<this computer>:8089/tv/`, such as `http://192.168.1.20:8089/tv/`.119120## Jellyfin, Emby, Channels DVR and VLC121122These play Airwaves' channels through an emulated HDHomeRun tuner, which is off unless123you want it. Set `AIRWAVES_HDHR=on` in `.env`, then `docker compose up -d`. Then, with124`<host>` this computer's address and 5004 the `HDHR_PORT`:125126- **Jellyfin or Emby**: in Live TV, add a tuner device of type HDHomeRun with the URL127 `http://<host>:5004`, and a TV guide data provider of type XMLTV with128 `http://<host>:5004/xmltv.xml`.129- **Channels DVR**: Settings, Sources, Add Source, HDHomeRun, with `<host>:5004`.130- **VLC**: open the network stream `http://<host>:5004/channels.m3u`.131132(This is Jellyfin as a player of Airwaves' channels; Jellyfin as a library that Airwaves133channels play from is set up on the admin page, as above.)134135Players can also find the tuner by themselves on the LAN, with HDHomeRun discovery. That136needs host networking, on Linux only: add `COMPOSE_FILE=compose.yml:compose.host.yml` to137`.env` (and leave `BIND` unset), then `docker compose up -d`. Most players are just as138happy with the address typed in.139140## Keeping it private141142- **The admin page** (`/admin/`) and its tool endpoint for AI agents (`/admin/mcp`)143 change your channels and hold your Jellyfin sign-in. Without `AIRWAVES_ADMIN_PASSWORD`,144 anyone who can reach port 8089 can use them, so leave the password empty only when145 this computer is on a home network you trust, never one shared with strangers.146- **Never forward the ports to the internet.** To watch away from home, use a VPN such147 as [Tailscale](https://tailscale.com) and set `BIND` to the computer's Tailscale148 address, so Airwaves listens there only. The admin password travels unencrypted over149 plain HTTP, which is fine at home or over a VPN but not across the internet.150- **Watching**: anyone who can reach port 8089 can watch, unless you set151 `AIRWAVES_TOKEN`; then the app needs the same token in its Settings.152- **AI agents**: to let an agent manage channels over MCP with a password set, give it153 the password as a bearer token, for example154 `claude mcp add --transport http airwaves http://<host>:8089/admin/mcp --header "Authorization: Bearer <password>"`.155156## Updating157158From `airwaves/deploy/standalone`:159160```sh161git pull162docker compose up -d --build163```164165Your channels and settings stay: they're in `channels` and `data`.166167YouTube changes often, and older versions of yt-dlp (the tool Airwaves uses to play168YouTube) stop working. Airwaves keeps its own copy in `data/tools` and replaces it when a169new release comes out (it checks daily), so there's no need to update Airwaves for that.170If YouTube channels stop playing anyway, delete `data/tools/yt-dlp`; Airwaves downloads171the latest one the next time it needs it.172173## Backing up174175- Airwaves keeps backups of the channel setup in `data/backups` (each channel's176 settings, logo and schedule, and the Jellyfin sign-in; no videos), and the admin page177 shows them. Copy that folder somewhere else now and then, and keep the copy private,178 since it holds the Jellyfin sign-in.179- Videos of your own in `channels` are yours to back up as you would any files.180- The rest of `data` (caches, yt-dlp) is made again as needed.181182## When something's wrong183184- **Look at the log first**: `docker compose logs --tail 100 airwavesd`.185- **"can't write to /data" (or /channels)**: the folder belongs to another user. Set186 `PUID` and `PGID` to its owner, or give it to the user Airwaves runs as:187 `sudo chown -R 1000:1000 data channels`. Then `docker compose up -d`.188- **No weather channel**: the log says why. It needs a location (`AIRWAVES_ZIP`, or189 `AIRWAVES_LAT` and `AIRWAVES_LON`) and the display (`COMPOSE_PROFILES=weather`). To go190 without it, put a `#` before `COMPOSE_PROFILES=weather` and run191 `docker compose rm -sf weatherstar`.192- **"port is already allocated"**: another program uses that port. Pick another `PORT`,193 `WEATHERSTAR_PORT` or `HDHR_PORT` in `.env`.194- **The app can't connect**: check the address and port, that the computer's firewall195 lets the port in, and `docker compose ps` (airwavesd should say "healthy").196197## Building the image elsewhere198199`compose.yml` builds the image on the computer it runs on. To build it once for both200kinds of computer and push it to a registry instead (from the repository root):201202```sh203docker buildx build --platform linux/amd64,linux/arm64 -f deploy/standalone/Dockerfile \204 -t <registry>/airwavesd:latest --push .205```206207then set `image:` to that name in `compose.yml` and drop its `build:` section. The image208runs as a regular user, not root, and checks its own health (`airwavesd -healthcheck`).