Install the YAVTT Server
Config files you'll need
The steps below tell you to copy the contents of these files. Grab them from the repository:
- docker-compose_reverse.yml: Path A (behind a reverse proxy)
- docker-compose_noreverse.yml: Path B (standalone)
- .env.example: passwords and JWT secret
- migrate_in.sh: migrating from the Integrated Server
Or browse the whole docker/ folder on Codeberg.
This folder contains everything you need to run the YAVTT server with Docker. Pick the path that matches your setup, follow the steps, and you'll have a running server in a few minutes.
What you need
- A VPS or a home server that run 24/7; or you can host it on the same PC your client uses, but it is suggested to deactivate the server with
docker compose downwhen you do not need it. - Docker and the Docker Compose plugin installed. Follow the official Docker docs: https://docs.docker.com/engine/install/ for Linux; https://docs.docker.com/desktop/ for Windows and Mac.
- Optional but recommended: a domain name pointing at your machine, so players connect to
yavtt.example.cominstead of an IP.
You do not need to clone the YAVTT repository.
The yavtt-server image is multi-arch (x86-64 and arm64), so a Raspberry Pi or other arm64 host pulls the right build automagically!
Pick your path
Follow the diagram to pick the best path to install the YaVTT server.
flowchart TB
Q1["Do you have VPS, an home server, or a device you can keep on at all times?"]
Q2["Do you already have running services behind a proxy?"]
Q3["Do you want to keep the server up 24/7 or do you want to trade convenience with security?"]
Q4["Can you open ports on your router?"]
A1["Path A: docker compose behind your own proxy (recommended)"]
A2["Path A: docker compose behind a proxy (recommended)"]
B["Path B: docker compose with no reverse proxy (security risk)"]
C["Path C: Standalone with port 8000 open (security risk)"]
D["Path D: Standalone with Tailscale (you depend on a third-party)"]
Q1 -->|Yes| Q2
Q1 -->|No| Q4
Q2 -->|Yes| A1
Q2 -->|No| Q3
Q3 -->|Convenience| B
Q3 -->|Security| A2
Q4 -->|Yes| C
Q4 -->|No| D
Path A is the recommended path, as it is the most secure, and safe to keep running 24/7 on any server or VPS you own.
If unsure: pick Path D with Tailscale. It is secure and you do not need a dedicated server nor open ports, but you depend on a third-party service.
Path A — Behind a reverse proxy
A.1 Set up the proxy first (skip if you already have one) and the yavtt server
If you don't already run a reverse proxy, the easiest is Nginx Proxy Manager (NPM). In that case, create a folder of your choosing, create a docker-compose.yml file and copy the contents of docker-compose_reverse.yml inside it.
Then, create a .env file and copy the contents of .env.example inside it. Make sure to change the passwords and to generate a JWT token following the simple instructions inside .env.example.
Now you can spin up your docker containers with docker compose up -d in your terminal.
Open http://your-server-ip:81 and log in with the default credentials (admin@example.com / changeme). NPM will force you to change them. Important: in your router or cloud firewall, port-forward / allow ports 80 and 443 to your machine. If you do not do this, you will not be able to access the admin UI.
To check if yavtt-server is working, paste this command into your terminal: docker compose logs -f yavtt-server; once you read Uvicorn listening on port 8000, the server is ready.
Note: if you already have a different reverse proxy, you'll have to slightly modify the docker-compose settings.
A.2 Tell the proxy about YAVTT
If you have a domain: add an A record for yavtt.example.com pointing at your machine's public IP.
In NPM's admin UI:
- Go to Hosts → Proxy Hosts → Add Proxy Host.
- Domain Names:
yavtt.example.com(or whatever you chose). - Forward Hostname / IP:
yavtt-server(the container name. Remember npm and the yavtt-server must be on the same network!). - Forward Port:
8000. - Block Common Exploits: on.
- Websockets Support: on (required — game sessions use WebSockets).
- SSL tab: select Request a new SSL Certificate, tick Force SSL, HTTP/2 Support, agree to Let's Encrypt's terms, save.
Done. To check if it is working, use your browser to go to yavtt.example.com. If you see a "Welcome to YAVTT!" message, you're all set! Connect with the YAVTT client to yavtt.example.com.
Path B — Standalone (no reverse proxy)
B.1 Set up yavtt-server
Create a folder of your choosing, then create a docker-compose.yml file and copy the contents of docker-compose_noreverse.yml inside it.
Then, create a .env file and copy the contents of .env.example inside it. Make sure to change the passwords and to generate a JWT token following the simple instructions inside .env.example. You can skip the NPM_DATABASE_PASSWORD variable.
Now you can spin up your docker containers with docker compose up -d in your terminal.
To check if yavtt-server is working, paste this command into your terminal: docker compose logs -f yavtt-server; once you read Uvicorn listening on port 8000, the server is ready.
B.2 Open your ports
To allow your server to communicate with the Internet, you must open up the port 8000. If you are on your home server or on your PC, go to your router admin panel and open up the port 8000. If you are on a VPS, you'll have to follow that VPS docs to open port 8000.
Now try to connect to http://your-ip:8000 through your browser. If you read "Welcome to YAVTT!" then you're all set!
For more security, you can setup a VPN like Wireguard or Tailscale. In that way, you will not be exposing the port to the public Internet. However, your friends will need a little more setup to connect to your YaVTT instance.
Warning: having your port exposed like that is a security risk. If you must use Path B, I recommend at least not having the server up 24/7.
Path C — Integrated Server with open 8000 port
The Integrated Server is a single executable that does not need docker compose. It is more limited but it can be useful if you are just testing YaVTT out. Know that the server is up as long as you keep YaVTT open.
C.1 Download the IS version of YaVTT
Download the Integrated Server version of YaVTT. Only you need this version; your players must install the normal version.
C.2 Open the port 8000
Open the port 8000 on your router.
C.3 Start YaVTT_IS
Start YaVTT_IS. If you opened your port, ask your players to connect to the IP you see on the top of the screen.
WARNING: if you open the port 8000, you are at risk. Make sure to close the program when you are not running an adventure.
Path D — Integrated Server with Tailscale Funnel
Instead of opening the 8000 port, you use the third-party service Tailscale to set up a secure funnel for your friends to connect to.
D.1 Make a Tailscale account
Create a Tailscale account and follow this guide to set up your Funnel: https://tailscale.com/docs/features/tailscale-funnel. Ensure you have the right settings in your Tailscale account (such as Magic DNS active), and you have Tailscale installed on the machine you will run your server in. You do not need to manually create the Funnel: just install Tailscale: https://tailscale.com/docs/install.
D.2 Download the IS version of YaVTT
Download the Integrated Server version of YaVTT. Only you need this version; your players must install the normal version.
D.3 Start YaVTT_IS
Start YaVTT_IS. If you have Tailscale correctly installed, the program will automatically start the service and start the funnel. Simply follow the on-screen instructions. Your players will need to put the funnel link into their server field.
WARNING: if you use the Tailscale Funnel path, know that you will depend on a third-party service (Tailscale, in this case). It is convenient but not self-contained any more.
Day-to-day operations
Check what's running
docker compose ps
View logs
docker compose logs -f yavtt-server # live tail; Ctrl+C to exit
docker compose logs --tail=200 yavtt-db
Update to a newer YAVTT version
Edit docker-compose.yml, change the image tag (e.g. codeberg.org/derto/yavtt-server:0.1.0 → :0.2.0), then:
docker compose pull
docker compose up -d
Your data (./yavtt_data, ./yavtt_systems, ./yavtt_postgres_data, and ./yavtt_backups) is preserved across upgrades. WARNING: even if you data remains, up until version 1.0 of YAVTT, there is NO GUARANTEE you will be able to safely migrate your adventures.
Starting from 1.0.0, every major version will guarantee backward compatibility. Remember: right now YAVTT is in an Alpha-state, so be wary!
Stop / start
docker compose stop # stop without removing
docker compose start # start back up
docker compose down # stop and remove containers (data persists)
Back up
All persistent data lives in four folders next to docker-compose.yml:
./yavtt_postgres_data: the entire database./yavtt_data: user-uploaded assets (maps, portraits, etc.) and journals./yavtt_systems: installed game systems (downloaded from Plaza)./yavtt_backups: the backups the server writes (database dumps, adventure zips, full archives).
The full archive is created by the server, not by you and not by the client:
in the hub's Backups panel (or the web admin UI's Server backups table at
/admin), press Create full archive. The job writes
full_<version>_<timestamp>.tar.gz into ./yavtt_backups; it holds the
database dump, the uploads and journals (server_data), the installed
systems, the JWT secret and a manifest, in one file. Download it from
the same list and keep at least one copy off-site. Restore on it (or on
a dump) applies it at the next server boot, after a self-restart.
The archive layout is exactly the one migrate_in.sh uses (see
"Migrating from YAVTT-IS" below), so an archive downloaded here moves a
server to another host as is.
Migrating from YAVTT-IS (Integrated Server)
If you started on YAVTT-IS, the all-in-one binary
that runs the client, server, and database together, and now want a real
server, you can move everything across. On the YAVTT-IS host, create the
full archive in the hub's Backups panel (or the web admin UI's Server
backups table at /admin): Create full archive, then Download it.
Then, on a fresh deployment here (compose file + .env set up, but not
yet serving), place both the archive and migrate_in.sh (from this
docker/ folder) next to your compose file, then run:
chmod +x migrate_in.sh
./migrate_in.sh full_<version>_<timestamp>.tar.gz
migrate_in.sh is unchanged: it consumes the archive layout the server
writes (database dump, server_data, systems, secret.key, manifest).
It restores the database, places the uploads and systems, and carries the JWT
secret into .env. The server image must be the same release or newer than
the YAVTT-IS binary.
Uninstall and delete everything
docker compose down
rm -rf yavtt_postgres_data yavtt_data yavtt_systems yavtt_backups .env docker-compose.yml
Troubleshooting
Connection refused from the client — check docker compose ps: both yavtt-server and yavtt-db should be in Up state. If yavtt-server is restarting, docker compose logs yavtt-server usually shows why.
Players can connect but the session never starts — almost always WebSocket support is off on the reverse proxy. Toggle "Websockets Support" on NPM's Proxy Host edit page.
Database password change — Postgres locks the password at first init. Changing POSTGRES_PASSWORD in .env after the DB exists has no effect. To actually rotate: connect with docker compose exec yavtt-db psql -U <user> <db> and run ALTER USER <user> WITH PASSWORD 'new', then update .env to match.
Cannot create my admin account — Fresh servers ask for a special code that is printed once, at their first startup, for admins. You can find the code in the logs of your Docker Compose services. You can access it by going to the machine with Docker and using the following command:
docker compose logs yavtt-server
If you use the IS version, the code will be auto-added to the code field.