Why doesn't apache2 respect my envvars file?

My envvar files has these lines in it:

export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

My apache2.conf has these lines in it:

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

But when I run apache2 -M I get this:

apache2: bad user name ${APACHE_RUN_USER}

A temporary fix is to hard-code www-data into it my apache2.conf file. There was some speculation here that this was because some configuration script didn't replace the env vars correctly in my apache2.conf file. Regardless how do I get apache2 to consult my envvars file?

As another data point this site seems to indicate the envvars is generated at build, but read by apache2ctl at runtime, suggesting that this file isn't just poop leftover by the build process.


After looking over the answer given by @Lekensteyn, I tried sudo apache2ctl -M with my apache2.conf reverted to the original. This worked so I dug into the man pages a bit. Here's what man apache2 had to say:

In  general, apache2 should not be invoked directly, but rather should 
be invoked via /etc/init.d/apache2 or apache2ctl. The default Debian 
configuration requires environment variables that are defined in 
/etc/apache2/envvars  and  are  not  available  if  apache2  is  
started  directly. However, apache2ctl can be used to pass arbitrary 
arguments to apache2.

So, the answer to this question is: You're not using apache2 correctly; use apache2ctl instead.

Thanks @Lekensteyn for pointing me in the right direction.


From http://httpd.apache.org/docs/2.2/configuring.html:

The values of shell environment variables can be used in configuration file lines using the syntax ${ENVVAR}. If "ENVVAR" is the name of a valid environment variable, the value of that variable is substituted into that spot in the configuration file line, and processing continues as if that text were found directly in the configuration file. (If the ENVVAR variable is not found, the characters "${ENVVAR}" are left unchanged for use by later stages in the config file processing.)

So, the variable is indeed retrieved from the environment as expected. Now where does this happen?

In /etc/init.d/apache2, APACHE_ENVVARS is set to the path of the envvars file which is based on the initscript path. It usually results in APACHE_ENVVARS=/etc/apache2/envvars being set. Now, since this value equals to the default values as set in apache2ctl, it is not exported.

From /usr/sbin/apache2ctl:

# the path to the environment variable file
test -z "$APACHE_ENVVARS" && APACHE_ENVVARS="$APACHE_CONFDIR/envvars"
# pick up any necessary environment variables
if test -f $APACHE_ENVVARS; then
  . $APACHE_ENVVARS
fi

Explanation: if APACHE_ENVVARS is empty, use the default path which is /etc/apache2/envvars. If this file exists, "source" it (execute the commands from that file in the current environment).

Be sure that the envvars file does not contain any syntax errors. To perform such a check, use:

sh -n /etc/apache2/envvars && echo Syntax OK || echo FAIL

Errors are printed if any.