Nginx 1.14 can't access System Environment Variables - nginx

I have spend past 2 days trying to figure out how to get a System Environment Variable to get passed into Nginx.
I have declared the Environment Variable in /etc/nginx.conf with env FOO.
I have tried perl_set and set_by_lua.
But non works.
I am running this on a Ubuntu "Bionic" 18.04 machine.
Any idea?
Edit:
The issue is, Nginx strips all the environment variables, so they are not available within the web server process. Following some Nginx tutorials, set_by_perl or set_by_lua are the ways recommended for getting System Environment Variables into the web server process, which doesn't seem to work in my case.
Edit: Following is the tutorial I followed: https://web.archive.org/web/20170712003702/https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html

You can't set an environment variable from within nginx.conf. It will be ignored, which is what you've seen.
There are several places you can set the environment variables, I'll show the example for the file where the env vars will be availbale to all user logins and to NGINX.
$sudo nano /etc/environment
Add your defs to the end of the file; Leave everything that is there, there. Just append your new defs. Do this exactly, no extra spaces at the end of lines, no extra lines at the end of the file. Use double quotes. No comments. Very exact.
export COMPILERKEY = "jk8894085349058jjggl"
export FOO="ThisIsFooValue"
export FOO2="ThisIsFooValue2"
Save the file
Reboot server
To show all env vars that are defined
$env
Once defined, then you can access env vars through defined means. Access methods for the environment variables is a question which I think you're not asking about yet. I hope this helps.

Related

How can I use the Container's ENV on DATABASE_URL Symfony

I have the following environment on my php container like so:
DATABASE_URL:mysql://root:${MYSQL_ROOT_PASSWORD}#db:3306/${MYSQL_DATABASE}
I tried to echo it inside my container, and do a db migration. All is good. Now I used it on my .env file on symfony like so:
DATABASE_URL=${DATABASE_URL}
When i tried to login, the app says:
Authentication request could not be processed due to a system problem.
When i try to manually put everything on .env DATABASE_URL all is good.
I suspect that when I tried to use the container's ENV it doesn't get it right.
My question is how can I use the actual Containers' environment variable?
Thanks!
Note:
I on dev environment.
I am not quite familiar with symfony, but it seems like symfony never overwrites existing environment variables. (Ref: https://symfony.com/doc/current/components/dotenv.html)
What if you remove that line in your .env file? Since DATABASE_URL is already an environment variable, calling getenv('DATABASE_URL') in symfony should return you the correct value even if you did not define it in .env. All dotenv does it to write those key value pairs as environment variables in your system. You don't need to define it again if it is already present.
note that there is separate environments when you run php from cli and when it gets run by webserver (when you access it from your browser).
For example, in case of nginx-fpm, the variables that you see in your cli by running printenv are not avaiable in php script run by nginx when you call getenv(). In order to set environment variable for php fpm you can edit php-fpm.conf:
....
[www]
env[DATABASE_URL] = 'mysql://...'
....
If you use another webserver than you should find out how to make env vars available in php script.
Your DATABASE_URL=${DATABASE_URL} in .env file didn't work bacause DATABASE_URL was not set for php fpm.
Hope this helps.
P.S. Note, that this construction VAR=${VAR} makes nothing because DotEnv will not override VAR as it is already defined.
P.P.S. It is advised that you use .env file for your dev server and "real" env variables in staging/production.

Where should I set the variable PATH in R?

I constantly need to call Tex Live binaries for compilation in R. However after the upgrade of Tex Live distribution, the path to current binaries needed to updated manually in the PATH(Sys.getenv("PATH")) variable.
As a single user on a Ubuntu system, which file should I update the value in, so that R gets the PATH correctly irrespective of whichever directory R is launched from.
One point I still don't gather is from where does R gets its site-wide (I mean for all users, even if faulty in saying so) PATH variable set, because no such variable name as "PATH" occur inside any files (Renviron, Renviron.site, Rprofile.site) in either of "R_HOME/etc/" and user's home directory? I also haven't set Sys.getenv("R_ENVIRON") and Sys.getenv("R_ENVIRON_USER") values.
I'd appreciate anybody's input here.
#JeffreyGoldberg's solution was close, but not quite right.
Rprofile files are interpreted as R code
Renviron files can only contain name value pairs, and are not interpreted as R code
From the help for Startup:
Note that there are two sorts of files used in startup: environment files which contain lists of environment variables to be set, and profile files which contain R code.
I'm not sure if this question is asking specifically how one can set the site wide value of PATH, rather than PATH for one specific user, but there are three locations you can put these files.
A project directory (i.e., a directory you choose to launch R from)
HOME
R_HOME/etc
These locations are searched in the order numbered above. The first location can contain configurations specific to a project, the second contains those specific to a user, and the third, site wide configuration settings. When a file is found it is used, so local takes precedence over global. Don't think you can create a more specific version that simply updates what you've done in a more general configuration file. R_HOME/etc/Renviron is created on installation and should not be edited. You may create a file called R_HOME/etc/Renviron.site, but do not edit R_HOME/etc/Renviron.
To create a site wide value of PATH, you will want to set it in a file in R_HOME/etc. Here you can use either Renviron.site or Rprofile.site for the file name. For a file in R_HOME/etc, Do not use Renviron, Rprofile, .Renviron, or .Rprofile for the name of a profile or environment file in this location. You can find out what R_HOME is in an R session using R.home(), or Sys.getenv("R_HOME")
To create a PATH value for a single user, set it in a file in HOME, which you can find in your R session using Sys.getenv("HOME") or path.expand("~"). You can also just use "~" to refer to HOME. Here, an Renviron file should be ~/.Renvironand an Rprofile file ~/.Rprofile. Take note of the difference between how profile and environment files are named in your HOME directory vs. R_HOME/etc
To create a PATH for a single project, set it in a file in that project's top level directory. Name the files as you would in your home directory (.Rprofile or .Renviron).
If you are creating an Renviron file, the file should include the following line:
PATH=<your path>
< and > should not be included. An example would be:
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
If you are creating an Rprofile file, the file should include the following line:
Sys.setenv("<your path>")
again, don't include "<" or ">". An example would be:
Sys.setenv("/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin")
There are various ways of doing this that get and edit a PATH variable (e.g., tack on a new path at the end, or the beginning). You can also use the strategy of setting an environment variable if it doesn't already exist and/or doesn't contain something you want it to. I've come to prefer just setting up my path simply, and coding it directly.
One final note, if you run R from a command line interface, environment variables may be inherited from your shell. RStudio also has its own startup sequence and may modify the end of your PATH variable. It should start as it is defined in your Rprofile or Renviron files. The R Console app itself has the fewest quirks with system environment variables, and should accept your path exactly as it is set with an Rprofile or Renviron file.
Edit: I should have tested before posting. What I describe below did not work. (Down voting my own answer is a strange thing.)
On my system (macOS, bash), R.app is not picking up my $PATH from my shell environment or .profile. However RStudio is picking it up. I do not understand the different behaviors.
One way to get consistent behavior would be to specify this in an Renviron file.
If you create a file named .Renviron in your come directory with a line like
Sys.setenv(PATH="/opt/local/bin:usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Library/TeX/texbin")
(but of course with the path elements you need) that should give you consistent behavior.
The downside is that you need to manually maintain this. I suppose you could run a script from one of your other start up scripts that generated the .Renviron file. But either way, I consider this whole thing a work around in place of actually understanding where R picks up its environment from.

What is the Unix way for a console script to use config files?

Let's imagine we have some script 'm12' (I've just invented this name) that runs
on Linux computers. If it is situated in your $PATH, you can easily run it
from the console like this:
m12
It will work with the default parameters. But you can customize the work of
this script by running it something like:
m12 --enable_feature --select=3
It is great and it will work. But I want to create a config file ~/.m12rc so I
will not need to specify --enable_feature --select=3 every time I run it.
It can be easily done.
The difficult part is starting here.
So, I have ~/.m12rc config file, but I what to start m12 without parameters that
are stored in that config file. What is the Unix way to do this? Should I run
script like this:
m12 --ignore_config
or there is better solution?
Next. Let's imagine I have a config file ~/.m12rc and I want some parameters from that
file, but want to change them a bit. How should I run the script and how the
script should work?
And the last question. Is it a good idea for script to first look for .m12rc
in the current directory, then in ~/ and then in /etc?
I'm asking all these questions because I what to implement config files in my
small script and I want to make the correct decisions about the design.
The book 'The Art of Unix Programming' by E S Raymond discusses such issues.
You can override the config file with --config-file=/dev/null.
You would normally use the order:
System-wide configuration (/etc/m12/m12rc, or just /etc/m12).
User's personal configuration (~/.m12rc)
Local directory configuration (./.m12rc)
Command-line options
with each later-listed item overriding earlier listed items. You should be able to specify the configuration file to read on the command line; arguably, that should be given precedence over other options. Think about --no-system-config or --no-user-config or --no-local-config. Many scripts do not warrant a system config file. Most scripts I've developed would not use both local config and user config. But that's the way my mind works.
The way I package standard options is to have a script in $HOME/bin (say m12a) that does it for me:
#!/bin/sh
exec m12 --enable_feature --select=3 "$#"
If I want those options, I run m12a. If I want some other options, I run raw m12 with the requisite options. I have multiple hundreds of files in my personal bin directory (about 500 on my main machine, a Mac; some of those are executables, but many are scripts).
Let me share my experience. I normally source config file at the beginning of the script. In the config file I also handle all the parameter switches:
DEFAULT_USER=blabla
while getopts ":u" do
case $opt in
u)
export APP_USER=$OPTARG
;;
esac
done
export APP_USER=${APP_USER-$DEFAULT_USER}
Then within the script I just use variables, this let me to have number of script having same input parameters.
In your case I imaging you would move "getopts" section to script and after it source the config file (if there was no switch to skip sourcing).
You should not put yours script config file to etc, it will require root privilidge to do that, and you simple can live with config file in home.
If you would like anyway to put your script for sharing with other users, it should go to /usr/share...
Another solution use thor (ruby gem), its way simpler to handle input parameter, avoiding work to get same result in bash e.g. getopts support only single letter switches.

Is there a way to wrap arbitary commands located under a subdirctory in a shell script

I have a bunch of customizations and would like to run my test program in a pristine environment.
Sure I could use a tiny shell script to wrap and pass of arguments but it would be cool and useful if I could invoke a pre and possibly post script only to commands located under certain sub directories. The shell I'm using is zsh.
I don't know what you include in your “pristine environment”.
If you want to isolate yourself from the whole system, then maybe chroot is what you're after. You can set up a complete new system, with its own /etc, /bin and so on, but sharing the kernel, networking and other non-filesystem stuff with your running system. Root's cooperation is required (the chroot system call is reserved to root).
If you want to isolate yourself from your dot files, run the program with a different value for the HOME environment variable:
HOME=~/test-environment /path/to/test-program
HOME=~/test-environment zsh
If this is specifically about zsh's configuration files, you can set the ZDOTDIR environment variable before starting it to tell zsh to run its own dot files from a directory other than $HOME (or zsh --no-rcs to not load any dot file).
If by pristine environment you mean a fully controlled set of environment variables, then the env program does this.
env -i PATH=$PATH HOME=$HOME program args
will run program args with only the environment variables you specified.

Location of configuration in unix program

I want to write a unix/linux program, that will use a configuration file.
My problem is, where should I put the location of the file?
I could "hardcode" the location (like /etc) into the program itself.
However, I would like it, if the user without privileges could install it (through make) somewhere else, like ~.
Should the makefile edit the source code? Or is it usually done in a different way?
Create some defaults:
/etc/appname
~/.appname
Then if you want to allow these to be overridden have your application inspect an environment variable. e.g.
$app_userconfig
$app_config
Which would contain an override path/filename.
Lastly add a command line option that allows a config to be specified at runtime, e.g.
-c | --config {filename}
It is common to use a series of places to get the location:
Supplied by the user as a command line argument (i.e. ./program -C path/to/config/file.cfg).
From an environment variable (char *path_to_config = getenv("PROGRAMCONFIG");).
Possibly look for a user specific or local version (stat("./program.cfg") or build up a strig to specify either "$HOME/.program/config.cfg" or "$HOME/.program.cfg" and stat that).
Hardcoded as a backup (stat("/etc/program/config.cfg",...)).
keeping a global config file under /etc/prgname is a standard. Also allowing a .local config file for individual users that will override the global settings would allow each user to personalize the program to their preference.
As skaffman says, the canonical locations for things like config files are specified in FHS. There appears to be a convention that a program will read a config file from the directory from which it is run as an alternative to the one in the hard-coded location. You may wish to consider adding a command-line switch that allows a user to specify an alternative config file location, as well.
The makefile shouldn't modify the source directly, but it can pass a folder path/name to the compiler through the -D option. One way to handle it would be to #define something like DEFAULT_PATH to be the default installation path. If the user wants to define a path, the makefile would add -DUSER_PATH=whatever to the compiler options. You would write your code to use USER_PATH if it exists, and DEFAULT_PATH otherwise.

Resources