This is interesting.
If I understood well this allows one to run isolated instances of nginx
listening on different IPs and also under different user accounts. Is that
correct?
Jérôme Loyet wrote:
You could then imagine many cases in which this option could be usefull.
You can do whatever you want Scope is only limited by your
imagination (almost)
Here is an exemple of what our compagny needs and how I’ll make it. I
just warn that this has not been tested.
- One box mutualized with several customers.
- All architectures are the same: NET → nginx → apache(with php)
- each customer has its own path and own conf file
- each customer runs with a different user/group
- each customer has an numerical ID (from 1)
- each customer has its own prefix (/data/www/customers/$ID)
- each customer has a frontend listening on *:(8000 + $ID)
- each customer has a backend listening on *:(9000 + $ID)
The idea is to have a template file for nginx.conf. We’ll use m4 in
our case. This template will be something like this:
user M4_NGINX_USER M4_NGINX_GROUP;
error_log logs/errors;
pid logs/nginx.pid;
events {
workers 1024;
}
http {
mime types are common for all users
include /usr/local/nginx/conf/mime.types
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header Set-Cookie;
proxy_temp_path temp/;
proxy_cache_path cache/ keys_zone=CACHE:10m;
proxy_cache CACHE;
proxy_cache_min_uses 1;
proxy_cache_use_stale error timeout invalid_header http_500 http_502
http_503 http_504;
proxy_cache_valid any M4_NGINX_DEFAULT_TIMEOUT;
server {
listen M4_NGINX_FRONTEND_PORT;
location / {
proxy pass http://M4_NGINX_BACKEND_ADDRESS:M4_NGINX_BACKEND_PORT;
}
location ~* \.(gif|jpg|jpeg)$ {
proxy pass http://M4_NGINX_BACKEND_ADDRESS:M4_NGINX_BACKEND_PORT;
proxy_cache_valid M4_NGINX_IMAGES_TYPE M4_NGINX_IMAGES_TIMEOUT;
}
You can add some macros to generate more locations dynamicaly
the power of m4:
}
}
So this template is generated from few parameters:
M4_CUSTOMER_ID → 1
M4_NGINX_PREFIX → /data/www/customers/client/M4_CUSTOMER_ID
M4_NGINX_USER → client_ M4_CUSTOMER_ID
M4_NGINX_GROUP → client_ M4_CUSTOMER_ID
M4_NGINX_DEFAULT_TIMEOUT → 1m
M4_NGINX_FRONTEND_PORT → eval(8000 + M4_CUSTOMER_ID)
M4_NGINX_BACKEND_ADDRESS → 127.0.0.1
M4_NGINX_BACKEND_PORT → eval(9000 + M4_CUSTOMER_ID)
M4_NGINX_IMAGES_TYPE → any
M4_NGINX_IMAGES_TIMEOUT → 1d
Via a backoffice interface, the customer can set by his own some
parameters like (default timeout, images_types or images_timeout). The
backend then generate a temporary nginx conf file and:
test the temporary conf file
if the test is not valid {
report error to the user so that he can correct his settings
} else {
backup the old nginx.conf file
replace the nginx.conf file with the temporary one
send HUP signal to nginx
}
At startup each nginx has been launched with something like:
for prefix in /data/www/customers/*; do
test -d $prefix || continue
if /path/to/nginx -t -p $prefix/; then
echo “[info] nginx for customer basename $prefix
correctly
launched”
else
echo “[ERROR] unable to launch nginx for customer basename $prefix
” >/dev/stderr
fi
done
in this case I could have specified all my path abolutely as I have a
macro processor which can do the job. But I have other boxes as this
one but without a customer back office access. Each conf is done
manually so with relative path no (or much less) mistakes are
possible. We’re using this feature with apache (-d serverroot) for a
long time and it helps us a lot.
Hope this helps
++ Jerome