This guide describes how to create a systemd service to run the PHP application.
- Setup
- Create a systemd unit configuration file
- Enable and start the todolist service
- Reboot and try again
- What have I done?
- End result
Make sure you have completed the previous exercise.
Stop your php -S command if it is still running.
You must write a systemd unit file which describes how and when to run the
application. You may save this file to /etc/systemd/system/todolist.service.
You will have to use nano (or Vim) to create and edit this file directly on the
server. You cannot use an SFTP client.
Reminder: You can edit a file with nano by running the following command:
sudo nano <path>. If the file does not exist, it will be created by nano when you exit and save. Thesudois necessary because the/etc/systemd/systemdirectory is only writable byroot.You cannot use FileZilla because you cannot connect with
rootover SFTP as that is considered insecure and therefore not allowed by the default configuration of the SSH server.
You may find the following documentation useful to write your unit file:
[Unit]section options[Service]section options- Environment
(for the
Environment,UserandWorkingDirectoryoptions)
- Environment
(for the
[Install]section options
Here are a few hints:
- In the
[Unit]section of your unit file:-
You should briefly document what your service is with a
Descriptionoption. -
You may want to use an
Afteroption. What other service needs to already be running for the PHP TodoList to work? If there is one, your application should start after it.Hint: You can use the
ls /lib/systemd/systemcommand to list other system services.
-
- In the
[Service]section of your unit file:-
You should tell systemd what command to run your application with using the
ExecStartoption.Hint: You must use absolute command paths with
ExecStart. For example, if you want to execute thephpcommand, you cannot simply writephp, you have to use the absolute path to the command instead.You can find the path to any binary with the
which <command>command. -
You must tell systemd where to execute the command (in which directory) with the
WorkingDirectoryoption. This must be an absolute path.Hint: Go in the application directory on the server and execute the
pwd(print working directory) command if you are not sure what the absolute path is. -
You should tell systemd which user must run the command with the
Useroption. You can use your own username.It's bad practice to run an application with the
rootuser. An application running as therootuser that has any security flaw could allow an attacker to gain superuser privileges, and thus obtain complete control over your server.To go further, you could create a system user specifically to run this application. This would allow you to limit that user's privileges, also limiting the damage an attacker could make if your application is compromised.
-
If your application requires one or multiple environment variables to be set, you can set them by adding an
Environmentoption. This option can be included in the file multiple times to set multiple environment variables. -
In case your application crashes due to a bug or a server issue, you should configure the
Restartoption so that systemd automatically restarts it when there is a problem.
-
- In the
[Install]section of your unit file:-
You may want to set the
WantedByoption to tell systemd to automatically start your application when the server boots. You can use the valuemulti-user.targetfor this option.multi-user.targetmeans that the operating system has reached the multi-user runlevel. In other words, it means that user management and networking have been initialized. This is typically when you want to start running other processes which depend on users and/or networking, like web applications.
-
Hint: You should put comments in your unit file to explain what each option is for. This can help you if you come back later and do not remember what you did or why. Any line starting with
#is considered a comment.To see an example of a unit file, you can look at the one for the MySQL server you installed in previous exercises:
$> cat /lib/systemd/system/mysql.serviceYou will not use the same options as MySQL, but this shows you what a functional unit file can look like.
Enable and start your new service.
Reminder: The systemd control command (
systemctl) allows you to manipulate services:sudo systemctl <operation> <service-name>.The operations to enable and start are simply
enableandstart. The name of the service is the name of your unit file without the ".unit" extension. For example, if the unit file is "todolist.service", the name of your service is "todolist".
Check that the service is running properly and that there were no errors.
You can also use the
systemctlcommand to check the status of your service with itsstatusoperation (instead ofenableorstart). It should also show you the last few lines of its logs.To see the complete logs, you can use the
sudo journalctl -u <service-name>command. Pay attention to the timestamps at the beginning of each line, which will let you know when each event occurred.
You (and everybody else) should be able to access the running todolist
application in your browser on your server's IP address and port 3000 (e.g.
W.X.Y.Z:3000).
If the status indicates a problem with your unit file, you should fix the
problem in your unit file. Then, be sure to run sudo systemctl daemon-reload
to take the changes into account. You may also need to run sudo systemctl restart todolist to restart your application.
If you have configured your unit file correctly, your application should restart automatically if the server is rebooted.
Try to reboot your server:
$> sudo rebootThe application should still be running.
You have configured your operating system's process manager (systemd, which comes bundled with Ubuntu) to manage your application's lifecycle for you. You no longer have to worry about:
- Running the command to start the application.
- Restarting the application after rebooting the server.
- Restarting the application after it crashes due to a bug.
