Skip to content

Instantly share code, notes, and snippets.

@HTMLGuyLLC
Last active December 11, 2021 15:47
Show Gist options
  • Save HTMLGuyLLC/262158c5feea0b45447db33c5a276aee to your computer and use it in GitHub Desktop.
Save HTMLGuyLLC/262158c5feea0b45447db33c5a276aee to your computer and use it in GitHub Desktop.
Sharing Environment Variables between Ubuntu users and Nginx

Sharing Environment Variables Between your Ubuntu user, and Nginx.

Environment: Ubuntu 16.04, Nginx 1.10.3

Step 1

Append the following to your site's .gitignore file so that you don't accidentally commit your environment variables.

/.env
/.env.nginx
Step 1 Variation

You can use another folder on your server and swap /var/www/my-site/ below with your alternative path.

Step 2

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;
}

Step 3

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.

Step 3 Variation

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.

Step 4

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'

Step 5

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

Step 6

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

Step 7

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

Step 8

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.

Warning

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

Improvements

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment