3

I've got this /etc/profile.d/myfile.sh:

export MYVAR=myval

I also have a PassEnv MYVAR line in a <virtualhost> section of an apache conf dir.

That lets me do things like:

$ echo $MYVAR
myval
$ python
>>> import os; os.getenv('MYVAR')
'myval'
$ sudo echo $MYVAR
myval
$ sudo -i
root# echo $MYVAR
myval

But then, despite that being the case I get:

root# /sbin/service httpd restart
/sbin/service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: [Mon Oct 22 14:44:02 2012] [warn] PassEnv variable MYVAR was undefined
                                                           [  OK  ]

And all of my attempts to access MYVAR from within my wsgi scripts just don't work.

Thoughts? Am I doing something obviously wrong?

EDIT for more detail

I've got a swarm of computers/VMs and a swarm of developers working on a swarm of projects. I need a simple central place to keep environment information, the most common is the "environment" (dev/stage/prod). The scheme that we've got (modifying *.wsgi programmatically) is turning out to be more fragile than we'd like.

The main options that I see are:

  • put things in the shell environment
  • put things in other config files

Getting things into the shell environment is the best, because we won't need to write yet more duplicated "what is my environment" code.

3
  • 1
    Eight years later, so really only for future readers. sudo echo $MYVAR will evaluate $MYVAR and then execute the resulting command. In your example it's myval so the effect is sudo echo myval which I imagine isn't what you'd intended Jun 25, 2020 at 20:10
  • have you found a solution to this? im running into the exact same problem
    – Paul Ma
    Nov 2, 2022 at 9:57
  • @PaulMa You should ask a new question with specific details. Maybe link to here. This one is already marked as answered so it's not so clear at first sight why the bounty was set.
    – cachius
    Nov 4, 2022 at 14:13

1 Answer 1

2

Apache isn't going to read the global user profile.

The big question is what are you actually wanting to do this for?

What you are doing is generally the wrong way of doing things with Apache, but because don't know the actual problem you are trying to solve, then can't say what you should be doing.

Amend your question and state what environment variables you are trying to set and why.


UPDATE 1

Not specifically what you are doing, but SetEnv in mod_wsgi doesn't set process wide environment variables. It sets per request variables in the WSGI environ dictionary.

PassEnv, which is related to SetEnv, would do the same thing but rather than the key/value being defined in Apache configuration file, it would come from the existing process environment variables that Apache inherited.

So, neither of the directives actually has the effect of setting a process wide environment variable for a WSGI application running under mod_wsgi. IOW, they would not be accessible via os.environ as you seem to want.

Now, for PassEnv specifically, if what you are wanting to do is have Apache process environment variables also be available to a WSGI application under mod_wsgi, then PassEnv is actually redundant as the Apache process environment variables will already be available.

This is because in embedded mode WSGI applications run inside the Apache child worker processes. Even in daemon mode, the daemon process is a direct fork of the Apache parent process (no exec of any separate application) and so is effectively also running inside of Apache.

So, PassEnv is not required as they would already be set.

To do it as you are wanting, you are simply doing it in the wrong place as Apache init.d startup scripts aren't going to source the global user login profile.

If you are using an Apache distribution from the Apache Software Foundation, or one that hasn't deviated to far from it, the correct place to set environment variables for Apache is in the 'envvars' file in same directory as the Apache executable. On various Linux distributions the Apache setup totally ignores that file and instead it is necessary to set them in some special file along with the system specific Apache init.d files. What exactly you have to do there will depend on the Linux distribution.

So as I said, Apache will not read that global profile file.

Doit in the right spot and technically it could work, but relying on setting environment variables which affect the whole of Apache wouldn't be what I would recommend.

You would be better having a WSGI script read a separate config file which sets the system status and then base things of that. Using a config file specifically for the purpose isn't as magic as relying on environment variable settings coming in from a file which isn't specifically part of the project but Apache init scripts.

8
  • 1
    Done, but could you tell my why this is the wrong way to do things with Apache? There's no good way to get correctly set environment variables into Apache wsgi subprocesses? The docs seem to be wrong, because they suggest that not only does it work, it looks easy. Oct 22, 2012 at 22:40
  • If you want to set a specific (system-)enviroment variable in apache, you must set it in the start skript since non-interactive shells do not use /etc/profile*. man bash explains this. If you want an apache-internal enviroment variable you set it in the apache config via SetEnv. All this has nothing to do with mod_wsgi.
    – tim
    Oct 22, 2012 at 23:57
  • As explained, SetEnv does not set Apache internal process environment variables. SetEnv will only set process environment variables in situations like CGI where spawning a separate process. In mod_wsgi SetEnv variables only get passed across to WSGI per request environ dictionary as everything is already effectively running inside of Apache and you cannot go changing process environment variables on every request when can have multiple threads running in same process handling requests. Oct 23, 2012 at 1:25
  • This is simply not true. See httpd.apache.org/docs/2.2/mod/mod_env.html for documentation...
    – tim
    Oct 23, 2012 at 10:36
  • All I can say is that I have been telling people to put stuff in envvars or appropriate init.d file for years to have environment variables available to Apache and never have had to have someone use PassEnv to do it. I just went and verified it again with an ASF source distribution. The environment variable I set in envvars was automatically available in the environment variables visible to the WSGI script running with mod_wsgi. It was not necessary to use PassEnv. Despite it saying 'which are available to Apache HTTP Server modules', my experience has been that that is relevant only to CGI. Oct 23, 2012 at 11:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .