Recently, I’ve been hosting a Foundry VTT server (a
nodejs app) in a virtual machine on my home network. I would start the
application inside a
tmux session, by
executing a CLI command which worked… fine. However, if the VM restarted or
the applications crashed, I had to ssh in and manually run the command again. So,
to better automate this tedious task, I created a unit file to
define the foundry server as a systemd service. Here’s how.
With so many distributions utilizing
systemd, unit files have become a new
standard for auto-starting, or re-starting, applications in Linux. Simply put,
unit files are used to define resources to be managed by systemd. This includes
services. So to run FoundryVTT as a service, we need to create a new systemd
.service unit file.
Creating the service file
To create a unit file, I opened
vim and filled it with the following contents:
[Unit] Description=A service to run the Foundry VTT node app Documentation=https://foundryvtt.com After=network.target [Service] Environment=NODE_PORT=30000 Type=simple User=ryan ExecStart=/usr/bin/node /home/user/foundryvtt/resources/app/main.js --dataPath=/home/user/foundrydata Restart=on-failure [Install] WantedBy=multi-user.target
This file tells systemd all the information it needs to run the service. The
contents of the
[Unit] section define some basic information about the unit
file. The variables which define our service, are appropriately listed in the
[Service] section and include:
Environment=NODE_PORT=30000sets an environment variable
Type=simplestates that our service is executing a single command, and is “started” when that command runs.
User=ryantells the service to run under the
ExecStartdefines which command to run when the service is started (this is the command I had to manually type in
Restart=on-failuretells the service to automatically restart on any failures.
Save and exit the file.
Start and Enable the Service
With the unit file created, the new service can be started:
sudo systemctl start foundryvtt
In addition to starting the service, I also enabled it so that it will automatically launch whenever the system reboots:
sudo systemctl enable foundryvtt
Stopping, Restarting, and Status
To check that the service is running, use the command
systemctl status foundryvtt:
sudo systemctl status foundryvtt [ryan@magmar dotfiles]$ sudo systemctl status foundryvtt ● foundryvtt.service - A service to run the Foundry VTT node app Loaded: loaded (/usr/lib/systemd/system/foundryvtt.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2020-07-12 16:34:29 EDT; 2s ago Docs: https://foundryvtt.com Main PID: 1070 (node) Tasks: 11 (limit: 2327) Memory: 93.8M CPU: 1.227s CGroup: /system.slice/foundryvtt.service └─1070 /usr/bin/node /home/ryan/foundryvtt/resources/app/main.js --dataPath=/home/ryan/foundrydata ... *A Bunch of Logs I removed*...
The output contains
Active: active (running), which means the service is
running. We can also restart or stop the service using the
systemctl restart foundryvtt and
systemctl stop foundryvtt commands, respectively.
For example, I can stop the service and then check the status to verify it is
killed (Note the
Active: inactive (dead) in the status output).
[ryan@magmar]$ sudo systemctl stop foundryvtt [ryan@magmar]$ sudo systemctl status foundryvtt ● foundryvtt.service - A service to run the Foundry VTT node app Loaded: loaded (/usr/lib/systemd/system/foundryvtt.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: https://foundryvtt.com
That’s about it. Systemd unit files might seem complicated at first, but after writing, one they aren’t that bad. Additionally, it turns out that using automation to create them isn’t too difficult either… but I’ll show that in another post. Until then, enjoy!
Creating Systemd Unit Files using Ansible My Three Required Gnome Extensions