diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 789f9ccee3e518d6f848ad6cc26cc52318f19de6..943a20eaa499e17f674f051eeb944e152118a1a0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,12 +1,13 @@
 image: eicweb.phy.anl.gov:4567/containers/image_recipes/ubuntu_dind:latest
 #
 stages:
-  - phase1
-  - phase2
-  - phase3
+  - builder
+  - config
+  - main
+  - singularity
 
-eic_builder_release:
-  stage: phase1
+builder_stable:
+  stage: builder
   tags:
      - sodium dind
   only:
@@ -18,20 +19,55 @@ eic_builder_release:
      - head Dockerfile
      - make login
      - make release-cached
-eic_builder_develop:
-  stage: phase1
+builder_unstable:
+  stage: builder
   tags:
      - sodium dind
-  only:
-     - develop
+  except:
+     - tags
+     - master
+     - staging
   script:
      - cd containers/builder
      - head Dockerfile
      - make login
      - make develop-cached
 
-eic_release:
-  stage: phase2
+## I wish there were a simple way to transfer the "latest/unstable" strings
+## between jobs...
+config_stable:
+  image: eicweb.phy.anl.gov:4567/containers/eic_container/eic_builder:latest
+  stage: config
+  tags:
+    - sodium dind
+  only:
+     - tags
+     - master
+     - staging
+  script:
+    - bash containers/release/config_release.sh
+  artifacts:
+    paths:
+      - config/eic-env.sh
+      - config/Dockerfile
+config_unstable:
+  image: eicweb.phy.anl.gov:4567/containers/eic_container/eic_builder:unstable
+  stage: config
+  tags:
+    - sodium dind
+  except:
+     - tags
+     - master
+     - staging
+  script:
+    - bash containers/release/config_release.sh
+  artifacts:
+    paths:
+      - config/eic-env.sh
+      - config/Dockerfile
+      
+release_stable:
+  stage: main
   tags:
      - sodium dind
   only:
@@ -39,22 +75,26 @@ eic_release:
      - master
      - staging
   script:
+     - cp config/Dockerfile containers/release/Dockerfile
      - cd containers/release
      - make login
      - make release-cached
-eic_develop:
-  stage: phase2
+release_unstable:
+  stage: main
   tags:
      - sodium dind
-  only:
-     - develop
+  except:
+     - tags
+     - master
+     - staging
   script:
+     - cp config/Dockerfile containers/release/Dockerfile
      - cd containers/release
      - make login
      - make develop-cached
 
-eic_builder_singularity:
-  stage: phase2
+builder_singularity:
+  stage: singularity
   tags:
      - sodium dind
   only:
@@ -73,8 +113,8 @@ eic_builder_singularity:
         - build/eic_builder.sif
         - build/eic_builder.def
 
-eic_singularity:
-  stage: phase3
+release_singularity:
+  stage: singularity
   tags:
      - sodium dind
   only:
diff --git a/containers/builder/Dockerfile b/containers/builder/Dockerfile
index 80299ec7e795c29af2a92fc63cfcad0160ebf4e4..f0713ee05981aeb90cdf8063a1bdd7ecfffe4359 100644
--- a/containers/builder/Dockerfile
+++ b/containers/builder/Dockerfile
@@ -38,17 +38,19 @@ RUN cd /opt/spack-environment && spack env activate . \
         ipython matplotlib scipy
 
 ## Strip the binaries
-RUN find -L /opt/view/* -type f -exec readlink -f '{}' \; | \
-    xargs file -i | \
-    grep 'charset=binary' | \
-    grep 'x-executable\|x-archive\|x-sharedlib' | \
-    awk -F: '{print $1}' | xargs strip -s
+#RUN find -L /opt/view/* -type f -exec readlink -f '{}' \; | \
+#    xargs file -i | \
+#    grep 'charset=binary' | \
+#    grep 'x-executable\|x-archive\|x-sharedlib' | \
+#    awk -F: '{print $1}' | xargs strip -s
 
 # Modifications to the environment that are necessary to run
 RUN cd /opt/spack-environment && \
-    spack env activate --sh -d . >> /etc/profile.d/z10_spack_environment.sh && \
+    spack env activate --sh -d . > /etc/profile.d/z10_spack_environment.sh && \
     echo "export BINARY_TAG=x86_64-linux-gcc9-opt" >> /etc/profile.d/z10_spack_environment.sh
 
+##
+
 ## make sure we have the entrypoints setup correctly
 ENTRYPOINT []
 CMD ["bash", "--rcfile", "/etc/profile", "-l"]
diff --git a/containers/release/Dockerfile b/containers/release/Dockerfile.in
similarity index 74%
rename from containers/release/Dockerfile
rename to containers/release/Dockerfile.in
index d37df77b794524cf80b7e46d320d73ac0fe7caf8..319d4ec8749e1b4f1810b49723b116d0dab1fad1 100644
--- a/containers/release/Dockerfile
+++ b/containers/release/Dockerfile.in
@@ -12,20 +12,23 @@ LABEL maintainer="Sylvester Joosten <sjoosten@anl.gov>" \
       basedist="ubuntu" \
       base="ubuntu"
 
-ENV DOCKERFILE_BASE=ubuntu            \
-    DOCKERFILE_DISTRO=ubuntu          \
+## @ENV@ will be automatically expanded to auto-load the 
+## runtime environment
+ENV DOCKERFILE_DISTRO=ubuntu          \
     DOCKERFILE_DISTRO_VERSION=20.04   \
     DEBIAN_FRONTEND=noninteractive    \
-    CURRENTLY_BUILDING_DOCKER_IMAGE=1 \
-    container=docker
+@ENV@
 
 ## Copy over files from builder
 COPY --from=builder /opt/spack-environment /opt/spack-environment
 COPY --from=builder /opt/software /opt/software
 COPY --from=builder /opt/view /opt/view
 COPY --from=builder /etc/profile.d/z10_spack_environment.sh /etc/profile.d/z10_spack_environment.sh
-## Setup global bashrc, useful for singularity
-COPY --from=builder /root/.bashrc /etc/bash.bashrc
+## Setup fresh bashrc, useful for singularity
+COPY bashrc /etc/bash.bashrc
+COPY bashrc /root/.bashrc
+## eic-shell and environment scripts. Not strictly needed anymore now we auto-load
+## the environment but still provided for backward compatibility (and documentation).
 COPY eic-shell /usr/local/bin/eic-shell
 COPY --from=builder /etc/profile.d/z10_spack_environment.sh /etc/eic-env.sh
 
diff --git a/containers/release/bashrc b/containers/release/bashrc
new file mode 100644
index 0000000000000000000000000000000000000000..307c4da3fbae2c10be41c940d1fbed8f1a66d47b
--- /dev/null
+++ b/containers/release/bashrc
@@ -0,0 +1,672 @@
+#!/bin/bash
+iatest=$(expr index "$-" i)
+
+#######################################################
+# SOURCED ALIAS'S AND SCRIPTS BY zachbrowne.me
+#######################################################
+
+# Source global definitions
+if [ -f /etc/bashrc ]; then
+	 . /etc/bashrc
+fi
+
+# Enable bash programmable completion features in interactive shells
+if [ -f /usr/share/bash-completion/bash_completion ]; then
+	. /usr/share/bash-completion/bash_completion
+elif [ -f /etc/bash_completion ]; then
+	. /etc/bash_completion
+fi
+
+#######################################################
+# EXPORTS
+#######################################################
+
+# Disable the bell
+if [[ $iatest > 0 ]]; then bind "set bell-style visible"; fi
+
+# Expand the history size
+export HISTFILESIZE=10000
+export HISTSIZE=500
+
+# Don't put duplicate lines in the history and do not add lines that start with a space
+export HISTCONTROL=erasedups:ignoredups:ignorespace
+
+# Check the window size after each command and, if necessary, update the values of LINES and COLUMNS
+shopt -s checkwinsize
+
+# Causes bash to append to history instead of overwriting it so if you start a new terminal, you have old session history
+shopt -s histappend
+PROMPT_COMMAND='history -a'
+
+# Allow ctrl-S for history navigation (with ctrl-R)
+stty -ixon
+
+# Ignore case on auto-completion
+# Note: bind used instead of sticking these in .inputrc
+if [[ $iatest > 0 ]]; then bind "set completion-ignore-case on"; fi
+
+# Show auto-completion list automatically, without double tab
+if [[ $iatest > 0 ]]; then bind "set show-all-if-ambiguous On"; fi
+
+# Set the default editor
+export EDITOR=vim
+export VISUAL=vim
+alias pico='edit'
+alias spico='sedit'
+alias nano='edit'
+alias snano='sedit'
+
+# To have colors for ls and all grep commands such as grep, egrep and zgrep
+export CLICOLOR=1
+export LS_COLORS='no=00:fi=00:di=00;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:*.xml=00;31:'
+#export GREP_OPTIONS='--color=auto' #deprecated
+alias grep="`which grep` $GREP_OPTIONS"
+unset GREP_OPTIONS
+
+# Color for manpages in less makes manpages a little easier to read
+export LESS_TERMCAP_mb=$'\E[01;31m'
+export LESS_TERMCAP_md=$'\E[01;31m'
+export LESS_TERMCAP_me=$'\E[0m'
+export LESS_TERMCAP_se=$'\E[0m'
+export LESS_TERMCAP_so=$'\E[01;44;33m'
+export LESS_TERMCAP_ue=$'\E[0m'
+export LESS_TERMCAP_us=$'\E[01;32m'
+
+#######################################################
+# MACHINE SPECIFIC ALIAS'S
+#######################################################
+
+# Alias's for SSH
+# alias SERVERNAME='ssh YOURWEBSITE.com -l USERNAME -p PORTNUMBERHERE'
+
+# Alias's to change the directory
+#alias web='cd /var/www/html'
+
+# Alias's to mount ISO files
+# mount -o loop /home/NAMEOFISO.iso /home/ISOMOUNTDIR/
+# umount /home/NAMEOFISO.iso
+# (Both commands done as root only.)
+
+#######################################################
+# GENERAL ALIAS'S
+#######################################################
+# To temporarily bypass an alias, we preceed the command with a \
+# EG: the ls command is aliased, but to use the normal ls command you would type \ls
+
+# Add an "alert" alias for long running commands.  Use like so:
+#   sleep 10; alert
+alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
+
+# Edit this .bashrc file
+#alias ebrc='edit ~/.bashrc'
+
+# Show help for this .bashrc file
+#alias hlp='less ~/.bashrc_help'
+
+# alias to show the date
+alias da='date "+%Y-%m-%d %A %T %Z"'
+
+# Alias's to modified commands
+alias cp='cp -i'
+alias mv='mv -i'
+alias rm='rm -iv'
+alias mkdir='mkdir -p'
+alias ps='ps auxf'
+alias ping='ping -c 10'
+alias less='less -R'
+alias cls='clear'
+alias apt-get='apt-get'
+alias multitail='multitail --no-repeat -c'
+alias freshclam='freshclam'
+alias vi='vim'
+alias vis='vim "+set si"'
+
+# Change directory aliases
+alias home='cd ~'
+alias cd..='cd ..'
+alias ..='cd ..'
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias .....='cd ../../../..'
+
+# cd into the old directory
+alias bd='cd "$OLDPWD"'
+
+# Remove a directory and all files
+alias rmd='/bin/rm  --recursive --force --verbose '
+
+# Alias's for multiple directory listing commands
+alias la='ls -Alh' # show hidden files
+alias ls='ls -aFh --color=always' # add colors and file type extensions
+alias lx='ls -lXBh' # sort by extension
+alias lk='ls -lSrh' # sort by size
+alias lc='ls -lcrh' # sort by change time
+alias lu='ls -lurh' # sort by access time
+alias lr='ls -lRh' # recursive ls
+alias lt='ls -ltrh' # sort by date
+alias lm='ls -alh |more' # pipe through 'more'
+alias lw='ls -xAh' # wide listing format
+alias ll='ls -Fls' # long listing format
+alias labc='ls -lap' #alphabetical sort
+alias lf="ls -l | egrep -v '^d'" # files only
+alias ldir="ls -l | egrep '^d'" # directories only
+
+# alias chmod commands
+alias mx='chmod a+x'
+alias 000='chmod -R 000'
+alias 644='chmod -R 644'
+alias 666='chmod -R 666'
+alias 755='chmod -R 755'
+alias 777='chmod -R 777'
+
+# Search command line history
+alias h="history | grep "
+
+# Search running processes
+alias p="ps aux | grep "
+alias topcpu="/bin/ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10"
+
+# Search files in the current folder
+alias f="find . | grep "
+
+# Count all files (recursively) in the current folder
+alias countfiles="for t in files links directories; do echo \`find . -type \${t:0:1} | wc -l\` \$t; done 2> /dev/null"
+
+# To see if a command is aliased, a file, or a built-in command
+alias checkcommand="type -t"
+
+# Show current network connections to the server
+alias ipview="netstat -anpl | grep :80 | awk {'print \$5'} | cut -d\":\" -f1 | sort | uniq -c | sort -n | sed -e 's/^ *//' -e 's/ *\$//'"
+
+# Show open ports
+alias openports='netstat -nape --inet'
+
+# Alias's for safe and forced reboots
+alias rebootsafe='sudo shutdown -r now'
+alias rebootforce='sudo shutdown -r -n now'
+
+# Alias's to show disk space and space used in a folder
+alias diskspace="du -S | sort -n -r |more"
+alias folders='du -h --max-depth=1'
+alias folderssort='find . -maxdepth 1 -type d -print0 | xargs -0 du -sk | sort -rn'
+alias tree='tree -CAhF --dirsfirst'
+alias treed='tree -CAFd'
+alias mountedinfo='df -hT'
+
+# Alias's for archives
+alias mktar='tar -cvf'
+alias mkbz2='tar -cvjf'
+alias mkgz='tar -cvzf'
+alias untar='tar -xvf'
+alias unbz2='tar -xvjf'
+alias ungz='tar -xvzf'
+
+# Show all logs in /var/log
+alias logs="sudo find /var/log -type f -exec file {} \; | grep 'text' | cut -d' ' -f1 | sed -e's/:$//g' | grep -v '[0-9]$' | xargs tail -f"
+
+# SHA1
+alias sha1='openssl sha1'
+
+#######################################################
+# SPECIAL FUNCTIONS
+#######################################################
+
+# Extracts any archive(s) (if unp isn't installed)
+extract () {
+	for archive in $*; do
+		if [ -f $archive ] ; then
+			case $archive in
+				*.tar.bz2)   tar xvjf $archive    ;;
+				*.tar.gz)    tar xvzf $archive    ;;
+				*.bz2)       bunzip2 $archive     ;;
+				*.rar)       rar x $archive       ;;
+				*.gz)        gunzip $archive      ;;
+				*.tar)       tar xvf $archive     ;;
+				*.tbz2)      tar xvjf $archive    ;;
+				*.tgz)       tar xvzf $archive    ;;
+				*.zip)       unzip $archive       ;;
+				*.Z)         uncompress $archive  ;;
+				*.7z)        7z x $archive        ;;
+				*)           echo "don't know how to extract '$archive'..." ;;
+			esac
+		else
+			echo "'$archive' is not a valid file!"
+		fi
+	done
+}
+
+# Searches for text in all files in the current folder
+ftext ()
+{
+	# -i case-insensitive
+	# -I ignore binary files
+	# -H causes filename to be printed
+	# -r recursive search
+	# -n causes line number to be printed
+	# optional: -F treat search term as a literal, not a regular expression
+	# optional: -l only print filenames and not the matching lines ex. grep -irl "$1" *
+	grep -iIHrn --color=always "$1" . | less -r
+}
+
+# Copy file with a progress bar
+cpp()
+{
+	set -e
+	strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
+	| awk '{
+	count += $NF
+	if (count % 10 == 0) {
+		percent = count / total_size * 100
+		printf "%3d%% [", percent
+		for (i=0;i<=percent;i++)
+			printf "="
+			printf ">"
+			for (i=percent;i<100;i++)
+				printf " "
+				printf "]\r"
+			}
+		}
+	END { print "" }' total_size=$(stat -c '%s' "${1}") count=0
+}
+
+# Copy and go to the directory
+cpg ()
+{
+	if [ -d "$2" ];then
+		cp $1 $2 && cd $2
+	else
+		cp $1 $2
+	fi
+}
+
+# Move and go to the directory
+mvg ()
+{
+	if [ -d "$2" ];then
+		mv $1 $2 && cd $2
+	else
+		mv $1 $2
+	fi
+}
+
+# Create and go to the directory
+mkdirg ()
+{
+	mkdir -p $1
+	cd $1
+}
+
+# Goes up a specified number of directories  (i.e. up 4)
+up ()
+{
+	local d=""
+	limit=$1
+	for ((i=1 ; i <= limit ; i++))
+		do
+			d=$d/..
+		done
+	d=$(echo $d | sed 's/^\///')
+	if [ -z "$d" ]; then
+		d=..
+	fi
+	cd $d
+}
+
+#Automatically do an ls after each cd
+# cd ()
+# {
+# 	if [ -n "$1" ]; then
+# 		builtin cd "$@" && ls
+# 	else
+# 		builtin cd ~ && ls
+# 	fi
+# }
+
+# Returns the last 2 fields of the working directory
+pwdtail ()
+{
+	pwd|awk -F/ '{nlast = NF -1;print $nlast"/"$NF}'
+}
+
+# Show the current distribution
+distribution ()
+{
+	local dtype
+	# Assume unknown
+	dtype="unknown"
+	
+	# First test against Fedora / RHEL / CentOS / generic Redhat derivative
+	if [ -r /etc/rc.d/init.d/functions ]; then
+		source /etc/rc.d/init.d/functions
+		[ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"
+	
+	# Then test against SUSE (must be after Redhat,
+	# I've seen rc.status on Ubuntu I think? TODO: Recheck that)
+	elif [ -r /etc/rc.status ]; then
+		source /etc/rc.status
+		[ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"
+	
+	# Then test against Debian, Ubuntu and friends
+	elif [ -r /lib/lsb/init-functions ]; then
+		source /lib/lsb/init-functions
+		[ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"
+	
+	# Then test against Gentoo
+	elif [ -r /etc/init.d/functions.sh ]; then
+		source /etc/init.d/functions.sh
+		[ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"
+	
+	# For Mandriva we currently just test if /etc/mandriva-release exists
+	# and isn't empty (TODO: Find a better way :)
+	elif [ -s /etc/mandriva-release ]; then
+		dtype="mandriva"
+
+	# For Slackware we currently just test if /etc/slackware-version exists
+	elif [ -s /etc/slackware-version ]; then
+		dtype="slackware"
+
+	fi
+	echo $dtype
+}
+
+# Show the current version of the operating system
+ver ()
+{
+	local dtype
+	dtype=$(distribution)
+
+	if [ $dtype == "redhat" ]; then
+		if [ -s /etc/redhat-release ]; then
+			cat /etc/redhat-release && uname -a
+		else
+			cat /etc/issue && uname -a
+		fi
+	elif [ $dtype == "suse" ]; then
+		cat /etc/SuSE-release
+	elif [ $dtype == "debian" ]; then
+		lsb_release -a
+		# sudo cat /etc/issue && sudo cat /etc/issue.net && sudo cat /etc/lsb_release && sudo cat /etc/os-release # Linux Mint option 2
+	elif [ $dtype == "gentoo" ]; then
+		cat /etc/gentoo-release
+	elif [ $dtype == "mandriva" ]; then
+		cat /etc/mandriva-release
+	elif [ $dtype == "slackware" ]; then
+		cat /etc/slackware-version
+	else
+		if [ -s /etc/issue ]; then
+			cat /etc/issue
+		else
+			echo "Error: Unknown distribution"
+			exit 1
+		fi
+	fi
+}
+
+# Automatically install the needed support files for this .bashrc file
+install_bashrc_support ()
+{
+	local dtype
+	dtype=$(distribution)
+
+	if [ $dtype == "redhat" ]; then
+		sudo yum install multitail tree joe
+	elif [ $dtype == "suse" ]; then
+		sudo zypper install multitail
+		sudo zypper install tree
+		sudo zypper install joe
+	elif [ $dtype == "debian" ]; then
+		sudo apt-get install multitail tree joe
+	elif [ $dtype == "gentoo" ]; then
+		sudo emerge multitail
+		sudo emerge tree
+		sudo emerge joe
+	elif [ $dtype == "mandriva" ]; then
+		sudo urpmi multitail
+		sudo urpmi tree
+		sudo urpmi joe
+	elif [ $dtype == "slackware" ]; then
+		echo "No install support for Slackware"
+	else
+		echo "Unknown distribution"
+	fi
+}
+
+# Show current network information
+netinfo ()
+{
+	echo "--------------- Network Information ---------------"
+	/sbin/ifconfig | awk /'inet addr/ {print $2}'
+	echo ""
+	/sbin/ifconfig | awk /'Bcast/ {print $3}'
+	echo ""
+	/sbin/ifconfig | awk /'inet addr/ {print $4}'
+
+	/sbin/ifconfig | awk /'HWaddr/ {print $4,$5}'
+	echo "---------------------------------------------------"
+}
+
+# IP address lookup
+alias whatismyip="whatsmyip"
+function whatsmyip ()
+{
+	# Dumps a list of all IP addresses for every device
+	# /sbin/ifconfig |grep -B1 "inet addr" |awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' |awk -F: '{ print $1 ": " $3 }';
+
+	# Internal IP Lookup
+	echo -n "Internal IP: " ; /sbin/ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'
+
+	# External IP Lookup
+	echo -n "External IP: " ; wget http://smart-ip.net/myip -O - -q
+}
+
+# View Apache logs
+apachelog ()
+{
+	if [ -f /etc/httpd/conf/httpd.conf ]; then
+		cd /var/log/httpd && ls -xAh && multitail --no-repeat -c -s 2 /var/log/httpd/*_log
+	else
+		cd /var/log/apache2 && ls -xAh && multitail --no-repeat -c -s 2 /var/log/apache2/*.log
+	fi
+}
+
+# Edit the Apache configuration
+apacheconfig ()
+{
+	if [ -f /etc/httpd/conf/httpd.conf ]; then
+		sedit /etc/httpd/conf/httpd.conf
+	elif [ -f /etc/apache2/apache2.conf ]; then
+		sedit /etc/apache2/apache2.conf
+	else
+		echo "Error: Apache config file could not be found."
+		echo "Searching for possible locations:"
+		sudo updatedb && locate httpd.conf && locate apache2.conf
+	fi
+}
+
+# Edit the PHP configuration file
+phpconfig ()
+{
+	if [ -f /etc/php.ini ]; then
+		sedit /etc/php.ini
+	elif [ -f /etc/php/php.ini ]; then
+		sedit /etc/php/php.ini
+	elif [ -f /etc/php5/php.ini ]; then
+		sedit /etc/php5/php.ini
+	elif [ -f /usr/bin/php5/bin/php.ini ]; then
+		sedit /usr/bin/php5/bin/php.ini
+	elif [ -f /etc/php5/apache2/php.ini ]; then
+		sedit /etc/php5/apache2/php.ini
+	else
+		echo "Error: php.ini file could not be found."
+		echo "Searching for possible locations:"
+		sudo updatedb && locate php.ini
+	fi
+}
+
+# Edit the MySQL configuration file
+mysqlconfig ()
+{
+	if [ -f /etc/my.cnf ]; then
+		sedit /etc/my.cnf
+	elif [ -f /etc/mysql/my.cnf ]; then
+		sedit /etc/mysql/my.cnf
+	elif [ -f /usr/local/etc/my.cnf ]; then
+		sedit /usr/local/etc/my.cnf
+	elif [ -f /usr/bin/mysql/my.cnf ]; then
+		sedit /usr/bin/mysql/my.cnf
+	elif [ -f ~/my.cnf ]; then
+		sedit ~/my.cnf
+	elif [ -f ~/.my.cnf ]; then
+		sedit ~/.my.cnf
+	else
+		echo "Error: my.cnf file could not be found."
+		echo "Searching for possible locations:"
+		sudo updatedb && locate my.cnf
+	fi
+}
+
+# For some reason, rot13 pops up everywhere
+rot13 () {
+	if [ $# -eq 0 ]; then
+		tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
+	else
+		echo $* | tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
+	fi
+}
+
+# Trim leading and trailing spaces (for scripts)
+trim()
+{
+	local var=$@
+	var="${var#"${var%%[![:space:]]*}"}"  # remove leading whitespace characters
+	var="${var%"${var##*[![:space:]]}"}"  # remove trailing whitespace characters
+	echo -n "$var"
+}
+
+#######################################################
+# Set the ultimate amazing command prompt
+#######################################################
+
+alias cpu="grep 'cpu ' /proc/stat | awk '{usage=(\$2+\$4)*100/(\$2+\$4+\$5)} END {print usage}' | awk '{printf(\"%.1f\n\", \$1)}'"
+function __setprompt
+{
+	local LAST_COMMAND=$? # Must come first!
+
+	# Define colors
+	local LIGHTGRAY="\033[0;37m"
+	local WHITE="\033[1;37m"
+	local BLACK="\033[0;30m"
+	local DARKGRAY="\033[1;30m"
+	local RED="\033[0;31m"
+	local LIGHTRED="\033[1;31m"
+	local GREEN="\033[0;32m"
+	local LIGHTGREEN="\033[1;32m"
+	local BROWN="\033[0;33m"
+	local YELLOW="\033[1;33m"
+	local BLUE="\033[0;34m"
+	local LIGHTBLUE="\033[1;34m"
+	local MAGENTA="\033[0;35m"
+	local LIGHTMAGENTA="\033[1;35m"
+	local CYAN="\033[0;36m"
+	local LIGHTCYAN="\033[1;36m"
+	local NOCOLOR="\033[0m"
+
+	# Show error exit code if there is one
+	if [[ $LAST_COMMAND != 0 ]]; then
+		# PS1="\[${RED}\](\[${LIGHTRED}\]ERROR\[${RED}\])-(\[${LIGHTRED}\]Exit Code \[${WHITE}\]${LAST_COMMAND}\[${RED}\])-(\[${LIGHTRED}\]"
+		PS1="\[${DARKGRAY}\](\[${LIGHTRED}\]ERROR\[${DARKGRAY}\])-(\[${RED}\]Exit Code \[${LIGHTRED}\]${LAST_COMMAND}\[${DARKGRAY}\])-(\[${RED}\]"
+		if [[ $LAST_COMMAND == 1 ]]; then
+			PS1+="General error"
+		elif [ $LAST_COMMAND == 2 ]; then
+			PS1+="Missing keyword, command, or permission problem"
+		elif [ $LAST_COMMAND == 126 ]; then
+			PS1+="Permission problem or command is not an executable"
+		elif [ $LAST_COMMAND == 127 ]; then
+			PS1+="Command not found"
+		elif [ $LAST_COMMAND == 128 ]; then
+			PS1+="Invalid argument to exit"
+		elif [ $LAST_COMMAND == 129 ]; then
+			PS1+="Fatal error signal 1"
+		elif [ $LAST_COMMAND == 130 ]; then
+			PS1+="Script terminated by Control-C"
+		elif [ $LAST_COMMAND == 131 ]; then
+			PS1+="Fatal error signal 3"
+		elif [ $LAST_COMMAND == 132 ]; then
+			PS1+="Fatal error signal 4"
+		elif [ $LAST_COMMAND == 133 ]; then
+			PS1+="Fatal error signal 5"
+		elif [ $LAST_COMMAND == 134 ]; then
+			PS1+="Fatal error signal 6"
+		elif [ $LAST_COMMAND == 135 ]; then
+			PS1+="Fatal error signal 7"
+		elif [ $LAST_COMMAND == 136 ]; then
+			PS1+="Fatal error signal 8"
+		elif [ $LAST_COMMAND == 137 ]; then
+			PS1+="Fatal error signal 9"
+		elif [ $LAST_COMMAND -gt 255 ]; then
+			PS1+="Exit status out of range"
+		else
+			PS1+="Unknown error code"
+		fi
+		PS1+="\[${DARKGRAY}\])\[${NOCOLOR}\]\n"
+	else
+		PS1=""
+	fi
+
+	# Date
+	PS1+="\[${DARKGRAY}\](\[${CYAN}\]\$(date +%a) $(date +%b-'%-m')" # Date
+	PS1+="${BLUE} $(date +'%-I':%M:%S%P)\[${DARKGRAY}\])-" # Time
+
+	# CPU
+	PS1+="(\[${MAGENTA}\]CPU $(cpu)%"
+
+	# Jobs
+	PS1+="\[${DARKGRAY}\]:\[${MAGENTA}\]\j"
+
+	# Network Connections (for a server - comment out for non-server)
+	PS1+="\[${DARKGRAY}\]:\[${MAGENTA}\]Net $(awk 'END {print NR}' /proc/net/tcp)"
+
+	PS1+="\[${DARKGRAY}\])-"
+
+	# User and server
+	local SSH_IP=`echo $SSH_CLIENT | awk '{ print $1 }'`
+	local SSH2_IP=`echo $SSH2_CLIENT | awk '{ print $1 }'`
+	if [ $SSH2_IP ] || [ $SSH_IP ] ; then
+		PS1+="(\[${RED}\]\u@\h"
+	else
+		PS1+="(\[${RED}\]\u"
+	fi
+
+	# Current directory
+	PS1+="\[${DARKGRAY}\]:\[${BROWN}\]\w\[${DARKGRAY}\])-"
+
+	# Total size of files in current directory
+	PS1+="(\[${GREEN}\]$(/bin/ls -lah | /bin/grep -m 1 total | /bin/sed 's/total //')\[${DARKGRAY}\]:"
+
+	# Number of files
+	PS1+="\[${GREEN}\]\$(/bin/ls -A -1 | /usr/bin/wc -l)\[${DARKGRAY}\])"
+
+	# Skip to the next line
+	PS1+="\n"
+
+  # singularity?
+  if [ -e /environment ] ; then
+      PS1+="singularity"
+  fi
+
+	if [[ $EUID -ne 0 ]]; then
+		PS1+="\[${GREEN}\]>\[${NOCOLOR}\] " # Normal user
+	else
+		PS1+="\[${RED}\]>\[${NOCOLOR}\] " # Root user
+	fi
+
+	# PS2 is used to continue a command using the \ character
+	PS2="\[${DARKGRAY}\]>\[${NOCOLOR}\] "
+
+	# PS3 is used to enter a number choice in a script
+	PS3='Please enter a number from above list: '
+
+	# PS4 is used for tracing a script in debug mode
+	PS4='\[${DARKGRAY}\]+\[${NOCOLOR}\] '
+}
+PROMPT_COMMAND='__setprompt'
diff --git a/containers/release/config_release.sh b/containers/release/config_release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f91cd22f049e28d0dd5a77295bd4f49d96f461a5
--- /dev/null
+++ b/containers/release/config_release.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+## Extract a list of the variable definitions needed
+## for this environment from the builder image, and 
+## then configure the release Dockerfile to set these
+## variables
+
+mkdir -p config
+
+## Extract the desired environment variables as defined by spack
+grep export /etc/profile.d/z10_spack_environment.sh | \
+  sed 's/export /    /' | \
+  sed 's/;$/ \\/' > config/eic-env.sh
+
+## ensure we also have /lib/x86_64-linux-gnu in our library path
+## as it contains important ubuntu system libraries
+sed -i "s?LD_LIBRARY_PATH=?&/lib/x86_64-linux-gnu:?" config/eic-env.sh
+
+## create our release Dockerfile
+sed '/^@ENV@/r config/eic-env.sh' containers/release/Dockerfile.in | \
+  sed '/^@ENV@/d' > config/Dockerfile