Monday, October 12, 2020

Run php script as daemon process with Systemd (AWS EC2)

To run PHP script as a  daemon service under Linux using Systemd do as below. Best way to make a shell script daemon? With new systemd you can create a service. You must create a file or a symlink in /etc/systemd/system/, eg. myservice.service and place content like this one, myservice will be the name of the service:



Create a service unit file:

Let’s create a file called /etc/systemd/system/myservice.service

[Unit]
Description=My PHP service

[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/php -f /path/to/myservice.php

[Install]
WantedBy=multi-user.target

Now, you will be able to start, get status, restart and stop the services using the command

systemctl <start|status|restart|stop|enable> myservice

sudo systemctl enable myservice  
- enable for restart after boot

sudo systemctl is-enable myservice  
- check if myservice is enabled for startup

sudo systemctl start myservice  
- start the service

sudo systemctl restart myservice  
- restart the service

sudo systemctl status myservice  
- check the status of the service.


What is systemd PID file?

Can I use this script without creating a PID file? Why do we need a PID file at all? In which case we should use PID file? 

PIDFile=: If the service type is marked as "forking", this directive is used to set the path of the file that should contain the process ID number of the main child that should be monitored. when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.

Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time... Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.

systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)


For Type, there are a few choices: forking, simple, etc.

When you start the service manually from the command line (without using the nohupprefix command or the & suffix to run it in the background, or in other words, just run the command you would put on the ExecStart= line of the .service file), what happens?

a) If the service starts and keeps running, and the prompt does not return until you press Control-C or stop the service in some other way: then Type = simple is the right choice.

b) If the prompt returns but the service keeps running in the background (i.e. the service daemonizes itself on its own), then Type = forking is the right choice.

Note: many service applications designed to be portable to many Unix-style systems may behave as b) by default, but can be made to work like a) by adding an option (usually described as "don't fork", "keep running in foreground", "don't daemonize" or similar). In that case, if the option has no other side effects, then adding the option and using the a)-type behavior would be preferable for systemd.

Forking systemd service example

[Unit]
Description=My PHP service

[Service]
Type=forking
Restart=always
RestartSec=1
User=root
PIDFile=/var/run/myservice.pid
ExecStart=/usr/bin/php -f /path/to/myservice.php

[Install]
WantedBy=multi-user.target