- doctor [<name>] [--fix]: checks the system (user, programs, folders, zips, units and leftover copies in /etc, sandbox access to moved folders, journal, polkit, daemon, orphaned boot links and schedules) and each instance (ownership, server zip, config paths, mods, ports, failed starts/backups), with a fix for each. --fix applies the safe ones and re-checks them. - backup enable|disable|now|list: a systemd timer per instance (terraria-backup@.timer, Persistent=), saving the world first, into /var/lib/terraria/backups/<name>/ (group-readable), pruning only scheduled backups. rename carries the schedule, delete removes it. upgrade's backups move there too. - fetch vanilla|tmodloader [<version>] [--list] [--upgrade <name>]: downloads from terraria.org / tModLoader's GitHub releases, checks GitHub's sha256 and the zip, names it with its version. - terractld may write /etc/systemd/system, for backup enable and doctor --fix over --host. - Units, tmpfiles, packaging, completion, docs and changelog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8a509f1398
commit
fc2c08d47b
14 files changed
+1118
-56
No files matched your search
+109
-11
@@ -52,7 +52,8 @@ Everything is installed by the `terraria-server-manager` package:
|
||||
| `/usr/bin/terractl` | Helper script. The service calls it to set up, run and stop servers; you use it for everyday management. |
|
||||
| `/usr/lib/terraria-server-manager/terractl-remote` | The part of `terractl` that manages other hosts (`--host`, `remote`, `daemon`, `copy`, `move`), in Python. |
|
||||
| `/usr/lib/systemd/system/terractld.service` | The daemon that lets other hosts manage this one. Off until you turn it on (see [Managing other hosts](#managing-other-hosts)). |
|
||||
| `/etc/default/terractl` | Optional overrides (locations, stop timeout, the daemon's address). |
|
||||
| `/usr/lib/systemd/system/terraria-backup@.timer`, `terraria-backup@.service` | Scheduled backups of an instance. Off until you turn them on with `terractl backup enable` (see [Backups](#backups)). |
|
||||
| `/etc/default/terractl` | Optional overrides (locations of instances, zips and backups, stop timeout, the daemon's address). |
|
||||
| `/etc/systemd/journald@terraria.conf` | Size and retention of the servers' own journal (see [Logs](#logs)). |
|
||||
| `/usr/lib/sysusers.d/terractl.conf` | Defines the `terraria` system user. |
|
||||
| `/usr/lib/tmpfiles.d/terractl.conf` | Creates `/var/lib/terraria` and its subdirectories. |
|
||||
@@ -76,6 +77,7 @@ On stop, `terractl service-stop` sends `exit` through the pipe so the world is s
|
||||
├── dist/ Server zips (you add these; never modified)
|
||||
│ ├── terraria-server-1458.zip
|
||||
│ └── tModLoader-v2026.07.3.0.zip
|
||||
├── backups/<name>/ Backups from 'terractl backup' and 'upgrade' (group-readable)
|
||||
└── instances/
|
||||
├── <name>/ One directory per instance
|
||||
│ ├── instance.conf Which server type and zip to use
|
||||
@@ -87,7 +89,6 @@ On stop, `terractl service-stop` sends `exit` through the pipe so the world is s
|
||||
│ ├── Mods/ tModLoader mods + enabled.json
|
||||
│ ├── ModConfigs/ tModLoader mod settings
|
||||
│ └── banlist.txt
|
||||
├── .backups/ Backups made by 'terractl upgrade'
|
||||
└── .deleted/ Backups made by 'terractl delete'
|
||||
|
||||
/run/terraria/<name>.stdin Console pipe (exists only while running)
|
||||
@@ -326,6 +327,28 @@ The existing `terraria` user keeps `/opt/terraria` as its home directory. That's
|
||||
|
||||
## Server zips
|
||||
|
||||
Servers are unpacked from the official zips in `/var/lib/terraria/dist`. The easiest way to get them there is `fetch`, which downloads them and names them with their version:
|
||||
|
||||
```bash
|
||||
terractl fetch tmodloader # the latest stable tModLoader
|
||||
terractl fetch tmodloader 2026.07.3.0 # a specific version, e.g. the one your players have
|
||||
terractl fetch vanilla # the latest Terraria server
|
||||
terractl fetch vanilla 1449 # a specific version (1449 or 1.4.4.9)
|
||||
terractl fetch tmodloader --list # recent tModLoader versions, stable and preview
|
||||
```
|
||||
|
||||
tModLoader comes from its GitHub releases, and its download is checked against the checksum GitHub publishes. Vanilla comes from terraria.org, which only lists its newest version, but older ones can be fetched by number. Every zip is checked (complete, and the right kind) before it's put in `dist/`. Zips already there aren't downloaded again.
|
||||
|
||||
`--upgrade <name>` also switches an instance to the zip it just fetched, with `upgrade` (see [Upgrading](#upgrading-or-downgrading-an-instance)):
|
||||
|
||||
```bash
|
||||
sudo terractl fetch tmodloader --upgrade calamity
|
||||
```
|
||||
|
||||
`fetch` needs `curl` and internet access. Members of the `terraria` group can use it without `sudo` (except `--upgrade`). If a site changes its download address and `fetch` stops working, it says so; download the zip by hand as below.
|
||||
|
||||
### Adding zips by hand
|
||||
|
||||
Put the official downloads in `/var/lib/terraria/dist`:
|
||||
|
||||
| Type | File name pattern | Where to get it |
|
||||
@@ -634,7 +657,7 @@ Stable tModLoader and the latest vanilla Terraria can be based on different Terr
|
||||
|
||||
### Upgrading (or downgrading) an instance
|
||||
|
||||
Put the new zip in `/var/lib/terraria/dist`, with the version in its name (see [Server zips](#server-zips)). To see which zips an instance can use and which one it runs:
|
||||
Get the new zip with `terractl fetch` (or put it in `/var/lib/terraria/dist` by hand, with the version in its name; see [Server zips](#server-zips)). To see which zips an instance can use and which one it runs:
|
||||
|
||||
```
|
||||
$ terractl upgrade calamity
|
||||
@@ -656,7 +679,7 @@ sudo terractl upgrade calamity latest
|
||||
|
||||
1. **Checks the zip** before changing anything: it must be in `dist/`, match the instance's type, be readable by the `terraria` user, contain the server, and pass `unzip -t`. A damaged or half-downloaded zip is refused here, not on the next start.
|
||||
2. **Stops the server** if it's running. Stopping saves the world.
|
||||
3. **Backs up** the worlds and configs (not `server/`) to `/var/lib/terraria/instances/.backups/<name>-<date>-<old zip>.tar.gz`, readable only by root. Use `--no-backup` to skip this.
|
||||
3. **Backs up** the worlds and configs (not `server/`) to `/var/lib/terraria/backups/<name>/<name>-<date>-<time>-before-<old zip>.tar.gz`. Use `--no-backup` to skip this. These backups are never deleted automatically, not even by scheduled backups' `--keep`.
|
||||
4. **Pins `ZIP=`** in `instance.conf` to the new zip, so the version can't change by accident afterwards.
|
||||
5. **Unpacks the new zip** into `server/`. For tModLoader, the .NET runtime and logs are kept, as always. If this fails, the old pin is put back and the old `server/` is still in place, so the instance is exactly as it was.
|
||||
6. **Starts the server again** if it was running.
|
||||
@@ -680,9 +703,9 @@ You can still change version by hand: set `ZIP=` in `instance.conf` and restart.
|
||||
To go back to the old version *and* the worlds as they were before the upgrade, replace the instance with the backup `upgrade` made. The backup is in the same format as `export`, so `import` restores it, pinned to the version it was taken with:
|
||||
|
||||
```bash
|
||||
sudo ls /var/lib/terraria/instances/.backups/
|
||||
terractl backup list calamity
|
||||
sudo terractl delete calamity -y # keeps its own backup in .deleted/, just in case
|
||||
sudo terractl import calamity /var/lib/terraria/instances/.backups/calamity-20261002-213553-tModLoader-v2026.06.1.0.tar.gz
|
||||
sudo terractl import calamity /var/lib/terraria/backups/calamity/calamity-20261002-213553-before-tModLoader-v2026.06.1.0.tar.gz
|
||||
sudo terractl enable calamity --now
|
||||
```
|
||||
|
||||
@@ -892,19 +915,42 @@ On this host, copying *from* it works for members of the `terraria` group. Copyi
|
||||
- **Revoking.** `sudo terractl daemon status` shows the trusted computers, and `sudo terractl daemon revoke laptop` takes one's access away immediately.
|
||||
- **Firewall.** The daemon doesn't need to be reachable from the internet. Limit port 7776 to your LAN or VPN, or set `TERRACTL_LISTEN` to a LAN or VPN address.
|
||||
|
||||
The daemon runs as root, because it creates and removes instances and starts services, but with systemd's protections it can't write to `/usr`, `/boot`, `/etc` or home folders. Its certificate, key and trust list are in `/var/lib/terractl/`. Files in transit are kept in `/var/lib/terractl/transfers/`, and removed once used, after 6 hours unused, or when the daemon restarts.
|
||||
The daemon runs as root, because it creates and removes instances and starts services, but with systemd's protections it can't write to `/usr`, `/boot`, `/etc` or home folders. The one exception is `/etc/systemd/system`, where `backup enable` and `doctor --fix` write their drop-ins. Its certificate, key and trust list are in `/var/lib/terractl/`. Files in transit are kept in `/var/lib/terractl/transfers/`, and removed once used, after 6 hours unused, or when the daemon restarts.
|
||||
|
||||
---
|
||||
|
||||
## Backups
|
||||
|
||||
Everything worth keeping is in `data/`, `instance.conf` and `serverconfig.txt`, which is exactly what `export` saves. A nightly backup kept for 14 days, as a root cron job (`sudo crontab -e`):
|
||||
Everything worth keeping is in `data/`, `instance.conf` and `serverconfig.txt`, which is exactly what a backup saves. `terractl backup` makes them on a schedule, and keeps a set number:
|
||||
|
||||
```cron
|
||||
30 4 * * * /usr/bin/terractl export calamity /var/backups/terraria/calamity-$(date +\%F).tar.gz && find /var/backups/terraria -name 'calamity-*.tar.gz' -mtime +14 -delete
|
||||
```bash
|
||||
sudo terractl backup enable calamity # daily, keeping the newest 14
|
||||
sudo terractl backup enable calamity --every 04:30 --keep 30 # every day at 4:30, keep 30
|
||||
sudo terractl backup enable calamity --every weekly --keep 0 # weekly, keep them all
|
||||
terractl backup list # schedules and backups of all instances
|
||||
sudo terractl backup now calamity # one now
|
||||
sudo terractl backup disable calamity # stop (keeps existing backups)
|
||||
```
|
||||
|
||||
Create the folder first with `sudo mkdir -p /var/backups/terraria`. Separately, `upgrade` backs up an instance's worlds and configs before every version change (see [Undoing an upgrade](#undoing-an-upgrade)). In a crontab, `%` has a special meaning and must be written as `\%`, as above. Terraria also keeps a `.bak` copy of each world next to the world file, which is useful if the latest save is damaged.
|
||||
`--every` takes `hourly`, `daily`, `weekly`, `monthly`, a time such as `04:30`, or anything else systemd's `OnCalendar=` accepts (`'Sun 03:00'`, `'*-*-* 00/6:00'`; see `man systemd.time`). Running `backup enable` again changes the schedule.
|
||||
|
||||
How it works:
|
||||
|
||||
- **One systemd timer per instance**, `terraria-backup@<name>.timer`. A backup missed while the machine was off is made soon after it starts again. Backups start up to 10 minutes after the scheduled time, so several instances don't all start at once.
|
||||
- **The world is saved first** if the server is running, as `export` does, so the backup has the current state. The server keeps running.
|
||||
- **Backups go in `/var/lib/terraria/backups/<name>/`**, as `<name>-<date>-<time>.tar.gz`. Members of the `terraria` group can read them, as they can the instances themselves (`serverconfig.txt` can contain the server password). Change the folder with `TERRARIA_BACKUPS` in `/etc/default/terractl`.
|
||||
- **Only scheduled backups are deleted** when there are more than `--keep`. The ones `upgrade` makes before changing version (`...-before-<zip>.tar.gz`) and ones you put there yourself are kept.
|
||||
- **`rename` takes the schedule along**, and `delete` turns it off. Existing backups stay where they are in both cases.
|
||||
|
||||
To restore one, import it under a new name, or replace the instance with it:
|
||||
|
||||
```bash
|
||||
sudo terractl import calamity-restored /var/lib/terraria/backups/calamity/calamity-20261002-040512.tar.gz
|
||||
```
|
||||
|
||||
If a scheduled backup fails, `terractl backup list` and `terractl doctor` say so; the details are in `journalctl -u terraria-backup@<name>`.
|
||||
|
||||
Backups on the same disk don't protect against the disk failing. Copy `/var/lib/terraria/backups` elsewhere now and then, or put it on another disk (with `TERRARIA_BACKUPS`, or a mount). Terraria also keeps a `.bak` copy of each world next to the world file, which is useful if the latest save is damaged.
|
||||
|
||||
---
|
||||
|
||||
@@ -926,6 +972,10 @@ The servers always run as the `terraria` user. Administration is simplest with `
|
||||
| `upgrade <name> <zip>` | root only | Checked by the script. Stops and starts the server, and unpacks the zip as `terraria`. |
|
||||
| `reinstall` | root (or `terraria`) | |
|
||||
| `fix-perms` | root only | Checked by the script. |
|
||||
| `fetch` | root, or members of the `terraria` group | Writes to `dist/`, which the group may. `--upgrade` needs root. |
|
||||
| `backup list` | root, or members of the `terraria` group | |
|
||||
| `backup enable`, `disable`, `now` | root only | Checked by the script. |
|
||||
| `doctor` | anyone | Without root, the checks that need it are skipped. `--fix` needs root. |
|
||||
| `mods <name>` (list) | root, or members of the `terraria` group | |
|
||||
| `mods add/enable/disable/remove` | root (or `terraria`) | Run as root, it sets ownership of the files it installs to `terraria`. |
|
||||
| `delete`, `rename` | root only | Checked by the script. |
|
||||
@@ -1002,6 +1052,44 @@ While a server runs, whether systemd started it or you did, it holds a lock on t
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Start with `doctor`
|
||||
|
||||
`terractl doctor` checks the whole setup and explains anything that's wrong, with the command that fixes it:
|
||||
|
||||
```
|
||||
$ sudo terractl doctor
|
||||
terractl 0.0.12 on nas
|
||||
|
||||
System
|
||||
ok user and group 'terraria'
|
||||
ok programs (including ICU and curl for tModLoader)
|
||||
ok folders /var/lib/terraria/instances and /var/lib/terraria/dist
|
||||
ok server zips: 3 in /var/lib/terraria/dist
|
||||
FAIL /etc/systemd/system/terraria@.service replaces the package's terraria@.service (left over from a manual setup?)
|
||||
fix: rm /etc/systemd/system/terraria@.service && systemctl daemon-reload
|
||||
ok the services can use /var/lib/terraria/instances and /var/lib/terraria/dist
|
||||
ok the 'terraria' group can read the servers' journal
|
||||
|
||||
Instances
|
||||
FAIL calamity: 3 files aren't owned by terraria, so the server can't change them (saving can fail)
|
||||
fix: terractl fix-perms calamity
|
||||
ok pvp (vanilla, port 7778, terraria-server-1458.zip)
|
||||
|
||||
2 problem(s), 0 warning(s).
|
||||
terractl doctor --fix fixes 1 of them; the others need the steps shown.
|
||||
```
|
||||
|
||||
It checks:
|
||||
|
||||
- **The system:** the `terraria` user and group; `unzip`, and ICU and `curl` if there are tModLoader instances; the instances, zips and backups folders; unreadable zips; the systemd units, including old copies in `/etc/systemd/system` that replace the package's; whether the services may use the folders set in `/etc/default/terractl` (see [Changing locations](#changing-locations)); the servers' journal; polkit; the daemon, if it's on; and servers or backups that are still scheduled for instances that no longer exist.
|
||||
- **Each instance:** files the server can't change, or that others can read; its server zip (missing, wrong type, or a `ZIP=` changed by hand that hasn't been applied yet); paths in `serverconfig.txt` that point somewhere else (e.g. after copying it by hand); enabled mods that aren't installed; instances sharing a port; and failed starts or backups.
|
||||
|
||||
`--fix` fixes what's safe to fix by itself, and says what it did: file ownership and modes (`fix-perms`), folder and zip permissions, the servers' journal access, the drop-in for moved folders, and boot links or backup schedules for instances that are gone. Everything else, such as deleting unit files or opening up home folders, is left for you, with the steps shown. `terractl doctor <name>` checks only that instance (and the system).
|
||||
|
||||
Without `sudo`, `doctor` skips the checks that need root and says so. It exits with status 1 if it finds a problem, so it can be used in scripts and monitoring.
|
||||
|
||||
### Common problems
|
||||
|
||||
**tModLoader stops with `Aborted` right after "Launched Using Local Dotnet".**
|
||||
The ICU library is missing, so .NET aborts at startup. Fix it with `sudo apt install libicu-dev`, then restart the instance. To confirm, check that `ldconfig -p | grep -c libicu` prints more than 0.
|
||||
|
||||
@@ -1073,6 +1161,7 @@ Its access was revoked with `daemon revoke`, or the host's `/var/lib/terractl` w
|
||||
- common server console commands for `cmd` (`save`, `say`, `playing`, `kick`...);
|
||||
- the options of `enable`, `disable`, `watch`, `upgrade`, `reinstall`, `delete`, `export`, `copy` and `move`;
|
||||
- server zips for `upgrade`, only those of the instance's type (on a remote, all of its zips);
|
||||
- `vanilla`/`tmodloader` and the options for `fetch`, `backup` actions and schedules (`--every daily` etc.), and `--fix` for `doctor`;
|
||||
- remote names after `--host`, and `<remote>:<name>` for `copy` and `move`. Instance names on a remote are asked from its daemon, so they can take a moment;
|
||||
- `.tar.gz` files for `export` and `import`;
|
||||
- `mods` actions. For `mods add` it completes `.tmod` files and folders; for `mods enable` and `mods remove`, the installed mods; for `mods disable`, the enabled ones.
|
||||
@@ -1101,6 +1190,15 @@ terractl upgrade <name> <zip>|latest [--downgrade] [--no-backup]
|
||||
terractl reinstall <name> [--clean] Re-unpack the same version on next start
|
||||
(--clean also re-downloads .NET)
|
||||
terractl fix-perms <name> Reset the owner and modes of all its files
|
||||
terractl fetch vanilla|tmodloader [<version>] [--upgrade <name>]
|
||||
Download a server zip (default: the latest)
|
||||
terractl fetch vanilla|tmodloader --list Versions available to download
|
||||
terractl backup enable <name> [--every <when>] [--keep <n>]
|
||||
Back up on a schedule (default: daily, keep 14)
|
||||
terractl backup disable <name> Stop scheduled backups (keeps existing ones)
|
||||
terractl backup now <name> Back up now
|
||||
terractl backup list [<name>] Schedules and backups
|
||||
terractl doctor [<name>] [--fix] Check the setup; --fix fixes what it safely can
|
||||
terractl mods <name> [list] Show installed mods
|
||||
terractl mods <name> add <folder|file.tmod>... Install and enable mods (and ModConfigs)
|
||||
terractl mods <name> enable|disable <Mod>... Change which mods load
|
||||
|
||||
Reference in new issue
Block a user