Setting Up Friendica Daemon as a Systemd Service Tutorial

Friendica relies heavily on worker processes for doing things like federation, cleaning up the database, and many other tasks. It can either be run as a periodically running system cron job or in a daemon mode. A lot of this is personal preference of the administrator. I prefer to run it as a daemon process, mostly because posts are federated instantly rather than waiting for the cron job to be kicked off again several minutes later. The best way to use the daemon process is to have it be managed by systemd so that Linux will make sure it starts on startup, create a new one if it crashes, etc. On the Friendica links page I found this post by TauSys on setting up the daemon as a systemd process . None of the steps are hard per se, but it lays them out very clearly. It is unfortunately in German and some of the translation messes up some of the example configuration files etc. For that reason I’ve decided to write this post on how to setup the daemon as a systemd process, inspired heavily by the above post.

Notes

These steps will require you to know the installation location of your Friendica instance. If you followed my guide on setting it up under Ubuntu then it will be in /var/www/html. In most cases you will find it in that directory or something underneath of /var/www. For the remainder of this document the example locations in configuration files etc. will be using the /var/www/html location for convenience. Also for convenience commands to create/edit files will use the nano editor but you are of course free to replace it with your editor of choice.

Configuring PID File

When the daemon is kicked off it creates a “Process ID” (PID) file. This is used by Linux to provide a convenient place for determining process IDs without running queries etc. The /run directory is the common place for this file so we will set this to be a daemon.pid file inside of a friendica sub-folder. The location of the PID file location that Friendica will use is stored in our local configuration file found in the config/local.config.php file. It is set under the system settings with the keyword pidfile:

 'system' > [
     ...
  'pidfile' => '/run/friendica/daemon.pid',
     ...
  ],

For example that section of the local.config.php file on the friendicadevtest1 server from our installation tutorial above reads:

	'system' => [
		'pidfile' => '/run/friendica/daemon.pid',
		'urlpath' => '',
		'url' => 'https://friendicadevtest1.myportal.social',
		'ssl_policy' => 1,
		'basepath' => '/var/www/html',
		'default_timezone' => 'UTC',
		'language' => 'en',
	],

Configuring the PID File Hierarchy

We are putting the PID file in a sub-directory because we are going to setup systemd to run the process as the www-data user. Because of that we can’t just throw it into the /run directory since only root has permission to write there. We therefore are going to make a Friendica specific sub-directory that we will have www-data own. We could do this manually now but when the system reboots the directory will no longer exist. We therefore want to configure systemd to create it for us at startup time. We do this with a configuration file in the /etc/tmpfiles.d folder. Create a file there called friendica.conf by executing the command:

sudo nano /etc/tmpfiles.d/friendica.conf

Paste into that file the following text and save it:

d /run/friendica 0755 www-data www-data -

This tells systemd to create a directory at /run/friendica with ownership set to the www-data user and the group www-data. The www-data user will be able to do whatever they want in the folder. Others will be able to read this directory.

Now we want to do some manual testing to confirm we have everything setup before we build our systemd service file. Let’s create the directory by using systemd command:

systemd-tmpfiles --create --prefix /run/friendica

You can prove that this executed and worked correctly by executing

ls -l /run | grep friendica

You should see something like the below with different dates:

drwxr-xr-x  2 www-data www-data   60 Aug  4 14:42 friendica

Manually Testing Daemon Process Lifecycle

Assuming you got the above you are ready to start testing that the daemon can be run by starting it manually. First cd to your install directory (again ours is /var/www/html you’ll have to use your particular folder):

cd /var/www/html (the install directory)

Now lets try running the daemon as the www-data user and confirm it starts correctly:

sudo -u www-data bin/daemon.php start

You should see a prompt that reads like:

Starting worker daemon.
Child process started with pid 1276.

If you do not one of the prior steps was not completed correctly. If it complains about the configuration not having the pidfile keyword you may have a typo in your local.config.php file. If it complains about file permission then you have misconfigured one of the steps in the temporary file creation process.

At any time you can check the status of the daemon directly be executing the command:

bin/daemon.php status

It will either output “Pidfile wasn’t found. Is the daemon running?”, if it never ran or isn’t running, or something like “Daemon process 1276 is running.” if it is actively running.

If you have completed this step you are ready to create your systemd configuration file. First stop the current daemon so systemd will be able to start it after configuration:

bin/daemon.php stop

Create systemd Configuration File

Systemd “services” are created with configuration files under the /etc/systemd/system folder. We will want to create one for our Friendica daemon which we will call friendica-daemon.service. Create a new file with the below command and copy/paste the below template text into it:

sudo nano /etc/systemd/system/friendica-daemon.service
[Unit]
Description=Friendica daemon
After=network.target mariadb.service
Requires=network.target remote-fs.target nss-lookup.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/html
Type=simple
StandardOutput=null
StandardError=syslog
ExecStart=/usr/bin/php ./bin/daemon.php start
ExecStop=/usr/bin/php ./bin/daemon.php stop
PIDFile=friendica/daemon.pid
PrivateTmp=true
InaccessibleDirectories=/home /root /boot /opt /mnt /media
ReadOnlyDirectories=/etc /usr
Restart=always

[Install]
WantedBy=multi-user.target

Most of this file can be used as is. However some of the lines you will need to customize to your own installation. The first line to check is the After line. This tells systemd to not start this service until other services have been successfully started. In the above it says to not start it until the network and MariaDB is started. If you are using a different database you’ll need to change the second service to be the name of your database engine type. For example if you are using MySQL it would read:

After=network.target mysql.service

The second line to check is the WorkingDirectory. This is the folder that your Friendica instance is stored in. In our examples it is /var/www/html which is why it is set to that above. You will need to customize that to be consistent with your directory.

We can now reload systemd configurations to pick up the above new service definition

sudo systemctl daemon-reload

…and can then check that the update daemon can be started with systemd:

sudo systemctl start friendica-daemon.service

If you got any errors on startup then double check that you don’t have any typos in the configuration file. If you didn’t receive any errors then check the status of the Friendica daemon with systemd with the command:

systemctl status friendica-daemon.service 

You should see output that reads like the below (the active status the most important part):

● friendica-daemon.service - Friendica daemon
     Loaded: loaded (/etc/systemd/system/friendica-daemon.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-08-04 14:38:32 UTC; 6s ago
   Main PID: 1458 (php)
      Tasks: 1 (limit: 1119)
     Memory: 15.4M
        CPU: 523ms
     CGroup: /system.slice/friendica-daemon.service
             └─1458 /usr/bin/php ./bin/daemon.php start

Press the q key to exit the status gracefully.

Configuring the Daemon to Start on Reboot

We now want to make sure that the daemon starts on restart/boot. We do this by enabling the service with the command:

systemctl enable friendica-daemon.service

You should see output that reads something like:

Created symlink /etc/systemd/system/multi-user.target.wants/friendica-daemon.service → /etc/systemd/system/friendica-daemon.service.

Now you can reboot the server with sudo reboot and once it comes back up check that the service properly ran. First you can check it with the status command again like in the above step. You can also check with the daemon software itself like in the manual steps. Lastly you can directly ask the system with the ps command:

ps aux | grep daemon.php

Which should give you output like below:

www-data    1084  0.2  2.0 117312 20876 ?        Ss   14:42   0:00 /usr/bin/php ./bin/daemon.php start
root        1262  0.0  0.2   7008  2088 pts/0    S+   14:43   0:00 grep --color=auto daemon.php

If you want to confirm for yourself the behavior of systemd in restoring your process you could kill the daemon process listed in that process list command (in the above case 1084) and confirm that instantly a new one was created to replace it.

Conclusion

You now have a systemd managed lifecycle of your Friendica daemon process from starting up on initial boot to creating new ones if something causes the existing one to crash.