This snippet preserves a 2009 use case: running a lighttpd binary compiled from source on a Debian system that still uses the SysV init compatibility layer. Current Debian installations should normally use the lighttpd Debian package and its systemd service. Do not replace a package-managed service with this script.
For a local source build, configure lighttpd to write the PID file expected by the script:
server.pid-file = "/run/lighttpd.pid" The PID file and its parent directory must not be writable by unprivileged users. The script combines that PID with the absolute executable path so start-stop-daemon does not signal an unrelated process after a stale PID file.
SysV Init Script
Save this as /etc/init.d/lighttpd only when no package-owned script or unit already manages the service:
#!/bin/sh
### BEGIN INIT INFO
# Provides: lighttpd
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start the local lighttpd web server
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="lighttpd web server"
NAME=lighttpd
DAEMON=/usr/local/sbin/lighttpd
CONFIG=/etc/lighttpd/lighttpd.conf
PIDFILE=/run/lighttpd.pid
. /lib/lsb/init-functions
[ -x "$DAEMON" ] || exit 5
[ -r "$CONFIG" ] || exit 6
check_config()
{
"$DAEMON" -tt -f "$CONFIG"
}
do_start()
{
check_config || return 2
start-stop-daemon --start --quiet --oknodo \
--pidfile "$PIDFILE" --exec "$DAEMON" -- \
-f "$CONFIG"
}
do_stop()
{
start-stop-daemon --stop --quiet --oknodo \
--retry=TERM/30/KILL/5 \
--pidfile "$PIDFILE" --exec "$DAEMON"
result=$?
[ "$result" -eq 0 ] && rm -f "$PIDFILE"
return "$result"
}
do_reload()
{
check_config || return 2
start-stop-daemon --stop --quiet --signal HUP \
--pidfile "$PIDFILE" --exec "$DAEMON"
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
result=$?
log_end_msg "$result"
exit "$result"
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
result=$?
log_end_msg "$result"
exit "$result"
;;
restart)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
result=$?
[ "$result" -eq 0 ] && do_start
result=$?
log_end_msg "$result"
exit "$result"
;;
reload|force-reload)
log_daemon_msg "Reloading $DESC" "$NAME"
do_reload
result=$?
log_end_msg "$result"
exit "$result"
;;
status)
status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME"
exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|reload|force-reload|status}" >&2
exit 3
;;
esac lighttpd -tt validates the complete configuration before start or reload. Stop waits for an orderly shutdown and escalates only if the daemon does not exit within the timeout. Reload uses SIGHUP, allowing lighttpd to reopen logs and reload without the old SIGINT-then-start race.
Install and Test
sudo install -m 0755 rc.lighttpd.debian /etc/init.d/lighttpd
sudo update-rc.d lighttpd defaults
sudo service lighttpd start
sudo service lighttpd status If the configuration check fails, run the command directly to see the diagnostic:
sudo /usr/local/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf Rotate Access Logs
Log rotation belongs in logrotate, not in a custom init action. Save the following as /etc/logrotate.d/lighttpd-local and adjust the path to match the configured access log:
/var/log/lighttpd/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
invoke-rc.d lighttpd reload >/dev/null 2>&1 || true
endscript
} The original script moved the log into /tmp using date +%D. That format contains slashes, repeated runs can collide, and a public temporary directory is the wrong place for service logs. Delegating retention, compression, permissions, and naming to logrotate avoids those defects.
References
- [DebianSSD]Debian Manpages. start-stop-daemon(8).
- [DebianRC]Debian Manpages. update-rc.d(8).
- [lighttpd]Debian Manpages. lighttpd(8).