How to reference OS Environment Variables in nginx.conf - nginx

In nginx.conf.
After set a variable by set $name value,
i can reference it like $name,
But when I export an OS Environment Variable
by env name_from_env,
like https://nginx.org/en/docs/ngx_core_module.html#env said,
and i am sure the name_from_env is valid which
defined form nginx's parent process.
But, my friends, how to reference it ?
$name_from_env or ${name_from_env} or
%name_from_env% didn't work what I've tried before.

nginx doesn't have the built-in ability to reference its environment variables in the configuration at present. The simplest solution however is the perl_set directive from ngx_http_perl_module, an extra module for nginx. The official nginx packaging builds the Perl module dynamically so it's a case of ensuring you install the extra nginx-module-perl package (or configure your custom build of nginx, if that's what you're doing).
Configuration looks like this:
# Make environment variable available
env NAME_FROM_ENV;
# Load dynamic module (if built with Perl as dynamic module; omit if static)
load_module modules/ngx_http_perl_module.so;
http {
server {
location / {
# Use Lua to get get and set the variable
perl_set $name_from_env 'sub { return $ENV{"NAME_FROM_ENV"}; }';
...
}
}
}
See also https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html for how to use Lua to achieve the same thing. Lua support requires a third party module and isn't shipped with nginx's default packages.

It should be $name_from_env, just like any other Nginx variable.
Note that env can only be used in the main part of your config, not http, server or location blocks.
I'm guessing that env isn't really what you need in any case. If you are trying to pass variables down to your application, you should use proxy_param or fastcgi_param (depending on how you are talking to your upstream):
fastcgi_param MYVAR foo;

Related

How can I pass Path parameters to lua code by nginx?

I want to create a Location in my Nginx with such route /resource/{{state}} though the {{state}} is a place holder for a variable that must pass to my Lua script and according to this variable I want to process some resources.
I cannot find any documentation or guideline for creating such a route in Nginx and passing path parameters to Lua. Are path parameters available in nginx and if the answer is yes how can I access them in mylua code?
Use the regex location syntax with the ngx.var.VARIABLE API:
location ~ ^/resource/(?<state>[^/]+)/?$ {
content_by_lua_block {
ngx.say(ngx.var.state)
}
}
Note: nginx uses the PCRE2 library for regex support. Check the documentation for the syntax.

Unable to use environment variables in Lua code

I have some Lua code, which I use in my openresty nginx.conf file. This Lua code contains such lines:
...
local secret = os.getenv("PATH")
assert(secret ~= nil, "Environment variable PATH not set")
...
Just for testing reasons I tried to check if PATH variable is set and for some reason the assert statement does not pass. I see in the console:
Environment variable PATH not set
However, when I run this
$ echo $PATH
I see, that this variable indeed has some value. So, what is wrong with that and how can I fix it?
You need to tell nginx to make environment variables available. From the docs for the env directive: "By default, nginx removes all environment variables inherited from its parent process except the TZ variable. This directive allows preserving some of the inherited variables, changing their values, or creating new environment variables."
So, in your case you'd need to specify env PATH; in nginx.conf.

extending mime types in a Chef deployed Nginx server

I'm looking to extend the mime types in my Nginx configuration.
I've learned that I could, in principle, either edit the mime.types file, or after including mime.types in the http block of the config you could follow include mime.types with a types = {...} to append more types a la this answer.
Since I'm setting up Nginx with Chef, I have a templated configuration in sites-enabled folder that's included into the Nginx config proper. I would prefer not to have to template the nginx config or mime.types file, so I'm hoping it's possible to get it in the sites-enabled config file.
In a similar spirit to the linked question above, could I include this in my sites-enabled file to get the same effect?
http {
types {
# here is additional types
}
}
My working theory is that if blocks work as described in the link above, adding such a block would not overwrite the http block in the Nginx config, but would extend it as if I had added the types directly to the http block in nginx.conf.
Is this a valid strategy? Or am I overlooking something easier?
Although not explicitly stated in the documentation, the nginx types directive appears to behave similarly to other directives with regard to inheritance.
The directive is inherited from the previous level if and only if there are no type directives defined on the current level.
The types directive may appear in the http, server or location block level.
To extend the mime types (rather than redefining them) to can add a types block with your additions in any file containing an http, server or location context.
But if you add a types block at the server or location level, you should also add another include mime.types statement at the same level, so as not to lose the system defaults.
In your sites-enabled files:
# (1)
server {
# (2)
location ... {
# (3)
}
}
If your sites-enabled file includes the server { ... } block definition, you might add a types block in position (1) which would augment the mime types already loaded by the main nginx.conf file.
However, if you added a types block in positions (2) or (3), you would also need to add an include statement to pull in the system types again:
server {
include mime.types;
types { ... }
...
}
The types directive is documented here.

The default CSS of Django admin section is not loading

Folks, the default CSS of my Django admin section is not loading (setup uses nginx reverse proxy + gunicorn, OS is the Debian-based Ubuntu).
The following is part of etc/nginx/sites-available/myproject:
location /static/admin {
alias /home/mhb11/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/admin/static/;
}
That, btw, points to the correct location of django admin's css files, and is written below location /static/ {} snippet (not shown here).
Note that I have tried the root directive instead of alias too, to no avail. Also note that this error pertains solely to django admin static files. The project related static files are working perfectly. Also note that my settings.py file includes 'django.contrib.staticfiles', in INSTALLED_APPS and STATIC_URL = '/static/'.
What am I missing? Please ask for more information in case it is needed.
It may not be significant, but for consistency, your location path and alias path should both end with a / or neither end with a /.
With your current configuration, the server is constructing path names with an embedded //, like /home/mhb11/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/admin/static//somefile.css.
Try:
location /static/admin/ {
alias /home/mhb11/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/admin/static/;
}

Nginx: Use different backend based on value of argument

We have a legacy application written in php which we are now migrating to java.
The Application being hige, we are trying to migrate features in part.
Keeping this scenario in mind, i need to split traffic between php-fpm backend and the java app based on the value of a query string argument
for eg
if $format="csv", use fast-cgi and process request using php
If $format="xml",connect to the java backend using the proxy_pass directive.
Unfortunately i am finding it difficult to do this on nginx.
I tried the following
if ($args_format ="csv")
include php;
if ($args_format ="xml")
include proxy;
here php and proxy are files containing the proxy_pass and fast-cgi related statements
Unfortunately this throws a syntax error
Then I create a map by using something like
map $args_output $provider {
default "proxy";
csv "php";
}
then did an
include $provider;
This also fails as nginx seems to load the includes at start time and not during execution of each call.
Any suggestions on how i can achieve this in an elegant way.
The variable name is $arg_format
http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_
You must use { } after if statement.
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
Try something like ...
if ($arg_format ="csv") {
include php;
}
if ($arg_format ="xml") {
include proxy;
}

Resources