Сессия tmux позволяет серверу Terraria пережить отключение SSH, но после перезагрузки Linux сама сессия исчезает. Для автоматического возврата нужен сервис systemd: с явно выбранным существующим миром, постоянным пользователем и остановкой через игровую команду exit, после которой сервис ждёт завершения процесса.
Ниже — пример для vanilla PC dedicated server на x86-64 VPS с Debian/Ubuntu. Предполагается, что полный официальный Linux-дистрибутив сервера уже запускается вручную. У TShock, tModLoader, контейнеров и серверов под панелью собственные механизмы запуска: второй конкурирующий сервис для них создавать не нужно.
Зафиксируйте пользователя и пути#
В примере используется такая структура. Если у вас другая, замените все соответствующие пути:
| Что | Пример |
|---|---|
| Пользователь сервиса и домашний каталог | terraria, /srv/terraria |
| Полный распакованный Linux-дистрибутив | /opt/terraria/server |
| Конфигурация | /etc/terraria/serverconfig.txt |
| Существующий мир | /srv/terraria/worlds/main.wld |
| Сервис | terraria.service |
Перед сменой способа запуска введите exit в старой консоли, дождитесь завершения процесса и сохраните независимую копию остановленного каталога миров. Отключите старое задание cron, автозапуск screen или политику рестарта панели. Два процесса не должны одновременно записывать один мир.
Нужен отдельный пользователь terraria с домашним каталогом /srv/terraria. Если его нет, создайте средствами своего дистрибутива. Ему необходимы чтение и доступ к каталогам полного дистрибутива, чтение конфигурации, запись в каталог миров и существующие файлы мира. Для замены резервных файлов может требоваться запись в сам каталог, даже если .wld доступен на запись.
Владельцем исполняемых файлов оставьте администратора; у TerrariaServer.bin.x86_64 должно быть право выполнения. Конфигурацию с паролем подключения разрешите читать только владельцу и группе сервиса. До настройки автозапуска проверьте запуск от нужного пользователя:
sudo -u terraria -H /bin/bash -c 'cd /opt/terraria/server && TERM=xterm ./TerrariaServer.bin.x86_64 -config /etc/terraria/serverconfig.txt'
В конфигурации укажите уже проверенный мир, чтобы запуск не требовал ответов в консоли:
world=/srv/terraria/worlds/main.wld
worldpath=/srv/terraria/worlds
banlist=/srv/terraria/banlist.txt
port=7777
maxplayers=8
password=CHANGE_THIS_PASSWORD
upnp=0
Замените пароль до запуска. Параметра autocreate здесь намеренно нет: опечатку в пути нужно исправить, а не получить вместо своего мира новый пустой. Проверьте сообщения запуска, зайдите в ожидаемый мир, затем введите exit в консоли и дождитесь остановки.
Настройте процесс и канал команд для systemd#
Сохраните полный пример в /etc/systemd/system/terraria.service:
[Unit]
Description=Terraria vanilla dedicated server
After=network.target
RequiresMountsFor=/opt/terraria/server /srv/terraria/worlds
[Service]
Type=simple
User=terraria
Group=terraria
WorkingDirectory=/opt/terraria/server
Environment=HOME=/srv/terraria
Environment=TERM=xterm
UMask=0077
RuntimeDirectory=terraria
RuntimeDirectoryMode=0700
ExecStartPre=/usr/bin/test -r /etc/terraria/serverconfig.txt
ExecStartPre=/usr/bin/test -r /srv/terraria/worlds/main.wld
ExecStartPre=/usr/bin/rm -f /run/terraria/console
ExecStartPre=/usr/bin/mkfifo -m 0600 /run/terraria/console
ExecStart=/bin/bash -c 'exec 3<>/run/terraria/console; exec /opt/terraria/server/TerrariaServer.bin.x86_64 -config /etc/terraria/serverconfig.txt <&3'
ExecStop=/bin/bash -c 'kill -0 "$$MAINPID" 2>/dev/null || exit 0; exec 3<>/run/terraria/console; echo exit >&3; while kill -0 "$$MAINPID" 2>/dev/null; do sleep 1; done'
Restart=on-failure
RestartSec=10
TimeoutStopSec=120
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Закрытый FIFO в /run/terraria передаёт команды в консоль. В Linux Bash может открыть его сразу для чтения и записи, не ожидая другого процесса. Оставшийся открытым дескриптор также не даёт вводу завершиться из-за отсутствия писателя. Команда exec заменяет Bash на Terraria: systemd наблюдает сам игровой процесс, а не оболочку, которая запустила что-то в фоне и закончилась.
При плановой остановке ExecStop отправляет exit и ждёт исчезновения процесса. Двойной знак доллара нужен, чтобы systemd передал $MAINPID оболочке без преждевременной подстановки. Начальная проверка учитывает случай, когда процесс уже умер. Явная команда systemctl stop не вызывает повторный запуск через Restart=on-failure.
Таймаут 120 секунд — начальное выбранное значение, а не гарантия сохранения. Если процесс зависнет, systemd сможет завершить его принудительно. Увеличьте время, если реальные сохранения этого требуют, и разбирайте каждый случай превышения. При пропадании питания или убийстве ядром эта последовательность не выполняется.
Сначала проверьте остановку и запуск, затем reboot#
Проверьте unit и включите сервис:
sudo systemd-analyze verify /etc/systemd/system/terraria.service
sudo systemctl daemon-reload
sudo systemctl enable --now terraria.service
sudo systemctl status terraria.service --no-pager
sudo journalctl -u terraria.service -b --no-pager -n 100
sudo ss -ltnp 'sport = :7777'
Сначала исправьте ошибки синтаксиса и путей к программам. Проверка чтения мира не пускает отсутствующий файл в меню выбора, но ещё не подтверждает его исправность и возможность записи. В журнале должна прослеживаться загрузка нужного мира до начала приёма подключений. Слушающий сокет сам по себе не доказывает доступность через внешний firewall или успешный вход игрока.
Подключитесь совместимым vanilla-клиентом, сделайте небольшое узнаваемое изменение мира и выполните sudo systemctl stop terraria.service. По журналу убедитесь, что сохранение и завершение закончились без таймаута и принудительного убийства. Запустите сервис снова и проверьте изменение. Только после этого планируйте перезагрузку VPS, предупредив игроков и подготовив независимую копию.
После возвращения SSH проверьте systemctl is-enabled terraria.service, статус текущей загрузки, журнал и порт теми же командами. Предыдущую остановку можно посмотреть через journalctl -u terraria.service -b -1, если журнал сохранил ту загрузку. Ещё раз проверьте мир в игре.
Если вручную всё работает, а после reboot — нет, сравните пользователя, абсолютные пути, монтирование файловой системы и права каталогов. Сервис не наследует вашу SSH-оболочку и домашний каталог. Когда таких собственных VPS несколько, Nexardo помогает организовать общее управление инфраструктурой; путь к миру и корректную остановку всё равно нужно явно определить в настройке каждого сервера.




