Can't run nginx automatically as user

I have an nginx server configured to run the master service as a non-root user and it runs fine when I manually invoke it by running nginx -c /path/to/nginx.conf as the user 'nginx' but it doesn't work from my rc.conf script.

I've tried to automate startup by writing it into an rc.conf script saved to /etc/rc.conf.d/nginx with the following lines:
Code:
nginx_user="nginx"
nginx_enable="YES"
nginx_flags="-c /path/to/nginx.conf"

but when I run service nginx start I get the error nginx: [emerg] open() "/path/to/nginx.pid" failed (13: Permission denied)

when I run ls -al /path/to/ I can see that the folder is owned by nginx:nginx but the pid file is owned by root:nginx

Code:
drwxr-xr-x  2 nginx  nginx      7 Nov 23 22:29 .
drwxr-xr-x  6 nginx  nginx     18 Nov 21 22:11 ..
-rw-r--r--  1 nginx  nginx   1534 Nov 23 19:49 nginx.conf
-rw-r--r--  1 root   nginx      0 Nov 23 22:29 nginx.pid

If I chown nginx:nginx /path/to/nginx.pid then the next time I run service nginx start the server starts up correctly, but the pid file is removed at shutdown so on restart it won't start automatically.

Is there a way in the rc.conf file to force ownership of the pid file?
Is there something else I should be changing to make this work?



Thanks in advance for anyone who can shed some light on how the rc scripts work here.


Other details:
I've tried echo nginx_pid_prefix=\"/path/to\" >> /etc/rc.conf.d/nginx but that doesn't seem to affect anything.
When I invoke nginx -c /path/to/nginx.conf as ther user 'nginx' the pid is owned by nginx:nginx with permissions set to 644.
 
mkdir /var/run/nginx
chown nginx:nginx /var/run/nginx

And set nginx to use /var/run/nginx/nginx.pid or something like it.
 
Have you tried adding the line pid /path/to/nginx.pid to /etc/rc.conf.d/nginx ?
I'm not seeing that this does anything. I'm not certain /usr/local/etc/rc.d/nginx actually allows you to specifically set the pidfile which seems like an oversight...

mkdir /var/run/nginx
chown nginx:nginx /var/run/nginx

And set nginx to use /var/run/nginx/nginx.pid or something like it.

The same problem, the pid is created under root:nginx with 644 permissions which prevents user nginx from using it.


I took some time to learn about the rc subsystem and I've determined where the error is happening.

/usr/local/etc/rc.d/nginx seems to invoke eval ${command} ${nginx_flags} -t for all types of startup.
( ${command} will be /usr/local/sbin/nginx in this case)
This section of the script is run as root despite the nginx_user="nginx" setting.

Oddly on normal exit an nginx server will destroy the /path/to/nginx.pid, but completion of the command nginx -t leaves an empty pid file behind. Because this empty pid file is owned by root when run_rc_command "$1" is invoked at the end of the script the nginx_user doesn't have permission to write the pid file.

This has pointed me to a few things that may or may not be bugs.

In /usr/local/etc/rc.d/nginx:
  1. I haven't found any way to enforce a pid file from /etc/rc.conf.d/nginx which means service nginx stop fails every time (be aware that nginx_pid_prefix is ignored if nginx_profiles is not set)
  2. Invoking ${command} ${nginx_flags} -t will always cause the service to fail if the rc.conf option nginx_user is set to anything other than "root"
More likely it seems number 2 above is a bug in nginx: running nginx -t should probably destroy the pidfile at exit.


That being said I've found what should be a few workarounds...

  1. Add mypid=/path/to/nginx.pid; touch $mypid; chown $nginx_user $mypid; to /usr/local/etc/rc.d/nginx just before the final command run_rc_command "$1"
  2. In /usr/local/etc/rc.d/nginx modify how the configuration check is run by changing eval ${command} ${nginx_flags} -t to eval su -m ${nginx_user:-root} -c \"${command} ${nginx_flags} -t\"
Neither of these is ideal because I want to be able to "set and forget" my nginx server configuration for jails, which means I'm not particularly interested in editing /usr/local/etc/rc.d/nginx after installing the port, so I've opted for a 3rd option which is to add nginx_program="/path/to/nginx_user_script.sh" to /etc/rc.conf.d/nginx.

The file /path/to/nginx_user_script.sh contains the following code:
Code:
#!/usr/bin/env sh
pidfile=/path/to/nginx.pid
touch $pidfile
chmod g+w $pidfile 2> /dev/null

/usr/local/sbin/nginx $@
The permissions for /path/to/nginx_user_script.sh are set to 755

When this script is run for the configuration check the root user changes permissions to allow users in the group specified by nginx.conf to write and/or delete the pid file. On the second run chmod fails (which is why I redirect stderr to /dev/null) and doesn't actually modify anything.

For reference the first directive in my nginx.conf is:
Code:
user nginx nginx;
which I think is why the pid has group "nginx". The second "nginx" in that line is supposed to set the group for worker threads.
 
www/nginx is designed to start up and run as root in order to access certain files needed to access the network and other things. I don't recall all the details but it is posted somewhere, probably the nginx documentation.
 
www/nginx is designed to start up and run as root in order to access certain files needed to access the network and other things. I don't recall all the details but it is posted somewhere, probably the nginx documentation.
Running nginx as root allows the master process to listen on port 80 (ports less than 1024 can only be used by root). I have already configured my server to work as non-root by setting the listen port to 8080 and configuring logs, temp files, and the pid to user-owned files/locations.

My server configuration works fine from the terminal but some combination of the way the pid file is handled and the configuration of the rc script breaks autostart.

Oh, don't set pidfile in nginx.conf.
I don't understand this suggestion. Can you elaborate?
Configuring the pidfile with nginx -g "pid /path/to/nginx.pid;" causes the same failure mode.

The problem seems to mostly relate to the fact that the command nginx -t doesn't destroy the pid file at exit, which seems like unintended behavior.
 
Back
Top