# Can't run nginx automatically as user



## Rexypoo (Nov 24, 2017)

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:

```
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


```
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.


----------



## gfx (Nov 25, 2017)

Have you tried adding the line `pid  /path/to/nginx.pid` to /etc/rc.conf.d/nginx ?


----------



## SirDice (Nov 27, 2017)

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

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


----------



## Rexypoo (Nov 30, 2017)

gfx said:


> 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...



SirDice said:


> `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:

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)

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...


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"`
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:

```
#!/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:

```
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.


----------



## drhowarddrfine (Nov 30, 2017)

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.


----------



## SirDice (Nov 30, 2017)

Oh, don't set pidfile in nginx.conf.


----------



## Rexypoo (Dec 1, 2017)

drhowarddrfine said:


> 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.



SirDice said:


> 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.


----------

