Getting serious with nginx and passenger
As we are safety-conscious devops we don’t want our webservers to run as root.
Today we’re hosting a pretty standard rails/mysql app. As server we use our trusty nginx. To make it not too easy we combine it with passenger!
Too really get serious, we want to fire all this up with a upstart script.
Get the party started
To bring the startup into the form of a proper startup script, we wrote something pretty similar to this:
But it will run as root this way - A little further down the road, one might consider setuid www. But behold - It’s a trap!
Seemingly the correct way seems to be to use the user directive, like
user www # in the nginx.conf
to actually tell nginx under which user to run. The nginx master process will actually run as root, but the child processes handling the request will run as the unprivileged www user.
This has the additional benifit, that we can bind ports lower than 1024!
root 3908 0.0 0.0 654708 1180 ? Ss 19:10 0:00 nginx: master process /opt/nginx/sbin/nginx
www 3909 0.0 0.1 655240 2648 ? S 19:10 0:00 nginx: worker process
www 3910 0.0 0.0 654856 1696 ? S 19:10 0:00 nginx: cache manager process
Being patient with the passenger
The goal is in reach, but the passenger is not ready to board yet. Instead it gives us the error page, telling it’s missing the HOME environment variable.
Passenger just wants a litte attention for himself. In the nginx.conf we have to add the following lines:
passenger_default_user www;
passenger_default_group www;
So actually it’s just these three lines you need to get all up an running - and if you do not take all the detours trying to find out how to run services in general via upstart - it should be set up rather quickly.