In this article, we will see how to create a Bash script to monitor a Node.js application and restart the associated system service only when the application files have been modified. We will use inotifywait
from the inotify-tools
package to observe file changes and systemctl
to restart the service.
Before starting, make sure you have inotify-tools
installed and that you are managing your Node.js application with systemd.
sudo apt-get install inotify-tools
Make sure that your Node.js application is managed by systemd
and that you have a service file, such as myapp.service
.
Then create a file called monitor.sh
and make it executable:
touch monitor.sh
chmod +x monitor.sh
Open monitor.sh
with your favorite text editor and enter the following content:
#!/bin/bash
# Directory to monitor
MONITOR_DIR="/path/to/your/nodejs/app"
# Service name
SERVICE_NAME="myapp.service"
# Log file for the script
LOG_FILE="/var/log/monitor.log"
# Function to log messages
log_message() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
log_message "Starting file monitoring for $MONITOR_DIR"
# Function to restart the service
restart_service() {
log_message "Changes detected in $MONITOR_DIR. Restarting $SERVICE_NAME."
systemctl restart $SERVICE_NAME
if [ $? -eq 0 ]; then
log_message "$SERVICE_NAME restarted successfully."
else
log_message "Error restarting $SERVICE_NAME."
fi
}
# Handling SIGINT and SIGTERM signals to clean up before exiting
trap 'log_message "Stopping monitoring script."; exit 0' SIGINT SIGTERM
# Monitor directory for changes
inotifywait -m -r -e modify,attrib,close_write,move,create,delete "$MONITOR_DIR" --format '%w%f' |
while read FILE; do
log_message "File modified: $FILE"
restart_service
done
Script explanation:
Variables:
MONITOR_DIR
: The directory of your Node.js application.SERVICE_NAME
: The name of the systemd service that runs your application.LOG_FILE
: A file to log script messages.
Functions:
log_message
: Logs timestamped messages toLOG_FILE
.restart_service
: Logs a message, restarts the service, and logs whether the restart was successful.
Handling Signals:
- The script handles the
SIGINT
andSIGTERM
signals to ensure it logs a message when it is stopped.
- The script handles the
inotifywait:
inotifywait
monitors the directory recursively (-r
) for specific events: modification, attribute change, closing write, move, creation, and deletion (-e modify,attrib,close_write,move,create,delete
).- The
--format '%w%f'
option outputs the full path of the modified file. - The output of
inotifywait
is read line by line. For each line, the script logs the change and restarts the service.
You can run the script directly in the background:
./monitor.sh &
You can create a systemd service file to manage the monitoring script. Create a file called monitor.service
and insert the following content:
[Unit]
Description=File Change Monitoring for Node.js Apps
[Service]
ExecStart=/path/to/monitor.sh
Restart=always
[Install]
WantedBy=multi-user.target
Enable and start the monitoring service:
sudo systemctl enable monitor.service
sudo systemctl start monitor.service
Conclusion
By following these steps, you can create a Bash script that monitors your Node.js application files and automatically restarts the associated service when changes are detected. This is useful for development and production environments, where changes need to be applied automatically without manual intervention.