9

Background:

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04 LTS"

I've built nginx, and I'd like to use upstart to start it:

nginx upstart script from the site:

description "nginx http daemon"

start on runlevel 2

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6

console owner

exec /usr/sbin/nginx -c /etc/nginx/nginx.conf  -g "daemon off;"

respawn

I get "unknown job" when i try to use initctl to run it, which I just learned apparently means there is an error, ( what's wrong with "Error" to describe errors?)

Can someone point me in the right direction ? I've read the documentation , as it is, and it seems kind of sparse for a SysV init replacement... but whatever just need to add this job to the list, run it, and get on with what's left of my life... Any tips?

EDIT: initctl version init (upstart 0.6.5)

2
  • 1
    One comment about 'unknown job' vs 'Error'. You are just looking in the wrong place. Initctl doesn't read the config file, it just asks Upstart to load a known job – and upstart doesn't know this job when you issue initctl command. Error occurred earlier when Upstart tried to read the job file. There should be an error message in the system log (/var/log/syslog, /var/log/messages or wherever your system stores these logs) May 22, 2010 at 7:17
  • By the way, it turns out that in /sbin there are start and stop commands for upstart jobs. They worked for me. Now, they link back to initctl, so I'm unsure why they work, but they do.
    – chiggsy
    Oct 18, 2010 at 5:31

7 Answers 7

3

You cannot have multiple stop on directives in an upstart job description for Upstart >= 0.5.

And console owner is probably not what you want (this makes nginx the owner of the system console).

Try:

description "nginx http daemon"
start on runlevel 2
stop on runlevel [016]
console output
exec /usr/sbin/nginx -c /etc/nginx/nginx.conf  -g "daemon off;"
respawn
4
  • Still unknown job, alas. Where are you getting this info from? Man? Info? online? Where is 0.6.5 documented?
    – chiggsy
    May 20, 2010 at 19:11
  • kinda worked.. thnx
    – chiggsy
    May 21, 2010 at 0:18
  • Yes, it is hard to find the current Upstart documentation, at least on the web. But the manual page is quite good. Try: man 5 init May 22, 2010 at 7:18
  • 1
    This is not the right way to run nginx on production servers. The daemon off option is for development only.
    – PhilT
    May 23, 2012 at 6:50
16

I've ended up here more than once so I thought I'd provide an updated answer based on my own experience after using the answers here. Thanks especially to @danorton and @orj for their answers.

This script has been tested on Upstart 1.5 running on Ubuntu 12.04 with Nginx 1.0.11 and Passenger 3.0.11. If you're not using Passenger you may need to play around with the post-stop line. Refer to the Upstart cookbook.

In an empty /etc/init/nginx.conf add the following lines (You can remove the comments if you like):

description "nginx http daemon"

start on (filesystem and net-device-up IFACE=lo)
stop on runlevel [!2345]

env DAEMON=/usr/local/nginx/sbin/nginx
env PIDFILE=/var/run/nginx.pid

# Needed to allow Nginx to start, however, the wrong PID will be tracked
expect fork

# Test the nginx configuration (Upstart will not proceed if this fails)
pre-start exec $DAEMON -t

# Ensure nginx is shutdown gracefully
# Upstart will be tracking the wrong PID so the following is needed to stop nginx
post-stop exec start-stop-daemon --stop --pidfile $PIDFILE --name nginx --exec $DAEMON --signal QUIT

# Start Nginx
exec $DAEMON

I've taken the Upstart script from the Nginx Wiki and tweaked it as a number of lines are not needed, cause confusion or do not work.

You may need to alter env DAEMON and env PID lines depending on where you have installed nginx and are writing the PID. The PID can be configured in nginx.

I tried all forms of expect. Only expect fork seems to work. With Passenger nginx creates 61 forks. Upstart requires 0, 1 or 2. As others have hinted, Upstart will be tracking the wrong PID. I've also removed respawn as it does nothing probably because of the same reason. Some additional pre/post-start script may be able to fix that by grabbing the real PID. I, however, use monit to handle restarts so do not need it.

Do not use daemon off. This is for development only. See http://wiki.nginx.org/CoreModule#daemon

References:

1
  • 1
    I would think that you would want to run using daemon off; so that upstart watches the correct process/PID without the need for the expect fork or post-stop directives. The wiki section describing the daemon option also states "You can use daemon off safely in production mode with runit/daemontools, however you can't do a graceful upgrade.", which I assume is referring to the upgrading to a new binary on the fly feature.
    – Gary
    Aug 8, 2012 at 23:13
3

You can’t. At least not properly, anyway.

Nginx does not spawn its daemon in one of the two ways that upstart requires, either via “expect fork” or “expect daemon”, so upstart is unable to track the master nginx process. There are some hacks, but they have their own problems.

If you’re okay with the fact that upstart can’t keep track of the master process and kill it on shutdown, this will work:

start on local-filesystems \
  and (net-device-added INTERFACE=lo) \
  and (runlevel [12345])
stop on runlevel [06]

env DAEMON=/usr/sbin/nginx

respawn
respawn limit 10 5

expect daemon

pre-start script
  $DAEMON -t
end script

$DAEMON
1
  • expect daemon causes upstart to hang for me (Ubuntu 12.04, Upstart 1.5, Nginx ). expect fork worked although as @danorton hints, Upstart will be tracking the wrong PID. I also couldn't get respawn to work (See my full answer).
    – PhilT
    May 23, 2012 at 7:16
2

There is an Upstart config file example in the NGINX Wiki.

You may need to adjust the path to the nginx binary in the config file.

This config file is working fine for me with Ubuntu 10.04 and nginx 1.0.5.

I also installed an nginx symlink in /etc/init.d pointing at /lib/init/upstart-job so I could use the standard service command to start and stop nginx.

Note: If you install Phusion Passenger with NGINX you might need to add the following stanza to the Upstart config script:

env PID=/opt/nginx/logs/nginx.pid
post-stop script
    start-stop-daemon --stop --pidfile $PID --name nginx --exec $DAEMON --signal TERM
end script

I found this necessary on my Ubuntu config. Otherwise when I issued initctl stop nginx or service nginx stop nginx didn't actually stop. I also noticed that Upstart thought the nginx process had a PID that was actually the PID of one of the Passenger processes. So clearly NGINX/Passenger is confusing Upstart a little.

2
  • Thanks for that script for passenger. This seemed to stop the processes but I got stop: Job failed while stopping while doing so. Did you see this?
    – PhilT
    Nov 8, 2011 at 16:22
  • I have the same problem as @PhilT, any word on this? Nov 19, 2011 at 15:28
0

I use:

description "Nginx HTTP Server"

start on filesystem
stop on runlevel [!2345]

respawn

exec /opt/nginx/sbin/nginx -g "daemon off;"

The stop on runlevel [!...] seems to be more standard. It's what the stock ssh/samba scripts do. You should also add the respawn bit so it restarts if it dies. I'm also not sure why you want console output that simply sends console output to stdout. The default behavior is to simply send console output to the logger.

You can see all the stanza docs on the Upstart wiki

3
  • Unfortunately, that wiki seems to imply that it is only version 0.5. It is very strange to me that such an important change is documented in that fashion.
    – chiggsy
    Sep 26, 2010 at 1:47
  • What is only version 0.5? Oct 13, 2010 at 4:37
  • The wiki in general. The man pages are ok, but they sure are not 'info' pages, which usually are much more detailed.
    – chiggsy
    Oct 18, 2010 at 5:09
0
description "nginx"

start on (net-device-up and local-filesystems)
stop on runlevel [016]

expect fork
respawn
exec /usr/sbin/nginx

See http://geeknme.wordpress.com/2009/10/15/getting-started-with-upstart-in-ubuntu for more.

0

Oddly none of the answers here actually works fully as they leave upstart in a stop/killed state which prevents another start working. This means that restart nginx fails.

The bug with upstart is well documented at https://bugs.launchpad.net/upstart/+bug/406397 and I'm astonished that the author of upstart doesn't seem to care enough to fix it. The only solution I've seen that works is the following (stolen from the same bug report):

# nginx - Nginx Web Server
#

description "Nginx Web Server"

start on (local-filesystems and
    (net-device-up IFACE=eth1 or net-device-up IFACE=eth0) )
stop on runlevel [!2345]

env DAEMON=/usr/local/sbin/nginx
env PID=/var/run/nginx.pid

respawn

pre-start script
$DAEMON -s stop 2> /dev/null || true
$DAEMON -t > /dev/null
$DAEMON
end script

script
sleepWhileAppIsUp(){
    while pidof $1 >/dev/null; do
    sleep 1
    done
}
sleepWhileAppIsUp $DAEMON
end script

post-stop script
if pidof > /dev/null $DAEMON;
then
    $DAEMON -s stop
fi
end script

The advantage of writing it like this is that even the respawn works. The disadvantage is that it's ugly and a nasty hack.

2
  • Upstart is pretty much a dead product; Ubuntu is very nearly the last distribution using it. All others are switching away or have already switched. Jun 8, 2013 at 17:08
  • Even Ubuntu itself has switched to systemd in newer versions. But some of us sysadmins are still stuck with 14.04 because LTS. Jan 5, 2016 at 13:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .