In this lesson, you will learn how to use systemd-notify to programmatically signal to the system manager that your custom service has finished its initialization and is ready to accept requests.
The Problem with Simple "Start" Scripts
When you define a service as Type=simple, systemd assumes the service is ready the moment the process starts. However, real-world applications often perform complex tasks—like opening database connections, loading heavy configuration files, or initializing network sockets—before they can actually do their job. If another service depends on your application being fully "live," it might crash because it started too early.
Using Type=notify
To solve this, we use Type=notify. In this mode, systemd waits for a specific message from your process before marking the service as "started." Your application uses the sd_notify protocol (often via the systemd-notify command or a language-specific library) to send a signal over a Unix domain socket defined in the NOTIFY_SOCKET environment variable.
Concrete Implementation
If you are writing a simple shell script or a background daemon, you can signal readiness like this:
#!/bin/bash
# Perform heavy initialization here...
echo "Loading database..."
sleep 5
# Signal to systemd that we are ready
systemd-notify --ready
# Now, keep the service running
exec ./my_app_binary
In your unit file, you must ensure you have set the correct type:
[Service]
Type=notify
ExecStart=/usr/local/bin/my-script.sh
When systemd-notify --ready is executed, systemd receives the message through the socket, transitions the unit state from "activating" to "active," and proceeds to start any other services that depend on yours.
If you don't use this protocol, systemd is effectively "flying blind," guessing when your service is ready based only on whether the process successfully spawned. By integrating notify protocols, you create a synchronous, reliable handshake between your code and the init system.
Key Takeaway: Use Type=notify and the systemd-notify command to provide explicit feedback to systemd, ensuring that dependent services only launch after your application is fully initialized and ready to work.