Dietela: Living in Multiple Environments
Wait, why would we need different places to deploy our code?
This article is written as an individual review assignment for PPL CS UI 2021.
Horray! Your code works fine on your personal computer (PC). Now, it is time to showcase your product to the rest of the world. After deploying it for public use, your product suddenly contains bugs, bugs you have never encountered while testing in your PC or local environment.
Turns out you discovered that your deployment environment requires different configuration settings than in your local environment. Here, we will unravel the essence of “environments” and discover the four most common deployment instances for software development.
The Essence
What is an Environment?
In a nutshell, an environment is the “place” where the code is executed. Every software you see, whether it is a website, a mobile application, or even an operating system, has an environment.
In particular to software development, we usually have a local environment (to write code on our PC) and one or more deployment environments.
More Than One Deployment Environment?
Multiple environments are usually handled by the usage of different branches in a Git repository, where one branch can have a different CI/CD or release configuration. These configurations are represented in variables, called environment variables, where values stored in the environment variables can be different in each environment.
Multiple environments offer two significant benefits for software development:
- Quality Control
Multiple environments allow the internal team to have private and public instances.
We want to see if our code has fulfilled the expected outcome, but we want any issues or debugging logs to be visible only to us and not to the real users. By separating instances, we can conduct user testing for our code changes without any interference on the stable product code used by the real users.
2. Real Features Testing
In our Dietela product, our customers can subscribe to a diet program consultation with a nutritionist by paying through a third-party payment gateway.
As the developer team, we have to test our payment feature numerous times to handle all cases without paying with real money. Here, we can create an environment to make the real features work as they should without sacrificing real resources from the internal team.
The Instances
There are four deployment instances that are widely used in the world of software development. They are:
Localhost
The localhost environment is the environment we used while developing code on our PC.
Since everything takes place within the scope of our PC, localhost can exist in any branch in our local Git repository. The environment variables are detected from the .env
file located in the code directory.
As our product is a mobile application built on React Native, the mobile development side executes the following command
react-native run-android
to build and run an Android app bundle on an Android device or emulator. The configurations used for the app bundle are taken from .env
that follows the environment settings below:
.env.local.example
for Dietela mobile repositoryMeanwhile, the backend development side that uses Django REST framework should execute the command
python manage.py runserver
to run the web instance of REST APIs in localhost:8000
with the following environment variables:
Development
The development environment is the environment for developers to test anything in the same type of deployment instance as the real product. Development is usually interchangeable with staging (see below) where one can exist without the other; however, they serve very distinct purposes. Like our team, we do not have a development environment and only use the staging environment.
In development, form fields, seed, and any data can be just any random text, such as “asdfghjkl”. The purpose of the development environment is for the developers and testers to check if the provided configurations can run in a real deployment instance and verify the main flow and all edge cases of the product.
In Git flow, the conventional way to have a development environment is to have a public branch called “develop”, while in Trunk Based Development, it takes place in “master”.
Staging
The staging environment is the environment that serves as the reflection of the real product in terms of data and performance but is still in development mode. There are many conventions of staging environment name, but our team uses the term “staging”.
Since staging reflects the real product, this is the instance used for demos to stakeholders or clients, therefore the data filled and configuration contained in staging are to be taken seriously.
The Git branch name just follows the agreed environment naming, while the environment variables are stored according to the corresponding deploying “terminal”. For example, scripts to deploy with Gitlab CI/CD detect from variables in Gitlab CI/CD settings:
The steps to build the mobile app are the following:
(1) First, we generate a .env
file from “STAGING_{VAR_NAME}” environment variables.
(2) Second, we compile the code into a release-type APK file by executing
./gradlew assembleRelease
or you can see the full script below:
Production
The production environment is the environment for the real product used by the end-users. Therefore, any software we use runs within the production environment.
The data in production is inaccessible for the developer team, but it does not limit the developers to become end-users. Data gathered here can be used for many purposes: analytics tracking, data science, machine learning dataset, and etc.
In Git flow, the “master” branch is reserved for production. Meanwhile, Trunk Based Development can associate production to any agreed branch, mostly seen being “production” or “release”.