How to use Systemd Timers to Schedule the Execution of a Specific Command
Tags: systems, systemd, tutorial, devops
Published: 2022-12-31 19:09:58

If you need to run a command periodically on your Linux server, you might consider using a Systemd timer instead of a cron job. Systemd timers offer more control over your command and are more flexible than Cron jobs. 
Here's a quick comparison between the two:

- Systemd timers are more flexible than Cronjobs. They allow you to specify more granular time intervals, such as "every 15 minutes" or "every other hour on weekdays." They also allow you to specify more complex schedules, such as "every Monday, Wednesday, and Friday at 10am."
    
- Systemd timers are easier to manage. You can use the `systemctl` command to start, stop, enable, disable, and view the status of Systemd timers. This is much more convenient than having to manually edit Cronjob configuration files.
    
- Systemd timers offer better integration with the rest of the system. They can be used to trigger system-wide events, such as triggering a system shutdown or reboot. They can also be used to trigger custom targets, which are collections of units (such as services, sockets, and paths) that can be started, stopped, or restarted as a group.
    
- Systemd timers can be used to trigger actions based on system state. For example, you can use a timer to trigger a script that checks for low disk space and takes action to free up space if necessary.
    
- Systemd timers are more reliable than Cronjobs. Systemd is a modern and reliable init system that is used by default in most modern Linux distributions. In contrast, Cron has a long history of security vulnerabilities and can be prone to errors. By using Systemd timers, you can take advantage of the reliability and security benefits of Systemd.


As an example, let's update Algolia indexes for Magento products using the default Magento command, we will need to create two files: a Systemd unit file and a Systemd timer file.

The unit file will contain the configuration for the service that will be run to update the Algolia indexes. This will include details such as the command to be run, the working directory, and any dependencies or requirements for the service.

The timer file will contain the configuration for the timer that will control how often the service is run. This will include details such as the time interval between runs, as well as any special scheduling considerations (e.g. only running the service on certain days of the week).

Once these two files are created, we can use the `systemctl` command to start, stop, enable, and disable the timer as needed. This will allow us to easily automate the process of updating the Algolia indexes for our Magento products.

Let's first create the Systemd unit file on /etc/systemd/system/update-products-indexes.service

The content of **update-products-indexes.service**
```shell
[Unit]
Description=Update indexes
Requires=nginx.service
After=nginx.service

[Service]
Type=oneshot
WorkingDirectory=/var/www/magento-website/current
ExecStart=/usr/bin/php bin/magento indexer:reindex

[Install]
WantedBy=multi-user.target
```

There are a few things to note in the following configuration:

-   The `Type=oneshot` parameter specifies that the service should only be run once, and not kept alive.
-   The `WorkingDirectory` parameter specifies the directory in which the command will be run. In this case, it will be inside the Magento installation located at `/var/www/magento-website/current`.
-   The `ExecStart` parameter specifies the command to be run, which comes with the Magento installation.

For more information, you can refer to the official documentation.

Next we will create the timer file and save it on /etc/systemd/system/update-products-indexes.timer

The content of **update-products-indexes.timer**

```shell
[Unit]
Description=Timer for products indexes update
Requires=update-products-indexes.service

[Timer]
Unit=update-products-indexes.service

# Time to wait after booting before we run first time
OnBootSec=10min

# Define a calendar event (see `man systemd.time`)
OnCalendar=0/6:00:00

[Install]
WantedBy=multi-user.target
```

To tell Systemd to run our configured service, we need to start the corresponding timer with the following command:
```
sudo systemctl start update-products-indexes.timer
```

To ensure that the service is run at boot time in case the server is restarted, we need to enable both the service and the timer with these commands:
```
sudo systemctl enable update-products-indexes.service
sudo systemctl enable update-products-indexes.timer
```

It's important to note that we only need to start the timer file, as it will call the unit file (service) at the specified frequency. 
However, if you want to run the unit file directly, you can use the following command:
```shell
`sudo systemctl start update-products-indexes.service`
```
In conclusion, using Systemd timers can be a powerful and convenient way to automate the execution of a specific command on a Linux server. They offer greater flexibility and ease of management compared to cron jobs, and provide better integration with the rest of the system. Whether you need to run a command periodically or based on system state, Systemd timers can help you get the job done efficiently and reliably. So next time you need to automate a task on your Linux server, consider using Systemd timers as an alternative to cron jobs.