Signing in
Open your web app's address and sign in with your email and password. There is no sign-up form: every account is one the owner made on purpose. A session lasts seven days.
The sidebar down the left (a tab bar along the bottom on a phone) holds Home, Search, Library, YouTube, Photos, Plex and Status, then your account. Hover an icon for its name. Guests see no Photos or Status.
The home page
Three rows, each loading on its own:
- Recent photos, the newest in your photo library, once you have set up a photos address. A photo opens in Photos.
- Recommended for you, drawn from your Plex history. A card opens the title in search.
- Courses for you, full-length YouTube courses on topics you pick. Edit the topics right on the page, up to eight.
Beside the greeting, the owner sees the stack's one-line status, such as Running.
Films and series
- Open Search and type a title. Results come from TMDB, with posters, ratings and years. A title you already own says In library.
- Press Download. For a film, the dialog lists the ten best-seeded releases. For a series, it lists whole-show packs first, then every season in order, then single episodes, with checkboxes and a running size: tick several seasons to start them together.
- Check Save to, which picks Movies or TV Shows for you, and confirm.
From there it is automatic. The Mac fetches the torrent file, scans it, and hands it to Transmission, which downloads only through your VPN. When it finishes, the download is scanned again and moved into the library, where it goes on seeding. Within the hour, the renamer (once its agent is installed) files it the way Plex expects:
Movies/Alien (1979) {tmdb-348}/Alien (1979) {tmdb-348}.mkv
TV Shows/Severance (2022)/Season 01/Severance (2022) - s01e01 - Good News About Hell.mkvOnly the owner downloads
Guests get search, the library and Plex, with no Download buttons. The server refuses a guest's download even if they try it by hand.
YouTube
- Open YouTube, then search, or paste a video's link straight into the box.
- Choose Video for an MP4, or Audio for an MP3.
- Watch it arrive in the Downloads list.
Each video is filed in a folder of its own with its thumbnail as the poster, so a Plex Other Videos library shows it like a film. Titles lose their hashtags and “(Official Video)” on the way.
YouTube/Fluffy Milk Bread Recipe (2024)/Fluffy Milk Bread Recipe (2024).mp4
YouTube/Fluffy Milk Bread Recipe (2024)/poster.jpg
YouTube/Audio/Fluffy Milk Bread Recipe (2024).mp3With the search box empty, the owner's For you suggests what to save next, built from what you have saved already: more from the channels you save from most, and the topics you return to. Not interested hides a suggestion for good, and Refresh rebuilds the list.
Your library and Plex
Library lists everything Plex holds: posters, the seasons of each series that are actually on disk, and how far through them you are, such as 17 of 19 watched. Owned titles everywhere carry Watch in Plex in place of a download, opening the title's page in Plex.
Ownership is matched on the TMDB id Plex gave the file, never on the title, so of five films called Memento only the one you have is marked. A series you hold only part of still counts as owned, and its card says which seasons you have.
Without Plex nothing else changes: every result offers a download, and the library page says why it is empty. With the whole Mac asleep, search still works, and whatever needs the Mac is greyed out with the reason.
Recommendations
Open Search with the box empty for rows of things you don't own yet. They are built from what Plex says about you: what you hold, what you played and when, what you rated, and what you started and dropped. Films and series feed each other, so a series you finished can lead a row of films.
Ratings are the strongest signal. To steer the rows, rate titles in Plex.
Deleting after watching
Delete from the TV or from the site, and the drive gets its space back without cutting short a torrent that still owes seeding time.
- On the TV: open a title, a season or an episode in Plex, then ⋯ → Add to Playlist → Delete. The first time, make the playlist with New Playlist and call it
Delete. About ten minutes later it is gone. Until then, take it off the playlist to change your mind. - On the site: press Delete… on a Library card (a series offers the whole show or one season) or on a saved YouTube video. Confirming there skips the ten minutes.
What happens to each file:
| The file is | What happens |
|---|---|
| A YouTube download | Removed with its artwork, and never suggested again. |
| Seeding, and paid up | Seeded 14 days or reached a 1:1 ratio: removed with its torrent. |
| Seeding, still owed | Moved out of Plex into a hidden .leaving folder, where it keeps seeding, then removed once it has paid. |
| Anything else | Removed with its subtitles and artwork. |
The Library page lists what is leaving the drive, with Keep it for anything that has not started yet.
Off until you turn it on
A new install only describes what it would delete, and the Library page says Dry run. When that looks right, set LIBRARIAN_APPLY=1 in the Mac's installed settings and run make deploy. Leave Plex's own Allow media deletion and Empty trash automatically after every scan off.
Photos
The photo library is Immich, showing the Media/Photos folder on your drive. It reads that folder and never writes to it, and Live Photos stay paired with their videos.
- On the Mac: the Gallery tab in the desktop app, signed in already.
- In a browser: Photos in the sidebar, if you set up a photos address. Only the owner gets in.
- From your phone: the Immich app backs up new photos over your tailnet. They land on the drive under
Media/Immich/library, by year and month. iOS does not let an app delete photos after backing them up, so clearing the phone stays a manual job.
Moving an existing library in? The README has step-by-step guides for leaving iCloud Photos and Google Photos, each checking every file by its hash before anything is removed.
The status line
The Mac works out one line about the stack, and the menu bar, the desktop app, the web status page and your phone all show it word for word:
| Line | What it means |
|---|---|
| Running | Every service answers and the VPN is up. |
| Degraded: VPN down | The web app can reach the Mac, but something behind the gateway is not answering; the line names it. |
| Starting… | A start, restart or stop is under way, from anywhere. |
| Down: Remote access stopped | The containers exist but the gateway is not answering, so the web app can reach nothing on the Mac. |
| Stopped | The VM is off, or nothing is running. |
Status, the owner's page, adds detail: a tile per service with its recent log, every download in flight with its speed, time left and peers, and every seeding torrent with its ratio. A download moving nothing at all is marked stalled: on a private tracker that usually means no reachable peers.
The desktop app
Central Station.app puts five apps in one window, with a home page that shows a card and a status dot for each.
| Keys | Opens |
|---|---|
| ⌘0 | Home |
| ⌘1 | Plex, from the server on this Mac |
| ⌘2 | Search |
| ⌘3 | Status |
| ⌘4 | Gallery |
| ⌘5 | YouTube |
| ⌘[ · ⌘R · ⌘, | Back, Reload, Settings |
It asks for your account once and signs in to everything with it. If your plex.tv password is the same, Plex opens signed in too. Each app keeps its place while you switch, so Plex keeps playing while you search.
Closing the window leaves the app in the menu bar. On the Mac that runs the stack, the menu bar icon shows the status line, and Restart Stack restarts it. Quit closes the app; the stack keeps running.
On any other Mac, make install installs just the window. In Settings, point Plex and Gallery at the stack Mac's tailnet name.
From your phone
- The web app works on any network, with or without Tailscale. Added to the home screen, it opens full screen like an app.
- Plex plays from the Mac over your tailnet, at full quality, with the Tailscale app connected.
- Status, Start and Restart are three Shortcuts. They still work when the web app cannot reach the Mac, which is when you need them. Start and Restart answer at once and work in the background, so ask for Status a minute later. A second Restart within three minutes is refused as a double tap.
Accounts and passwords
There is one owner, who can download and see Status, and any number of guests, who can search, browse the library and watch.
- Add a guest: in the database's admin panel (your PocketBase address followed by
/_/), open users → New record, with verified on and can_download off. - Change your password: go to
/accountwhile signed in. The desktop app keeps its own copy, so sign in there again afterwards. - Forgot it: “Forgot password?” on the sign-in page mails a link that works for 30 minutes, if email is set up.
- Check who can sign in:
scripts/check-users.shlists every account and fails unless there is exactly one owner and sign-ups are closed.
API tokens
Scripts, Shortcuts and curl use a personal API token instead of a password. Make one on Account → API tokens; it is shown once.
curl -H "Authorization: Bearer hms_…" https://your-site.example.com/api/search?q=alien- browse covers what a guest can do: search and the library.
- download adds downloads, status and the folder list. Only the owner can make one.
- Tokens work on
/api/only, and never to make another token or change a password. Revoke stops one within a minute.
Stopping and restarting
From the menu bar, or on the Mac:
make status # the status line and every service, as JSON
make restart
make down
make logs SERVICE=gateway # follow one serviceStopping or restarting pauses every torrent that is seeding until the stack is back. To apply a change, prefer make deploy, which restarts only what the change touches.