Managing env variables

How to manage environment variables in your projects and applications

A well designed application can run in multiple environments. Its configuration is not hard-coded in the source code, but instead extracted and allowed to be adjustable appropriately for different situations. Although apps run the same code, they may use different, environment-specific configuration.

For example, your application may use a different instance of database on your machine than in a production environment (thus, database credentials and addresses should be configurable).

For this reason, Qovery allows you to store your configurations and credentials securely using Environment Variables.

Set variables

Let's first create a new Node.js application that uses environment variables.

  1. In an empty directory, create .qovery.yml - Qovery configuration file with the following content:

    .qovery.yml
    application:
    name: node-app
    project: environment-variables-demo
    cloud_region: aws/eu-west-3
    publicly_accessible: true
    routers:
    - name: main
    routes:
    - application_name: node-app
    paths:
    - /*
  2. Create app.js file - a simple Node.js HTTP server application:

    app.js
    const http = require('http');
    const hostname = '0.0.0.0';
    const port = 3333;
    const MY_MESSAGE = process.env.MY_MESSAGE
    const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end(MY_MESSAGE);
    });
    server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
    });

    As you see, in the first highlighted line the app uses process.env.MY_MESSAGE environment variable to set a value of a property in the application. Then, in the second highlighted line, the application sends the value of previously set property back to the user that hits the server.

  3. And the last step to finish our application - create a Dockerfile with the following content:

    Dockerfile
    FROM node
    COPY app.js .
    EXPOSE 3333
    CMD [ "node", "app.js" ]

Now, initialize a Git repository in this directory and publish it to your Github. After it's done, your app should be deployed quickly:

Check app status
qovery status
OUTPUT
BRANCH NAME | STATUS | ENDPOINTS | APPLICATIONS | DATABASES
master | running | https://main-im6qagd2nmnrfqax-gtw.qovery.io | node-app | none
APPLICATION NAME | STATUS | ENDPOINT | DATABASES
node-app | running | | none

When you hit the application endpoint (using curl or your browser), you'll see an empty response:

Invoke application endpoint
$ curl https://main-im6qagd2nmnrfqax-gtw.qovery.io
OUTPUT

Why is that? That's because... we did not set MY_MESSAGE environment variable that we use in our application.

Let's fix it quickly. Run:

Add MY_MESSQGE variable
qovery application env add MY_MESSAGE "Hello World from Qovery!"

Now, our variable is set. To check it:

List env variables
qovery application env list
SCOPE | KEY | VALUE
BUILT_IN | QOVERY_JSON_B64 | <base64>
BUILT_IN | QOVERY_BRANCH_NAME | master
BUILT_IN | QOVERY_IS_PRODUCTION | true
BUILT_IN | QOVERY_APPLICATION_NODE_APP_HOSTNAME | <hidden>
APPLICATION | MY_MESSAGE | Hello World from Qovery!

After adding a new variable, we have to restart our application to make it able to read the new configuration:

Redeploy an application
qovery redeploy

Your application should be back up shortly after redeployment. You can track the status using qovery status command. After it's running again, test the app's endpoint:

Invoke application endpoint
$ curl https://main-im6qagd2nmnrfqax-gtw.qovery.io
OUTPUT
Hello World from Qovery!

Great! The env variable was read by the application correctly and returned to the user.

Configure database

Now, we would like to use a database in our application. How to get its connection data, like connection URI, password, and username?

Let's first add a database to our app:

.qovery.yml
application:
name: node-app
project: environment-variables-demo
cloud_region: aws/eu-west-3
publicly_accessible: true
databases:
- type: mongodb
version: "3.6"
name: my-mongo
routers:
- name: main
routes:
- application_name: node-app
paths:
- /*

Add the highlighted part to your Qovery config, commit and push. Voila! In a few minutes, our MongoDB instance is available to the application. To track this process, run qovery status.

After the database is deployed, we need to know a few details about it to use it in the application.

To get the details, run qovery application env list one more time:

SCOPE | KEY | VALUE
BUILT_IN | QOVERY_JSON_B64 | <base64>
BUILT_IN | QOVERY_BRANCH_NAME | master
BUILT_IN | QOVERY_IS_PRODUCTION | true
BUILT_IN | QOVERY_APPLICATION_NODE_APP_HOSTNAME | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_DATABASE |
BUILT_IN | QOVERY_DATABASE_MY_MONGO_PASSWORD | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_USERNAME | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_PORT | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_FQDN | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_HOST | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_CONNECTION_URI_WITHOUT_CREDENTIALS | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_CONNECTION_URI | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_VERSION | 3.6
BUILT_IN | QOVERY_DATABASE_MY_MONGO_TYPE | MONGODB
BUILT_IN | QOVERY_DATABASE_MY_MONGO_NAME | my-mongo
APPLICATION | MY_MESSAGE | Hello World from Qovery!

Adding a new database resulted in new environment variables available for the application! To display hidden values, add -c flag to the command -> qovery application env list -c.

Now, we could just read QOVERY_DATABASE_MY_MONGO_CONNECTION_URI env variable in our app to get the connection URI to MongoDB. This approach would work and is completely fine, but what if we have chosen a different name for database URI? If we need a value of one of BUILT_IN variables (like Qovery database credentials), but we want to use our own env variable names like, for example, MONGO_URI, then we can create an alias.

Let's see it in action:

Create variable alias
qovery application env add MONGO_URI '$QOVERY_DATABASE_MY_MONGO_CONNECTION_URI'

After running the command from above, we should see a new env variable added with the value of QOVERY_DATABASE_MY_MONGO_CONNECTION_URI:

List variables
qovery application env list
OUTPUT
SCOPE | KEY | VALUE
BUILT_IN | QOVERY_JSON_B64 | <base64>
BUILT_IN | QOVERY_BRANCH_NAME | master
BUILT_IN | QOVERY_IS_PRODUCTION | true
BUILT_IN | QOVERY_APPLICATION_NODE_APP_HOSTNAME | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_DATABASE |
BUILT_IN | QOVERY_DATABASE_MY_MONGO_PASSWORD | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_USERNAME | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_PORT | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_FQDN | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_HOST | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_CONNECTION_URI_WITHOUT_CREDENTIALS | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_CONNECTION_URI | <hidden>
BUILT_IN | QOVERY_DATABASE_MY_MONGO_VERSION | 3.6
BUILT_IN | QOVERY_DATABASE_MY_MONGO_TYPE | MONGODB
BUILT_IN | QOVERY_DATABASE_MY_MONGO_NAME | my-mongo
APPLICATION | MONGO_URI | <hidden>
APPLICATION | MY_MESSAGE | Hello World from Qovery!

Above, you can see that the env was added. Run the same command with -c flag to see that its value is in fact the same as QOVERY_DATABASE_MY_MONGO_CONNECTION_URI.

Now, we can use MONGO_URI environment variable to connect our application to MongoDB!

Update variable

What if we would like to change the message our app returns to the user? To change the value of MY_MESSAGE env variable, simply run:

Update variable
qovery application env add MY_MESSAGE "Completely new message!"

Adding env variable with the same name shadows previously set value.

Delete variable

If for some reason you would like to delete variable completely, you can run:

Delete variable
qovery application env delete MY_MESSAGE

That's all; it's gone.

Scopes of variables

So far, we have used just one branch (environment) and only one env variable scope (application scope).

To see what it means, run:

Create a new branch
git checkout -b another_branch
git push --set-upstream origin another_branch

Now, as we use a different Git branch, we are in a different environment.

Run qovery application env list. What do you see? Env variables we set previously are gone. That's because they were bound to the application scope.

On Qovery, we have a few levels of environment variables. BUILT_IN variables are automatically created and injected by Qovery. APPLICATION variables are bound to single application in one environment (Git branch). ENVIRONMENT scope variables are bound to the environment, so they're accessible by all applications in a given environment. The last scope - PROJECT scope - makes a given variable accessible everywhere (all apps, all environments).

To select the scope of variables that you are adding/removing/listing, use the CLI as follows:

Env variables scopes
qovery application env list
qovery project env list
qovery environment env list

The general pattern of this command is qovery SCOPE env COMMAND.