Debugging Why “sudo service nginx start” Fails While “sudo nginx” Works: A Deep Dive into Init Script Issues


2 views

When dealing with service management in Linux, the behavior difference between direct execution (sudo nginx) and init script execution (sudo service nginx start) often points to environmental or permission issues. Here's what we're observing:

# Successful execution
sudo nginx

# Failing commands
sudo service nginx start
sudo service nginx restart

# Working command
sudo service nginx stop

The strace output reveals a fundamental difference in how the PID file is being handled:

# Working server reads just the PID file path
read(3, "/run/nginx.pid\n", 128) = 15

# Failing server reads additional content
read(3, "/run/nginx.pid\nserver_name\n", 128) = 27

Based on the symptoms, here are the most likely culprits:

  • Corrupted or malformed init script (despite appearing identical)
  • Environment variables leaking into the service context
  • Race conditions during service startup
  • PID file handling issues

1. Validate Init Script Integrity

First, verify the actual content being executed:

# Check which script is actually being run
update-rc.d -f nginx defaults
ls -la /etc/init.d/nginx
sha1sum /etc/init.d/nginx

2. Examine Environment Variables

The strace output suggests environment contamination:

# Compare environments
sudo env > /tmp/service_env.txt
sudo -i env > /tmp/interactive_env.txt
diff /tmp/service_env.txt /tmp/interactive_env.txt

3. Debug the Init Script Directly

Add debug statements to the init script temporarily:

# Edit /etc/init.d/nginx
set -x  # Add at the beginning of the script
exec 2>&1 | tee /var/log/nginx-init-debug.log

Solution 1: PID File Handling Fix

Modify the init script's PID file handling:

# In /etc/init.d/nginx, replace:
pidfile=${PIDFILE-/run/nginx.pid}

# With:
pidfile=$(cat ${PIDFILE-/run/nginx.pid} | head -n1)

Solution 2: Clean Environment Execution

Force a clean environment when starting:

# Create a wrapper script
sudo sh -c 'env -i /etc/init.d/nginx start'

Solution 3: Systemd Alternative

If available, use systemd directly:

sudo systemctl start nginx
journalctl -u nginx -xe  # For detailed logs
  • Always validate init scripts after updates
  • Implement proper logging in init scripts
  • Consider migrating to systemd unit files if possible
  • Use configuration management tools to maintain consistency

When managing Ubuntu servers, encountering discrepancies between sudo service nginx start and direct sudo nginx execution is more common than you'd expect. Let's dissect this specific case where the service command fails silently while the direct command succeeds.

First, verify all standard configuration points:

# Configuration test
sudo nginx -t
sudo service nginx configtest

# Permission check
ls -la /etc/nginx/nginx.conf
ls -la /var/log/nginx/

# Service script inspection
diff /etc/init.d/nginx working-server:/etc/init.d/nginx

The strace output reveals a critical difference in PID file handling. The failing system attempts to read both /run/nginx.pid and some unexpected server_name data, suggesting:

  • Corrupted PID file contents
  • Improper service script variable parsing
  • Environment variable contamination

Ubuntu's init system expects specific PID file behavior. Try this emergency repair sequence:

# Force-clean any existing PID
sudo rm -f /run/nginx.pid
sudo rm -f /var/run/nginx.pid

# Manual start test
sudo nginx -c /etc/nginx/nginx.conf

# Then attempt service control
sudo service nginx restart

If the issue persists, examine the init script's PID handling. Add debug output temporarily:

# Edit /etc/init.d/nginx
find the start() function and add:
echo "Debug - PIDPATH: $PIDPATH" >&2
echo "Debug - Contents: $(cat $PIDPATH)" >&2

For production systems, consider these reliable alternatives:

# Systemd (Ubuntu 15.04+)
sudo systemctl enable nginx
sudo systemctl start nginx

# Upstart fallback
sudo start nginx

Verify all paths match your distribution's standards:

grep -r '/run/nginx.pid' /etc/nginx/
grep -r 'pid ' /etc/nginx/
grep -r 'user ' /etc/nginx/