I have a crontab entry that executes a shell script every 30 minutes. It passes a parameter to th script. I need to convert it to be a systemd timer. My crontab entry is:
*/30 * * * * /Users/jturman/development/john/fastapi/cron.sh sandbox >> /Users/jturman/development/john/fastapi/python-cron.log 2>&1
To convert your cron job to a systemd timer, you need to create two separate files: a service unit file and a timer unit file. Additionally, you need to make sure that systemd
can access your script and that it has the necessary execution permissions.
-
Create the Service Unit File
This file defines the actual work to be executed. Let’s create it at
~/.config/systemd/user/fastapi-cron.service
:[Unit] Description=Run fastapi cron script [Service] Type=oneshot ExecStart=/Users/jturman/development/john/fastapi/cron.sh sandbox StandardOutput=append:/Users/jturman/development/john/fastapi/python-cron.log StandardError=append:/Users/jturman/development/john/fastapi/python-cron.log
-
Create the Timer Unit File
This file defines when the script should be executed. Let’s create it at
~/.config/systemd/user/fastapi-cron.timer
:[Unit] Description=Run fastapi cron script every 30 minutes [Timer] OnBootSec=15min OnUnitActiveSec=30min [Install] WantedBy=timers.target
OnBootSec=15min
: This means the timer will trigger 15 minutes after boot (you can adjust it if needed).OnUnitActiveSec=30min
: This means the script will rerun every 30 minutes after it was last run.
-
Reload systemd daemons and enable the timer
Since these files are in your user directory, you should manage them using the
--user
flag. Execute the following commands:# Reload the systemd manager configuration systemctl --user daemon-reload # Start and enable the timer systemctl --user start fastapi-cron.timer systemctl --user enable fastapi-cron.timer
-
Verify the Timer Status
Check if the timer is active and running as expected:
systemctl --user list-timers fastapi-cron.timer
You should see output indicating that your timer is active and when it is next set to fire.
By following these steps, you should have successfully converted your cron job to use systemd
timers instead. Keep in mind that if your script requires any specific environment variables or paths, you may need to explicitly set them in the service file or adjust your script accordingly.
how did you choose the path for the 2 files?
The paths for the systemd service and timer files were chosen based on the assumption that you want to use user-specific systemd units, which are managed without requiring root privileges. Here’s why those paths were chosen:
-
User-Specific Directory (
~/.config/systemd/user/
):- Files placed here apply only to the user that owns them. This is appropriate when you are creating systemd units that do not need to be managed by the system-wide systemd but rather on a per-user basis.
- This directory structure conforms to the XDG base directory specification, which is widely used for user-specific configuration files.
- Using user-specific units means you don’t need administrative privileges (
sudo
) to manage the services and timers.
-
File Names (
fastapi-cron.service
andfastapi-cron.timer
):- The
.service
file defines what will happen when the timer triggers. - The
.timer
file defines when the.service
should be triggered. - Names are chosen to be meaningful and descriptive of their function. You want them to reflect the task they are managing, especially if you end up creating more timers and services later.
- The
If setting up systemd units for the system that apply to all users, you would place them in directories like /etc/systemd/system/
for custom units or /usr/lib/systemd/system/
for units provided by packages. However, you would need administrative rights to manage these system-wide systemd units.
is the .config directory in my home directory expected by systemctl?
Yes, the ~/.config/systemd/user/
directory is the expected location for user-specific systemd unit files, including both .service
and .timer
units. When you manage systemd units with the --user
flag, systemctl
looks in the ~/.config/systemd/user/
directory by default for unit files specific to your user account.
Here’s a brief summary of how this works:
-
Per-User Units:
- By placing unit files in
~/.config/systemd/user/
, you create a setup where these units are managed at the user level. - This means you don’t need root privileges to enable, start, stop, or view the status of these units.
- By placing unit files in
-
Enabling User Services:
- You control and manage these services using
systemctl --user
commands. - For example, to start or enable a user-specific unit, you’d use:
systemctl --user start myservice.timer
andsystemctl --user enable myservice.timer
respectively.
- You control and manage these services using
-
Activating the User Manager:
- You have to ensure that your user session is running a systemd user manager instance for this to work.
- On most modern Linux distributions, this is done automatically when you log into your graphical or text session. If not, you may need to manually activate user systemd with commands like
loginctl enable-linger [your-username]
.
-
Debugging and Status:
- You can view the status of user-specific units similarly to system-wide ones:
systemctl --user status myservice.service
.
- You can view the status of user-specific units similarly to system-wide ones:
Using this setup allows regular users to have personal background services and scheduled tasks without needing administrative intervention, and it keeps your user-specific configurations isolated within your home directory.
please explain again how to make my new fastapi service keep running even if I log out.
To ensure that your user-specific systemd services continue running even after you log out, you need to use the linger
feature of systemd
. Here’s how you can set it up:
-
Enable Linger for Your User Account:
-
Linger
is asystemd
feature that allows user services to continue running after you log out and to start user services without the need for the user to log in. -
To enable linger for your user account, use the
loginctl
command:sudo loginctl enable-linger your-username
Replace
your-username
with your actual username. This command allows your user systemd manager to continue operating even when your user is not logged into any active session.
-
-
Setup Your Systemd Service and Timer:
- Ensure your
.service
and.timer
files are correctly placed in~/.config/systemd/user/
. - Be sure to reload the user manager if you make any changes using
systemctl --user daemon-reload
.
- Ensure your
-
Start and Enable Your Timer:
-
Use
systemctl --user
to start and enable your timer:systemctl --user enable fastapi-cron.timer systemctl --user start fastapi-cron.timer
-
enable
ensures that the timer is automatically activated at boot time or when your systemd user manager starts. -
start
immediately begins the timer service.
-
-
Verify the Status:
-
Check the status of your timer and the associated service:
systemctl --user status fastapi-cron.timer systemctl --user status fastapi-cron.service
-
-
Test by Logging Out:
- After setting the above, you can test by logging out of your session and checking if the service continues to run. If properly configured with linger enabled, your timer should continue to operate.
By enabling lingering for your user, you ensure that your user-level systemd manager remains active, thus keeping your services and timers running independently of your current login session state. This setup is common for server environments or scenarios where services must run continuously irrespective of active user sessions.
Leave a Reply