Self-hosting (Docker)
Run Airwave on your own hardware — one prebuilt image, a Postgres database, and docker compose. The deploy model, prerequisites, and where each piece lives.
Airwave is built to be self-hosted: you run the server next to your media, point it at a Plex library, and stream your own channels to the TV apps. There's nothing to sign up for and no hosted tier.
Two ways to run it, same server, pick what fits your setup:
- Docker (recommended): for a NAS, mini-PC, or always-on Linux box. A single prebuilt image plus a
Postgres database, wired by
docker compose. No antivirus false positives, and the easiest to keep updated. Two ways to set it up:- Docker quick start: the recommended walkthrough. The full compose and
.env, set up by hand, in a terminal or a UI like Dockge / Portainer. - One-line installer: the fastest start if you already have Docker. One command does everything for you.
- Docker quick start: the recommended walkthrough. The full compose and
- One-click desktop app: for running Plex on your own Windows, macOS, or Linux machine, and the way most people run Airwave. A signed installer plus a tray app with embedded Postgres: no Docker, and nothing to configure to start. (A brand-new installer can occasionally trip antivirus or SmartScreen; if it does, Docker is always there.)
Set up the Docker stack
Same stack either way. Pick whichever fits how you like to work.
One command (fastest)
Already have Docker and just want it running? One command checks Docker, asks a few questions (sensible defaults, including auto-detecting your LAN IP), generates your secrets, writes the stack, and brings it up.
Linux, macOS, or Windows via WSL / Git Bash:
curl -fsSL https://www.getairwave.tv/install.sh | shWindows native (Docker Desktop, in PowerShell):
irm https://www.getairwave.tv/install.ps1 | iexIt installs to ~/airwave, tracks :latest (pin a release with --version), and re-running updates in
place. Preview everything with --dry-run, bind host paths and toggle extras with --advanced, or remove it
with --uninstall. The scripts are small and auditable, so read them first if you like:
install.sh or install.ps1.
By hand (recommended for full control)
Want to see exactly what you're deploying, tweak volumes and ports, or paste it into Dockge / Portainer? The
Docker quick start walks through the full docker-compose.yml and .env end to
end. Same result, and the better path if you want to understand and own your setup.
The deploy model
Everything ships as one image, run several ways. The published container
(ghcr.io/quixomatic/airwave) is a single artifact; which app it becomes is chosen at runtime by the
CG_ROLE environment variable:
server— the Bun API + the TV REST surface. Applies database migrations on start, then serves the API that the admin panel and every TV client talk to.web— the admin panel (a Vite SPA). Because each self-host lives at a different address, the SPA is built at container start with yourSERVER_PUBLIC_URLbaked in, then served.tvweb(optional) — the 10-foot TV app served as an auth-gated browser web player. Off by default; enable it with a compose profile.
A typical stack is therefore three services from two images: Postgres, the server, and the
web admin — all wired together by docker-compose.yml and a single .env. See
Roles & the single image for why it's built this way.
Prerequisites
- A host that runs Docker — a NAS (TrueNAS SCALE is proven), a mini-PC, or any Linux box with
docker compose(or a UI like Dockge / Portainer). The image is multi-arch (amd64 + arm64). - A LAN address or domain for the host. The admin and TV apps reach the server over the network,
so you need an address that your browser and TV can actually use — a LAN IP or a domain, not
localhost(unless you only ever browse from the host itself). - A Plex server whose library you want to turn into channels, reachable from the Airwave server (same LAN is simplest). Plex is the only media server supported today.
In this section
Docker quick start
Grab the stack files, fill in .env, bring it up — first boot, admin seed, and reaching the panel.
Desktop app
Run the whole server on your Windows/Mac/Linux machine next to Plex — an installer + tray app, embedded Postgres, no Docker.
Configuration
The full .env reference — every variable, what it does, defaults, and which are required.
Roles & the single image
One image, N roles (CG_ROLE) — the server, the admin web, and the optional browser TV player.
Updating
The release loop — pull a new tag, restart, migrations apply themselves; how images reach GHCR.
Once it's up
Deploying gets you a running server and an admin login — that's the starting point for the rest of the docs. From the admin panel you connect a source, build channels, and add viewers:
- Quick Start — zero to watching, end to end.
- Sources — connect and sync your Plex library.
- Settings — jobs, sessions, AI, and import/export.
Source map
| Concern | File |
|---|---|
| Compose stack (postgres + server + web + optional tvweb) | docker-compose.yml |
Environment reference (copy to .env) | .env.example |
Image build (one image, roles via CG_ROLE) | Dockerfile |
| Container entrypoint (PUID/PGID remap, migrations, role dispatch) | docker/entrypoint.sh |
GHCR publish / release workflow (on a v* tag) | .github/workflows/docker-publish.yml |
First-admin seed (from ADMIN_EMAIL / ADMIN_PASSWORD) | packages/auth/src/lib/seed-admin.ts |
| Server env schema (validated at boot) | packages/env/src/server.ts |
See also: Quick Start · Sources · Settings
Architecture
The main parts of Airwave — the self-hosted server, the admin web app, the viewer apps (tv-web, tv-native, tv-tauri desktop, tv-roku), and the shared packages — and how they fit together.
Docker quick start
Grab the stack files, fill in .env, and bring Airwave up with docker compose — first boot, the seeded admin, and reaching the panel.
