When working with process managers like Supervisor, we often encounter services that stubbornly insist on running as daemons. Zabbix Server is a classic example - it's designed to background itself immediately after launch, which directly conflicts with Supervisor's requirements for foreground processes.
Supervisor maintains control by monitoring the STDOUT/STDERR streams and process state. When a process daemonizes:
- The original process exits (breaking Supervisor's monitoring)
- A new background process detaches (becoming an unmanaged orphan)
- Supervisor can't track the actual service state
Here are proven approaches to handle this situation:
1. Using the 'nodaemon' Wrapper Technique
Create a simple bash wrapper that prevents daemonization:
#!/bin/bash # Prevent Zabbix from daemonizing exec /usr/sbin/zabbix_server --foreground
2. PID File Monitoring Approach
Configure Supervisor to watch the daemon's PID file:
[program:zabbix] command=/etc/init.d/zabbix-server start pidfile=/var/run/zabbix/zabbix_server.pid autorestart=true
3. The 'timeout' Trick for Stubborn Daemons
Some services briefly run in foreground before daemonizing. Catch this window:
[program:problematic_daemon] command=timeout --foreground 300 /usr/sbin/daemon_command autorestart=true
For modern systems, consider delegating to systemd:
[program:systemd_proxy] command=/bin/bash -c "systemctl start zabbix-server && tail -f /dev/null" stopasgroup=true killasgroup=true
After implementation, verify with:
supervisorctl status ps aux | grep zabbix
Check logs in /var/log/supervisor/ for any process management issues.
When working with supervisord
, one common issue arises when trying to manage processes that inherently daemonize themselves (like Zabbix Server) and don't offer a foreground mode option. Supervisor expects processes to run in the foreground, making this a tricky situation.
Supervisor requires processes to:
- Run in the foreground (not fork into the background)
- Not daemonize themselves
- Output to stdout/stderr (for logging purposes)
Here are several approaches to handle this:
1. Using a Wrapper Script
Create a bash script that prevents the daemon from forking:
#!/bin/bash
exec /path/to/your/daemon --option1 --option2 --no-daemon
Then configure supervisor to run this wrapper:
[program:zabbix_server]
command=/path/to/wrapper_script.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/zabbix_server.err.log
stdout_logfile=/var/log/zabbix_server.out.log
2. Leveraging PID Files
If the daemon creates a PID file, you can use this in your supervisor config:
[program:zabbix_server]
command=/path/to/daemon --pidfile /var/run/zabbix.pid
pidfile=/var/run/zabbix.pid
autostart=true
autorestart=true
3. Using the 'start-stop-daemon' Approach
Some systems have start-stop-daemon
which can help:
[program:zabbix_server]
command=start-stop-daemon --start --exec /path/to/daemon -- --options
autostart=true
autorestart=true
For particularly stubborn daemons:
[program:zabbix_server]
command=nohup /path/to/daemon --options > /dev/null 2>&1 & echo $! > /var/run/daemon.pid
pidfile=/var/run/daemon.pid
autostart=true
autorestart=true
- Always test configurations thoroughly
- Monitor resource usage when forcing foreground operation
- Check if your application has hidden foreground flags (like --fg or --nodaemon)
- Consider whether the daemon is designed to work with process managers
If you're having issues, try:
supervisorctl tail -f program_name
Or check the main supervisor log:
tail -f /var/log/supervisor/supervisord.log