Droplet Environment Variables Disappearing

February 3, 2017 982 views
Nginx Configuration Management System Tools Linux Commands Ghost Ubuntu

I have a Ghost droplet that I recently noticed was not taking image uploads as indicated by the following code that appeared when I tried to upload from the markdown editor file explorer ![]([object Object]). As a result I decided to ssh into my droplet to check out my config file where I am using environment variables to store images to my s3 bucket and noticed when I ran printenv that my environment variables were not there. I decided to set the env variables again like so: export AWS_ACCESS_KEY=*KEY ID* and ran printenv again and the key was there, but ssh'ing into the droplet a day later and the AWS_ACCESS_KEY is gone. Am I setting the env variables correctly? Any reason why they would disappear? I tend to run service ghost restart after setting them, but this didn't reset the env variables.

Here is the storage configuration in my config.js:

storage: {
        active: 'ghost-s3',
        'ghost-s3': {
         accessKeyId: process.env.AWS_ACCESS_KEY,
         secretAccessKey: process.env.AWS_SECRET_KEY,
         bucket: process.env.S3_BUCKET,
         region: process.env.S3_REGION,
         assetHost: process.env.S3_URL
        }
        },

3 Answers
jtittle1 February 4, 2017
Accepted Answer

@connordphillips

When you use export, whether it's in .profile, .bash_profile, or another file that's loaded when you login to SSH, the exported data will only persist for that session (i.e. until that SSH user logs out). For data to persist, it needs to be defined in a persistent way.

Method #01

With NodeJS, the first option is to use process.env and define the environment variables in a file that isn't accessible to the public. Yes, this is slightly frowned upon and most will say you're doing it wrong but it's the first obvious method.

process.env['VARIABLE_NAME'] = VALUE

Method #02

Alternatively, you can pass environment variables when running node. For example:

VAR_01='value' VAR_02='value' node app.js

Method #03

Utilize and existing package to handle .env and environment variables -- particularly, dotenv.

https://github.com/motdotla/dotenv

https://www.npmjs.com/package/dotenv

Using Git/GitHub/Version Control?

Make sure you setup a line to ignore your environment files in Method #01 and #03. You don't want to commit those files to any public repository.

@connordphillips

When you run export, the export is only valid for the shell that you're currently logged in to. Once you logout, whatever you've exported will disappear unless it's explicity set in .bash_profile for the user in question.

For example, if you're username is connord, you'd setup a .bash_profile for this user and add to it:

export AWS_SECRET_ACCESS_KEY=YOUR_KEY
export AWS_ACCESS_KEY_ID=YOURID

Then when you login as connord, the export commands will automatically run and you'll be able to access those variables.

That said, export is still only valid to the logged in users' shell, so you'd need to physically set them for persistence.

For details, you can read about process.env here:

https://nodejs.org/api/process.html#processprocessenv

You'll need to define the process.env variables for them to be persistent. For example:

process.env.AWS_SECRET_ACCESS_KEY = "YOURKEY";
process.env.AWS_ACCESS_KEY_ID = "YOURID"
  • Jtittle thank you so much for the answer. I'm navigating my nginx server and can't seem to figure out where I would find the currently logged in user (I ssh'd into the instance). I also notice at the root three what I assume bash related files, .bashrc, .bashhistory and .profile. Would I set the export in any of these or should there be a .bashprofile present or what you said above, create a .bash_profile? One interesting thing about .bashrc and .profile is their relationship, but I'm not sure if it is meaningful to answering this questions:

    .profile

    # ~/.profile: executed by Bourne-compatible login shells.
    
    if [ "$BASH" ]; then
      if [ -f ~/.bashrc ]; then
        . ~/.bashrc
      fi
    fi
    
    mesg n
    
    
    

    .bashrc (start of the file)

    # ~/.bashrc: executed by bash(1) for non-login shells.
    # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
    # for examples
    

@connordphillips

You can drop the export's in .profile, though keep in mind that this will only apply to the root user and only when that user logs in. They won't be globally set, available to other users, or available to your application unless you're running it while logged in via SSH. Once you close the connection to SSH, whether it's by hitting the X or using exit, they will disappear.

The same applies even if you're running as a user other than root (ideally, you should be -- creating a sudo user and escalating to run root commands is better in terms of security).

If you need the exported data to persist, you would need to define them using process.env as noted at the end of my previous reply.

  • Thanks you for clearing up my confusion. So you are saying that I should add export process.env.VARIABLE within .profile in order to persist the variables in my application? I'm using process.env.VARIABLE in my config.js file, so the reference is there for my configuration as by best practices in NodeJS, but the value for those variables are not present anywhere within the droplet. That seems to be the problem and from your answer might be resolved be setting that in a .bash_profile? or a .env file where the values are set. I'm not thinking it might be the latter as .bash_profile is user specific.

Have another answer? Share your knowledge.