#9 Environment variables

October 23, 2022

Let's make our server aware of its environment. On our local machine, we want to listen on our local port 8080. On the production server, we want to use HTTPS and port 443.

We need to use environment variables to set this context. These variables are loaded whenever a shell is started. On macOS, I added the following line to my .zprofile script. This is a script that runs whenever zshell (which is what I use) opens. If you use the regular bash, you want to edit .bash_profile.

nano .zprofile
...
export SERVER_ENV="DEV"

On our production server, we need to make the variable visible to the root. Remember - we are running our server with sudo. The file we need to edit is /etc/environment. We can omit the export bit.

sudo nano /etc/environment
...
SERVER_ENV="PROD"

We need to log out and back in for our changes to take effect. But before that, let's adjust our server code. We can access the environment variable with the os.Getenv() method. In the code, I added a simple if statement - if the variable is DEV, let's run a local server with HTTP. If it's PROD, let's listen on a different port with HTTPS.

The adjusted main() function is below.

func main() {
http.HandleFunc("/data", getData);
serverEnv := os.Getenv("SERVER_ENV")
if serverEnv == "DEV" {
http.ListenAndServe(":8080", nil)
} else if serverEnv == "PROD" {
http.ListenAndServeTLS(
":443",
"/etc/letsencrypt/live/api.jurajmajerik.com/fullchain.pem",
"/etc/letsencrypt/live/api.jurajmajerik.com/privkey.pem",
nil,
)
}
}

We can now test our code. Run it locally, then deploy with scp and test on the production server. Both local and production endpoint should now return Hello world.