Documentation
API reference

Start here

Search every guideesc close

Install

Run your tofa server

Get your tofa server running in a few minutes on Linux, macOS, Windows, or your NAS.

13 min read

Quick install#

Pick your platform. Every path ends in the same place: tofa running at http://localhost:33333, ready to claim with your account.

The setup we recommend. One line on any machine with Docker, whether that is a Linux box, a NAS, or Docker Desktop:

curl -fsSL https://get.tofa.tv/docker | sh

It is a short, readable script. Open get.tofa.tv/docker in a browser first if you want to read it before you run it. It writes a compose file for one container that manages everything itself, including its own database, asks where your media lives, starts the server, and points you at the claim page.

Prefer to write the compose file yourself? Set it up by hand below walks through every line.

Set it up by hand#

Prefer to write the files yourself, or want to see what each piece does? The rest of this page is the manual Docker walkthrough. One container runs and manages everything, including its own database and automatic backups, and it takes about ten minutes.

What you need#

  • A computer that stays on: a Linux box, a NAS, a mini PC, or a Mac. It doesn't need to be powerful. On an Unraid server, follow Install on Unraid instead.
  • Docker with the Compose plugin. If you don't have it, install Docker Engine (Linux) or Docker Desktop (Mac, Windows) from docker.com. Compose is included with both.
  • Your media in folders on that machine.
  • A tofa account with a verified email address.

The image runs natively on 64-bit Intel and AMD (x86-64) and on ARM, including Apple Silicon and ARM NAS boxes. Docker pulls the right build automatically.

01Build your compose file#

Make a folder for tofa, answer the questions below, and copy the result into a file named docker-compose.yml in that folder.

Everything here can be changed later, and skipped questions fall back to safe defaults. There are no secrets to set up: on first start tofa generates what it needs, including the key it signs sessions with, and stores it in its own data.

02Start it#

From the folder with your compose file:

docker compose up -d

The first start takes a minute or two while tofa sets up its database. To watch it come up:

docker compose logs -f

Ctrl+C stops the log view, not the server.

03Claim your server#

Open a browser to:

http://localhost:33333

If Docker runs on a different machine (a NAS or a server), use that machine's address on your network instead, for example http://192.168.1.50:33333.

Claiming from another device#

For security, a brand-new server only accepts a claim from its own local network. Opening it on the same machine (localhost) or by its LAN address (like 192.168.1.50) works out of the box. If the only way you can reach it is by a hostname, a public address, or through a reverse proxy, the claim page will refuse with a security notice.

For those cases the installer prints a one-time claim link that carries a setup token and works from anywhere:

http://your-server:33333/setup?setup_token=…

Lost it, or set the server up by hand? The server prints the same link in its own logs on every start while it is unclaimed:

# Docker
docker compose logs tofa | grep setup_token

# Native (systemd)
journalctl -u tofa | grep setup_token

Open that link from any device and claim as normal. The token stops working the moment the server is claimed.

Sign in with your tofa account and claim the server. It picks up its secure certificate on its own moments after the claim goes through, which is what lets your devices connect to it directly. There is nothing to restart.

From here you can manage it at this address or from app.tofa.tv.

04Add your media#

In the web interface, add a library and point it at your media inside the container: /media, or a subfolder like /media/Movies. If you mapped extra folders in your compose file (say /media/TV or /media/torbox), point each library at the container path you gave it, the right side of the colon. tofa scans, matches, and fills in artwork on its own.

Open any tofa app, sign in with the same account, and your server is there.

Everyday commands#

If you installed with a get.tofa.tv one-liner (native or Docker), you already have the tofa helper on your PATH. It detects how your server is installed and gives you one set of commands everywhere:

Task Command
Update to the latest beta tofa update
Is it running? What version? tofa status
Follow the logs tofa logs
Restart, stop, start tofa restart / tofa stop / tofa start
Print the local address tofa url

If you set Docker up by hand, the compose commands do the same jobs. Run them from the folder with your compose file:

Task Command
See the logs docker compose logs -f
Stop the server docker compose down
Start it again docker compose up -d
Restart it docker compose restart
Update to the latest beta docker compose pull then docker compose up -d

When a new build is out, the Software Update card under Admin, then Settings tells the admin. Linux one-liner, macOS, and Windows installs can apply the update from that card; Docker installs get the matching commands shown instead. Your data and settings survive updates on every platform. The full story, including channels and rollback, is in Keep your server up to date.

Remote access and local playback#

Streams always work: if no direct path is available, they go through the tofa relay. On top of that, tofa sets up faster direct paths where it can:

  • At home, devices connect straight to the server over your own network at full quality. On Linux this needs nothing from you. On Docker Desktop tofa can't see your machine's address by itself, so tell it under Settings, then Remote Access, then local network address (the setup wizard's remote access step shows the same control). Prefer keeping it in your compose file? The ADVERTISED_LAN_IP variable from step 1 does the same thing.

  • Away from home, the server asks your router to open a port automatically (Linux setup). If your router doesn't allow that, forward a port yourself and enter it under Settings, then Remote Access. Otherwise the relay covers it.

  • Through a tunnel or your own domain, if you already have one. Add its address under Settings, then Remote Access, then custom access URLs, and apps use it as a direct path. See Use your own tunnel or domain.

Settings, then Remote Access shows which path is active, and has a test button that checks the home-network address from the device you're on. If it reports carrier-grade NAT or double NAT, your connection can't be opened from the inside no matter how the router is configured; Local, direct, or relay covers what helps.

Backups#

tofa backs up its database on a schedule, keeps the recent ones, and verifies each backup can be restored. Backups live in the tofa-data volume. You can see them, take one manually, or restore one under Settings, then Database. Back up your server covers restores, disaster recovery, and what to copy yourself.

Put backups on a second disk

By default, backups sit on the same disk as the database. To survive a disk failure, add TOFA_BACKUP_DIR: /backups under environment: and a line like /mnt/other-disk/tofa-backups:/backups under volumes:. The Database page confirms the new location and can move existing backups over.

Use your own PostgreSQL#

tofa normally runs its own bundled database inside the container, and that is the setup we recommend and support. If you would rather point it at a PostgreSQL server you already run, set DATABASE_URL under environment: with a standard connection string:

environment:
  DATABASE_URL: postgres://tofa:[email protected]:5432/tofa

When DATABASE_URL is set, the bundled database stays off and tofa uses yours.

Your database, your responsibility

With an external database, backups, upgrades, tuning, and recovery are yours to handle. tofa's automatic backups, the Database page tools, and our help with database problems only cover the bundled setup. If your PostgreSQL breaks, we cannot get your data back.

Remove tofa#

Removing the program never touches your media files, and your library database is kept unless you delete it yourself, so a later reinstall picks up right where you left off.

Docker. Run docker compose down in the folder with your compose file, then docker rm the container if one is left. Your library database lives in the data folder you mapped in the compose file; delete that folder too if you want a truly clean slate.

Windows. Uninstall tofa from Settings, then Installed apps, like any other program. Your library database stays in C:\ProgramData\tofa; delete that folder if you don't want to keep it.

macOS. Quit tofa from the menu bar, then paste these lines into Terminal one at a time. Some may answer "No such process", which is fine.

sudo launchctl bootout system/com.tofa.server
launchctl bootout gui/$(id -u)/com.tofa.server.agent
launchctl bootout gui/$(id -u)/com.tofa.tray
sudo rm -f /Library/LaunchDaemons/com.tofa.server.plist
rm -f ~/Library/LaunchAgents/com.tofa.server.agent.plist ~/Library/LaunchAgents/com.tofa.tray.plist
sudo rm -rf /Applications/tofa.app ~/Library/Logs/tofa

If you installed from the terminal one-liner, two small helpers were added that you can remove the same way:

sudo rm -f /usr/local/bin/tofa /etc/tofa/manage.env

Your library database stays in ~/Library/Application Support/tofa; delete that folder if you don't want to keep it.

Linux. Remove the package with your package manager, for example sudo apt remove tofa on Debian and Ubuntu or sudo dnf remove tofa on Fedora. Your library database is kept in the tofa data directory; delete it if you don't want to keep it.

If something is off#

  • The page won't load at localhost:33333. Give it another minute on the very first start, and check docker compose logs -f for a line saying it's listening. If Docker is on another machine, use that machine's IP, not localhost.
  • The claim page refuses with a security notice. A new server only accepts a claim from its local network. Reach it by its LAN address (like http://192.168.1.50:33333) from a device on the same network, or use the setup_token link from the installer output or the server logs. See Claiming from another device.
  • Port 33333 is already in use. Move tofa to a free port by setting the environment variable TOFA_PORT, for example TOFA_PORT: 34000 in your compose file's environment: block. The server then listens, advertises, and is reached on that port everywhere, browser and apps alike. A Docker port remap ("34000:33333") also works for the browser, but the server doesn't know about the outside number, so apps are still told to connect on 33333. If you remap instead of setting TOFA_PORT, put the outside port in Settings → Remote Access → Local network address as address:port so apps hear the right one.
  • My media isn't showing up. Every media line is host-path:container-path, with a colon between the two. A line missing the colon (like - /mnt/media or - /mnt/media/TV/) makes Docker create an empty throwaway volume instead of mounting your files, so tofa sees an empty folder. Check that the left side is the real path on your machine, that the folder has files in it, and that every media line keeps its colon. To confirm tofa can see the files, run docker exec tofa ls /media (or docker exec tofa ls /media/TV for a folder you mapped): it should list your shows and movies, not come back empty.
  • Playback at home feels limited or slow. Use the test button under Settings, then Remote Access. If the address isn't reachable, correct the local network address on that same page. It should be your machine's address on your home network, not an address from inside Docker. (ADVERTISED_LAN_IP in your compose file sets the same thing.)

Still stuck? Getting help & feedback covers what to send us.