When your Linux distribution upgrades to systemd, those trusty old init scripts in /etc/init.d/
suddenly stop working. Here's how to get them running again without diving into full systemd unit file conversion.
# Quick verification step
ls -l /etc/init.d/solr
The error update-rc.d: error: solr Default-Start contains no runlevels
indicates your script lacks proper LSB headers. Systemd strictly enforces these metadata requirements that older init systems often ignored.
Add this header to your existing script (before any executable code):
### BEGIN INIT INFO
# Provides: solr
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Solr search server
# Description: Starts the Solr search platform
### END INIT INFO
For a truly minimal solution, systemd provides a compatibility layer:
# Create a basic service file
echo "[Unit]
Description=Solr search server (legacy init compat)
[Service]
Type=forking
ExecStart=/etc/init.d/solr start
ExecStop=/etc/init.d/solr stop
ExecReload=/etc/init.d/solr restart
[Install]
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/solr.service
# Reload and start
sudo systemctl daemon-reload
sudo systemctl start solr
If you encounter PID file issues or environment variables not being passed:
# Example of environment variable handling
Environment="INSTALL_ROOT=/opt/solr"
WorkingDirectory=/usr/local/solr/example
For long-term maintenance, here's how the complete systemd unit would look:
[Unit]
Description=Apache Solr
After=syslog.target network.target
[Service]
Type=simple
User=solr
Environment="INSTALL_ROOT=/opt/solr"
WorkingDirectory=/usr/local/solr/example
ExecStart=/usr/bin/java -jar -server start.jar -DINSTALL_ROOT=$INSTALL_ROOT
Restart=on-failure
LimitNOFILE=10000
[Install]
WantedBy=multi-user.target
For those who need a quick solution without diving into systemd unit file creation, you can leverage systemd's built-in compatibility layer. Here's how to make your old init script work immediately:
# Place your init script in /etc/init.d/
sudo cp solr /etc/init.d/
sudo chmod +x /etc/init.d/solr
# Use systemd's sysv-generator
sudo systemctl daemon-reload
# Now you can use either command:
sudo systemctl start solr
# OR
sudo service solr start
The error about missing LSB tags indicates your init script needs minimal metadata. Add this header right after the shebang (#!/bin/sh):
### BEGIN INIT INFO
# Provides: solr
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Apache Solr search server
# Description: Starts the Apache Solr search service
### END INIT INFO
While keeping the init script format, we can add some optimizations:
#!/bin/sh
### BEGIN INIT INFO
# (Include the LSB header from above)
### END INIT INFO
# Add these for better systemd integration:
PIDFILE=/var/run/solr.pid
LOG_FILE=/var/log/solr/solr.log
JAVA_OPTS="-Xms512m -Xmx512m -DINSTALL_ROOT=${INSTALL_ROOT}"
# Modify the start function:
start() {
if [ -f $PIDFILE ]; then
echo "Solr is already running (PID $(cat $PIDFILE))"
return 1
fi
echo $$ > $PIDFILE
exec java $JAVA_OPTS -jar start.jar > $LOG_FILE 2>&1 &
# ... rest of original start function
}
For better process management, consider this hybrid approach using systemd's Type=forking:
# Create /etc/systemd/system/solr.service with:
[Unit]
Description=Apache Solr
After=network.target
[Service]
Type=forking
ExecStart=/etc/init.d/solr start
ExecStop=/etc/init.d/solr stop
ExecReload=/etc/init.d/solr restart
PIDFile=/var/run/solr.pid
[Install]
WantedBy=multi-user.target
If you encounter permission problems, ensure:
- The script is executable (chmod +x)
- PID and log directories exist and are writable
- Environment variables (like INSTALL_ROOT) are properly set in /etc/default/solr
Verify operation with:
sudo systemctl status solr
journalctl -u solr -n 50 --no-pager