Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Josh Siok and Megan Siok
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Josh Siok@siok ) and Megan Siok

Reading Environment (ENV) Variables From The Server Scope In Lucee CFML 5.3.7.47

By on
Tags:

This is a pro-tip that I originally picked up from Julian Halliwell a few years ago. However, I sometimes talk to people who don't realize that this is possible. So, I wanted to try and amplify Julian's post. In Lucee CFML, you can read environment (ENV) variables directly out of the server scope. They are just automatically there - no dipping into the Java layer or dealing with the java.lang.System class. Lucee CFML brings these values to the surface for easy consumption.

Specifically, all of the ENV variables are located at:

server.system.environment

Much like the process.env object in Node.js, this is a Struct in which every value is a String. Let's see this in action. In the following ColdFusion code, I'm wrapping access to the aforementioned Struct in a User-Defined Function (UDF) - env() - so that I can add a bit of fallback logic for non-existent / non-populated environment variable values:

<cfscript>

	echoLn( "FOO:", env( "FOO" ) );
	echoLn( "BAR:", env( "BAR", "!! Fallback for Bar !!" ) );
	echoLn( "JAVA_HOME:", env( "JAVA_HOME" ) );
	echoLn( "JAVA_VERSION:", env( "JAVA_VERSION" ) );

	// ------------------------------------------------------------------------------- //
	// ------------------------------------------------------------------------------- //

	/**
	* I return the given environment variable value; or, the fallback if the variable is
	* either UNDEFINED or EMPTY.
	*/
	public string function env(
		required string name,
		string fallbackValue = ""
		) {

		// In Lucee CFML, we can access the environment variables directly from the
		// SERVER SCOPE.
		var value = ( server.system.environment[ name ] ?: "" );

		// For the sake of the demo, we're treating an EMPTY value and a NON-EXISTENT
		// value as the same thing, using the given value only if it is populated.
		return( value.len() ? value : fallbackValue );

	}


	/**
	* I echo each argument and then add a line-break (BR tag).
	*/
	public void function echoLn() {

		echo( arrayToList( arguments, " " ) & "<br />" );

	}

</cfscript>

Now, if we run this ColdFusion code, we get the following output:

FOO:
BAR: !! Fallback for Bar !!
JAVA_HOME: /usr/local/openjdk-8
JAVA_VERSION: 8u272

As you can see, our non-existent FOO and BAR variables are reported using their fallback values. And, our valid JAVA_HOME and JAVA_VERSION environment variables are successfully pulled out of the server scope. Easy peasy lemon squeezy!

Want to use code from this post? Check out the license.

Reader Comments

154 Comments

Loosely related, we tag each of our servers so that we can fork logic based on the development environment the server resides in. This allows us to use TEST resources whenever we're in the test environment and PROD resources when in prod.

How this works...in the server.json under jvm.args we add "-Dges.config.serverEnvironment=test" for our test server configs. Then in our applications, we access that variable using the application scope application.serverEnvironment. It's a very useful utility :)

15,260 Comments

@Chris,

Great minds think alike - we use a variable called serverType for that same kind of thing. I think it can be either "live", "preview", or "local" (if memory serves me off-hand). Probably in a perfect world, we wouldn't these kind of checks because every possible value would be an ENV input. But, sometimes, it's just so much easier to check to see which environment you're running in ๐Ÿ˜†

48 Comments

FWIW, the server.system struct (and environment and properties under that) are available also in CF2018 and above.

I appreciate that Ben's focus now is Lucee, and I don't want to jump in to every post and be "that guy". Still, since some folks using CF could find this, I wanted them to know they can use it there also. :-)

15,260 Comments

@Charlie,

No, Charlie, that is great to know. I have to say, I actually did quite a bit of Googling for things like, "ColdFusion environment variables" and "ColdFusion ENV" and "ColdFusion reading ENV values", and nothing came up for Adobe ColdFusion. So, thank you very much for adding clarity - I had tried to do my due diligence (without actually spinning up a server), and fell short.

1 Comments

So here is a question. If I add or change an ENV var, how do I force CF to re-read them w/o restarting CF? Sort of like you would do with a ?reload for the app.

15,260 Comments

@Derek,

That's an interesting question - I haven't run across that in my work since we actually deploy new containers as part of changes like that. As such, I've not personally had to reload an ENV value.

Your question is founded on the idea that the readable scope isn't automatically updated when an ENV is changed. I haven't tested that directly; but, I would mostly assume that to be true. But, even if that did update, you'd likely still have to reload the app itself since you never know where those ENV have been cached.

I wonder if the java.lang.System reads are update live. I supposed if they are, you might just have to go that route instead.

Sorry I don't have anything more definitive - I'll see if I can find some time to play with this idea.

Post A Comment — I'd Love To Hear From You!

Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.