Environment: Ubuntu 16.04, Nginx 1.10.3
Append the following to your site's .gitignore
file so that you don't accidentally commit your environment variables.
/.env
/.env.nginx
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.nginx
to the location block of any sites you need to have access to these variables.
Your Nginx host configuration can usually be found in: /etc/nginx/sites-enabled/default
Symfony Example
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/my-site/public;
index index.php index.html index.htm;
server_name _;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
#the important part
include /var/www/my-sites/.env.nginx;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
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 Nginx 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.nginx
.
I wrote the following script which creates the .env.nginx
file from the .env
one (and restarts Nginx 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'
NGINX_FILE='/var/www/my-site/.env.nginx'
#get origin env contents
#original format: export MYVAR='my val'
CONTENTS=`cat $FILE`
#default as empty in case file doesn't exist yet
CURRENT_NGINX_FILE_CONTENTS=''
#if file exists, get contents
[[ -f "$NGINX_FILE" ]] && CURRENT_NGINX_FILE_CONTENTS=`cat $NGINX_FILE`
#swap = for space
#new format so far: export MYVAR 'my val'
CONTENTS=${CONTENTS//=/ }
#swap export for fastcgi_param
#format change is now: fastcgi_param MYVAR 'my val'
CONTENTS=${CONTENTS//export/fastcgi_param}
#swap new line for ; new line
#format change is complete: env MYVAR 'my val';
CONTENTS=${CONTENTS//$'\n'/;$'\n'}
CONTENTS=${CONTENTS}';'
#if environment variables have changed, then replace contents and restart nginx
if [ "$CONTENTS" != "$CURRENT_NGINX_FILE_CONTENTS" ]; then
#remove old file if exists
[[ -f "$NGINX_FILE" ]] && sudo rm "$NGINX_FILE";
#add nginx version of the file with newly formatted contents
sudo echo "${CONTENTS}" >> "$NGINX_FILE"
echo "Environment Variables have changed. Restarting nginx. (Remember to run source /etc/profile)"
#restart nginx gracefully
sudo service nginx restart --graceful
fi
Manually restart Nginx so that it detects the environment variables
sudo service nginx restart
If that fails, you can run a config test to find out what you did wrong:
sudo nginx -t
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.nginx
file and restart Nginx for you.
If you remove an environment variable from the .env
file, it will remove it from Nginx 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 host config 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/nginx/sites-enabled/default
between two comment blocks, be my guest and I'll personally give it a shot and recommend it here.