Batch edit of environment file
When deploying a project on servers, we need to pay particular attention to the .env
file. This file is crucial and will determine whether our application works properly (or crashes).
The normal way of doing things is to run a git clone
command to get the latest version of the application from a repository (branch test
for a test server, dev
for an acceptance server, main
for a production server).
Once cloned, the next command will be to create the .env
file and it's done using cp .env.example .env
.
And that's where the obligation to be meticulous begins.
Depending on the server (is this a test server or UAt or PROD?), settings won't be the same. We'll for sure not enable debugging on a production one while we'll for a test / uat server. Credentials for the database f.i. will differ for each server. And so on.
So, each time the .env
file is created, the normal way of doing things is to open it in an editor and start to make changes.
And when you have to deploy several servers; you can't be 100% sure you haven't forgotten something important.
Below a Linux function that can help. You can just copy/paste it in your console and run it but first, let's take a look on it.
The updateEnv
function will receive three arguments.
- A variable name like
APP_DEBUG
, - The value was wish to set in the file f.i.
false
- And the name of the
.env
file to update (probably.env
)
The function will use grep
and sed
(see my Search and replace (or add) using sed article to learn more) to update the variable or add it to the file.
Then printf
will echo the new value on the screen, just for debugging / control process.
Finally, the function is called like this: updateEnv "APP_DEBUG" "false" ".env"
.
Before seeing the function, like always, just create a sample file:
mkdir -p /tmp/playing_env && cd $_
echo 'APP_ENV = local' > .env
echo 'APP_DEBUG = true' >> .env
echo 'APP_KEY = 3445118442a942d1/afd37466fadd5223' >> .env
echo 'APP_NAME = My application' >> .env
echo 'CACHE_DRIVER = redis' >> .env
echo 'DATABASE_TYPE = mysql' >> .env
echo 'FORCE_HTTPS = false' >> .env
Now, we can run in our console:
(
updateEnv() {
variable="$1"
newValue="$2"
file="${3:-.env}"
# search the variable in the file. If found, update. It not, add the entry
grepStatus="$(grep -E -q "^${variable}\s?=" "${file}" \
&& (sed -i -r "s~${variable}(\s?)=(\s?).*~${variable}\1=\2${newValue}~" "${file}" && echo "UPDATED") \
|| (sed -i -e "\$a${variable}=${newValue}" "${file}" && echo "ADDED"))"
# Output on the console to help the guy in front of the screen to understand
printf "\e[33;1m%s \e[32;1m%-7s\e[0;1m %s\n" \
${file} "${grepStatus}" "$(grep -i -E "^${variable}\s?=" "${file}")"
return 0
}
clear
dotEnv=".env"
updateEnv "APP_DEBUG" "false" "${dotEnv}"
updateEnv "APP_ENV" "production" "${dotEnv}"
updateEnv "APP_NAME" "My application is running on production" "${dotEnv}"
updateEnv "CAN_REGISTER" "false" "${dotEnv}"
updateEnv "FORCE_HTTPS" "true" "${dotEnv}"
)
The output will be, for this example:
.env UPDATED APP_DEBUG = false
.env UPDATED APP_ENV = production
.env UPDATED APP_NAME = My application is running on production
.env ADDED CAN_REGISTER=false
.env UPDATED FORCE_HTTPS = true
We can see fourth variables have been updated and one has been added (CAN_REGISTER
).
Adding a skip booleanโ
This version introduce a Should we add the variable? flag i.e. should we absolutely set a variable in the environment file if not yet there?
In the example here above, we've seen updateEnv "APP_DEBUG" "false" "${dotEnv}"
. In case of APP_DEBUG
is not yet present, the updateEnv
function will add the variable.
And now, if we call updateEnv "FORCE_HTTPS" "false" "${dotEnv}"
, same thing, we'll add FORCE_HTTPS
in the file but, what if we just skip it?
(
updateEnv() {
variable="$1"
newValue="$2"
file="$3"
add=${4:-true}
# search the variable in the file. If found, update. It not, add the entry
grepStatus="$(grep -E -q "^${variable}\s?=" "${file}" \
&& (sed -i -r "s~${variable}(\s?)=(\s?).*~${variable}\1=\2${newValue}~" "${file}" && echo "UPDATED") \
|| (if ( $add -eq true ); then \
sed -i -e "\$a${variable}=${newValue}" "${file}"
echo "ADDED"
else
echo "SKIP"
fi)
)"
# Output on the console to help the guy in front of the screen to understand
printf "\e[33;1m%s \e[32;1m%-7s\e[0;1m %s\n" \
${file} "${grepStatus}" "$(grep -i -E "^${variable}\s?=" "${file}" || echo ${variable})"
}
clear
dotEnv=".env"
updateEnv "DEFAULT_CACHE" "redis" "${dotEnv}" false
updateEnv "REDIS_HOST" "127.0.0.1" "${dotEnv}" false
)
Now, we've introduced a fourth argument; by default set to true
.
The output of the previous command will be the one below. If not present, variables are not added and this is just perfect.
.env SKIP DEFAULT_CACHE
.env SKIP REDIS_HOST