Many blogs suggest putting your variables in /etc/environment
and including that file in /etc/apache2/envvars
, but that solution did not work for me. After hours of searching and testing, this is what I came up with. I figured others may find it useful.
Environment: Ubuntu 16.04, Apache 2.4
Append the following to your site's .gitignore
file so that you don't accidentally commit your environment variables.
/.env
/.env.apache
You can use another folder on your server and swap /var/www/my-site/
below with your alternative path.
Add Include /var/www/my-site/.env.apache
to the virtualhost block of any sites you need to have access to these variables.
Your Apache virtualhost configuration can usually be found in: /etc/apache2/sites-enabled/000-default.conf
or /etc/apache2/sites-enabled/mysite_com.conf
Example
<VirtualHost *:80>
DocumentRoot /var/www/my-site/public
#Here's where we include the environment variables
Include /var/www/my-site/.env.apache
<Directory /var/www/my-site/public>
#...whatever config you have here
</Directory>
</VirtualHost>
Add . /var/www/my-site/.env
to the top of /etc/profile
so that all users on the server have access to the environment variables via the command line.
If you need to protect your env vars more, use ~/.bashrc
instead so only your current user has access and swap /etc/profile
below with ~/.bashrc
.
Create the .env
file in the location you specified above.
nano /var/www/my-site/.env
Inside that file, enter your environment variables in the following format:
export MY_VAR='my value'
export ANOTHERVAR='another value'
Now that you have Apache and Ubuntu looking at the .env files and you've got some variables in your .env, it's time to generate /var/www/my-site/.env.apache
.
I wrote the following script which creates the .env.apache
file from the .env
one (and restarts Apache automatically, if needed), then I run this script during my deploy process.
#!/usr/bin/env bash
#set file locations
FILE='/var/www/my-site/.env'
APACHE_FILE='/var/www/my-site/.env.apache'
#get origin env contents
#original format: export MYVAR='my val'
CONTENTS=`cat $FILE`
#default as empty in case file doesn't exist yet
CURRENT_APACHE_FILE_CONTENTS=''
#if file exists, get contents
[[ -f "$APACHE_FILE" ]] && CURRENT_APACHE_FILE_CONTENTS=`cat $APACHE_FILE`
#swap = for space
#new format so far: export MYVAR 'my val'
CONTENTS=${CONTENTS//=/ }
#swap export for setEnv
#format change is complete: setEnv MYVAR 'my val'
CONTENTS=${CONTENTS//export/setEnv}
#if environment variables have changed, then replace contents and restart apache
if [ "$CONTENTS" != "$CURRENT_APACHE_FILE_CONTENTS" ]; then
#remove old file if exists
[[ -f "$APACHE_FILE" ]] && sudo rm "$APACHE_FILE";
#add apache version of the file with newly formatted contents
sudo echo "${CONTENTS}" >> "$APACHE_FILE"
echo 'Environment Variables have changed. Restarting apache. (Don't forget to run "source /etc/profile")'
#restart apache
sudo service apache2 restart
fi
Manually restart Apache so that it detects the environment variables
sudo service apache2 restart
If that fails, you can run a config test to find out what you did wrong:
sudo apache2ctl configtest
You can either logout of ssh and log back in, or run the following to update the environment variables that are available to your user:
source /etc/profile
Then you can test it like this:
printenv MY_VAR
If it worked, you'll see the value on your screen
Integrate environment variables into your deployment process by modifying the .env
file, then running the script provided above which will auto-generate your .env.apache
file and restart apache for you.
If you remove an environment variable from the .env
file, it will remove it from Apache on restart, but it will not remove it from the system.
Instead, you should put the following in your /etc/profile
file:
unset MY_VAR
This could totally be done without adding any new files. I'm sure you could set something up where you put your variables in /etc/profile
and wrap them in two comment lines, then use regex to grab those and put them in your virtualhost file between two other comment lines. That would totally work.
Personally, I like having them in my project folder (gitignored of course) in an easily identifiable file, but Im not married to it. If anyone wants to modify my script above to grab the contents from /etc/profile
, parse out the custom env vars between two custom comment blocks, then save those in /etc/apache2/sites-enabled/000-default.conf
between two comment blocks, be my guest and I'll personally give it a shot and recommend it here.