How to Deploy Infisical to Manage Application Secrets on Koyeb
Tags: webdev, tutorial, opensource, security
Published: 2024-06-25 14:27:43

[Infisical](https://infisical.com/) is an open-source secret management platform to securely store and manage secrets for both users and applications. It integrates easily with many different application stacks and can replace environment variable-based secret workflows with simple API driven secret management. With advanced features like continuous monitoring and pre-commit checks, Infisical can help you prevent leaks and identify actions that might expose sensitive data.

In this tutorial, we will show how to deploy an Infisical instance on Koyeb. We provision a [Koyeb PostgreSQL database](https://www.koyeb.com/docs/databases) to store the application data, set up an [Aiven Redis database](https://aiven.io/redis) to manage session data and perform background tasks, and configure [Mailgun](https://www.mailgun.com/) to handle emails. We will deploy Infisical using these components and demonstrate how to manage secrets with it for your applications.

Be sure to modify all of the environment variable values to reflect your own data. You can consult this guide if you need additional information on appropriate values.

## Requirements

To successfully follow and complete this guide, you need:

- A [Koyeb account](https://app.koyeb.com) to provision the PostgreSQL database and to build and deploy the Infisical application.
- An [Aiven account](https://aiven.io/) to provision the Redis database.
- A [Mailgun account](https://www.mailgun.com/) to provide account-based email services for the application.
- [Docker](https://www.docker.com/) installed on your local computer run the initial database migrations.

## Steps

To complete this guide and deploy an Infisical application, you'll need to follow these steps:

1. [Provision a PostgreSQL database on Koyeb](#provision-a-postgre-sql-database-on-koyeb)
2. [Provision a Redis instance on Aiven](#provision-a-redis-instance-on-aiven)
3. [Set up the Mailgun SMTP service](#set-up-the-mailgun-smtp-service)
4. [Connect to the database to run Infisical migrations](#connect-to-the-database-to-run-infisical-migrations)
5. [Get the Infisical image version number](#get-the-infisical-image-version-number)
6. [Deploy Infisical to Koyeb](#deploy-infisical-to-koyeb)
7. [Create an administration account](#create-an-administration-account)
8. [Configure a project and secrets](#configure-a-project-and-secrets)
9. [Access secrets for your applications](#access-secrets-for-your-applications)

## Provision a PostgreSQL database on Koyeb

Infisical uses a PostgreSQL database to store its application data. Since we will be deploying the application to Koyeb, we will create a database using [Koyeb's PostgreSQL service](https://www.koyeb.com/docs/databases), which includes a free tier.

To deploy a new PostgreSQL database, on the **Overview** tab of the [Koyeb control panel](https://app.koyeb.com/), click **Create Database Service**. Choose a name for the service and choose the region closest to you or your users.

Once the database is provisioned, click the **copy icon** associated with `psql` to save the connection details for later.

## Provision a Redis instance on Aiven

Infisical uses Redis for session management and to help coordinate background tasks.
We will use [Aiven Redis](https://aiven.io/redis) for this since they have a generous free tier.

To begin, [log in to your Aiven account](https://console.aiven.io/login) and follow these steps:

1. In the upper-right corner, click **Create service**.
2. On the service selection page, click **Redis**.
3. Select **Free plan** to use a free Aiven service.
4. Select the region closest to where you plan to run Infisical.
5. Choose a name for the service or confirm the default choice.
6. Click **Create free service** to initialize the new Redis store.

Once the service is available, click the **copy icon** associated with the **Service URI** to save the connection details for later.

## Set up the Mailgun SMTP service

Next, you need to copy the SMTP information for your Mailgun account. We will configure Infisical to handle authentication and account-based email flows using this provider.

To begin, log into your [Mailgun account](https://login.mailgun.com/login/). In the side navigation pane, open the **Sending** menu. Next, click the **Overview** sub-menu item.

Mailgun offers sandbox domains to test its functionality. These are useful, but restricted to sending emails only to previously authorized email addresses. We can use this to test the mail delivery with Infisical for free. On the right sidebar of the Overview page, enter the email address you want to send test emails to in **email address** input field of the **Authorized Recipients** section and click the **Save Recipient** button.

Mailgun will send a verification email to the provided address. In the verification email, click the **I Agree** button to complete the authorization process. If you refresh the page in Mailgun, you see that the target email address is now marked as verified.

From this same page, click the **Select** box associated with "SMTP" to see the information you need to send email using your Mailgun account. The information related to using SMTP with your Mailgun account will be displayed. Copy and save the following information:

| Mailgun SMTP info | Infisical env var | Example                                                          |
| ----------------- | ----------------- | ---------------------------------------------------------------- |
| SMTP hostname     | `SMTP_HOST`       | `smtp.mailgun.org`                                               |
| Username          | `SMTP_USERNAME`   | `postmaster@sandboxbac59f0e6dac45cdab38e53aee4e1363.mailgun.org` |
| Password          | `SMTP_PASSWORD`   | `e627704d99111f00c7aedf3805961383-262b123e-66b6979f`             |

## Connect to the database to run Infisical migrations

Now that the Infisical database is up and running, we can begin to configure it for the application. Before running the Infisical application itself, we must apply the relevant migrations for the release we are using to the database.

To do this, pull the latest image built for PostgreSQL (instead of the legacy MongoDB implementation):

```bash
docker pull infisical/infisical:latest-postgres
```

Run the migrations for the Infisical version you pulled passing along your PostgreSQL connection string with `?sslmode=require` appended as the `DB_CONNECTION_URI` environment variable:

```bash
docker run --env DB_CONNECTION_URI="<YOUR_POSTGRESQL_CONNECTION_STRING>?sslmode=require" infisical/infisical:latest-postres npm run migration:latest
```

Docker will run the image with the PostgreSQL connection information and execute the `migration:latest` script defined in the image's `package.json` file. This will apply all of the necessary migrations to your database in the correct order, ensuring that it has the appropriate objects and structures to run Infisical.

You can verify this worked as expected by connecting to your database with the `psql` client and listing the available tables:

```bash
psql <YOUR_POSTGRESQL_CONNECTION_STRING> -c "\dt"
```

## Get the Infisical image version number

When we ran the database migrations, we pulled the `latest-postgres` tag to get the most up-to-date version of the software. We must ensure that the version of the application we run matches the migrations we applied. To do so, we need to disambiguate the `latest-postgres` tag and find the version-specific tag for the same image.

We can do this by finding the SHA-256 hash of the `latest-postgres` image we pulled. Run the following command to assign the image digest to a local `DIGEST` environment variable:

```bash
export DIGEST="$(docker image list --digests infisical/infisical | grep latest-postgres | awk '{print $3;}')"
```

Next, if you have [`jq` installed](https://jqlang.github.io/jq/), you can curl the Docker Hub API for all of the Infisical image tags and select the ones with matching digests:

```bash
curl -s https://hub.docker.com/v2/namespaces/infisical/repositories/infisical/tags | jq -r '.results[] | select(.digest == "'$DIGEST'") | .name'
```

The output will look something like this:

```
v0.64.0-postgres
049df6a
latest-postgres
```

In our case, we can see that `v0.64.0-postgres` is an alternative, stable tag for the same release we ran.

If you don't have `jq` available, you can manually search the [Infisical tags on Docker Hub](https://hub.docker.com/r/infisical/infisical/tags) to find the SHA-256 digest that matches the digest you found.

When you deploy Infisical to Koyeb, you should use this tag to avoid a version mismatch.

## Deploy Infisical to Koyeb

Now that the database is ready and you know which version to run, you can deploy Infisical to Koyeb. On the **Overview** tab of the [Koyeb control panel](https://app.koyeb.com/), click **Create Web Service** to begin:

1. Select **Docker** as the deployment method.
2. For the image path, use `docker.io/infisical/infisical` followed by the tag that corresponds to the migrations you ran. In the example we used above, this would be `docker.io/infisical/infisical:v0.64.0-postgres`.
3. In the **Environment variables** section, click **Bulk edit** to enter multiple environment variables at once. In the text box that appears, paste the following:

   ```
   SITE_URL=https://{{ KOYEB_PUBLIC_DOMAIN }}
   DB_CONNECTION_URI=
   REDIS_URL=
   SMTP_HOST=
   SMTP_PORT=465
   SMTP_USERNAME=
   SMTP_PASSWORD=
   SMTP_SECURE=true
   SMTP_FROM_ADDRESS=infisical@{{ KOYEB_PUBLIC_DOMAIN }}
   SMTP_FROM_NAME=Infisical
   TELEMETRY_ENABLED=false
   ENCRYPTION_KEY=
   AUTH_SECRET=
   ```

   Set the variable values to reference your own information as follows:

   - `SITE_URL`: This is the public URL where the Infisical instance will be available. This is used to form links in emails and for other purposes. Setting it to `https://{{ KOYEB_PUBLIC_DOMAIN }}` will automatically set the correct value.

   * `DB_CONNECTION_URI`: The connection string to connect to and authenticate with the PostgreSQL database. Set this to the `psql` connection string you copied from your Koyeb database detail page and append `?ssl_mode=require` to the end to force the connection to use TLS/SSL.

   - `REDIS_URL`: The connection string for your Redis instance. Use the value copied from the Aiven control panel.
   - `SMTP_HOST`: The host for the SMTP email provider. Use the SMTP hostname copied from your Mailgun account.
   - `SMTP_PORT`: The port to use to connect to the SMTP email provider. Though Mailgun shows port 587, the alternative port `465` is the only one that works with Infisical at time of writing.
   - `SMTP_USERNAME`: The username to use to authenticate with the SMTP email provider. Use the value copied from your Mailgun account.
   - `SMTP_PASSWORD`: The password to use to authenticate with the SMTP email provider. Use the value copied from your Mailgun account.
   - `SMTP_SECURE`: Whether to use TLS/SSL when sending emails. Set this to `true`.
   - `SMTP_FROM_ADDRESS`: The address that will be used in the `from` field when sending emails. Set this to your preferred email address. Using `infisical@{{ KOYEB_PUBLIC_DOMAIN }}` will automatically use your Infisical instance's public domain name.
   - `SMTP_FROM_NAME`: The human-readable name to use as the sender when sending emails. Choose your preferred name.
   - `TELEMETRY_ENABLED`: Whether telemetry is enabled on your Infisical instance. Set this to `true` or `false` according to your preference.
   - `ENCRYPTION_KEY`: Used for platform encryption and decryption operations. Generate an appropriate key by running `openssl rand -hex 16` locally.
   - `AUTH_SECRET`: This key is used to sign JSON Web Tokens (JWT). Generate an appropriate key by running `openssl rand -base64 32` locally.

4. In the **Instance** section, select the **Eco** category and choose **eMedium** or larger. The [Infisical Docker Hub page](https://hub.docker.com/r/infisical/infisical) recommends 1 CPU and 2GB of RAM at a minimum.
5. In the **App and Service names** section, set your App and Service name to your desired values. The App name will be used as a component in your public Koyeb URL, which uses the following format: `https://<APP_NAME>-<ORG_NAME>-<HASH>.koyeb.app`.
6. Click **Deploy**.

Koyeb will pull the image from Docker Hub and run it with the configuration you provided.

<Banner
  title="Blazing-Fast Deployments"
  description="Enjoy automatic continuous deployment, global load balancing, real-time metrics and monitoring, autoscaling, and more when your services run on Koyeb."
  type="claim-free"
  buttonText="Deploy Now"
  buttonLink="https://app.koyeb.com/"
/>

## Create an administration account

Once the deployment is complete, access your Infisical instance by visiting your Koyeb deployment URL. The application URL should have the following format:

```
https://<YOUR_APP_NAME>-<YOUR_KOYEB_ORG>-<HASH>.koyeb.app
```

You will be directed to a form to create an initial administration account for your instance:

![Infisical admin account creation](https://www.koyeb.com/static/images/tutorials/infisical/create-admin-account.png)

Fill out your information and click **Continue** to proceed.

You will be prompted to download recovery information that will allow you to recover your account if you get locked out of your account:

![Infisical download emergency kit](https://www.koyeb.com/static/images/tutorials/infisical/download-emergency-kit.png)

Click **Download PDF** to continue.

Next, you'll be taken to the Infisical's admin dashboard:

![Infisical admin dashboard](https://www.koyeb.com/static/images/tutorials/infisical/admin-dashboard.png)

It is a good idea to either disable sign ups or to restrict sign ups to certain email domains if your organization provides email accounts for your own domain.

Click **Save** when you are finished configuring Infisical's sign up behavior.

## Configure a project and secrets

To access the regular Infisical interface, click **Back to organization** in the upper-left corner. This will take you to the organization's overview page:

![Infisical overview page](https://www.koyeb.com/static/images/tutorials/infisical/overview-page.png)

To get started using Infisical, create a new project by clicking **Add New Project**:

![Infisical create new project](https://www.koyeb.com/static/images/tutorials/infisical/create-new-project.png)

Fill out a name and add members to the project. Click **Create Project** when you are finished.

You will be redirected to the workspace for your new project:

![Infisical new project workspace](https://www.koyeb.com/static/images/tutorials/infisical/new-project-workspace.png)

Click **Add Secrets** to add a new secret. Choose the key and value as well as the environments it should be accessible in:

![Infisical create new secret](https://www.koyeb.com/static/images/tutorials/infisical/create-new-secret.png)

Click **Create Secret** when you are finished. You should see the secret you created and an indication of what environments it is accessible from:

![Infisical new secret status](https://www.koyeb.com/static/images/tutorials/infisical/new-secret-status.png)

Here, we can see that our secret has only been configured for our project's development environment. To add different values to your other environments, click on the **secret table row** to expand it:

![Infisical expand secret environments](https://www.koyeb.com/static/images/tutorials/infisical/expand-secret-environments.png)

From here, you can add different values for your various environments. Click the **Check marks** associated with each environment to save the values you enter:

![Infisical add secret values for other environments](https://www.koyeb.com/static/images/tutorials/infisical/add-values-for-different-envs.png)

## Access secrets for your applications

With secrets configured for your environments, you can now use Infisical to provide those values to your application environments during deployment. Infisical offers [many integrations](https://infisical.com/docs/integrations/overview) that you can use to inject secrets into your applications.

As a simple demonstration, we'll use the [Infisical CLI](https://infisical.com/docs/cli/overview) to retrieve secrets for various environments and make them available to applications. Install the CLI according to the instructions available for your platform.

When you are ready, authenticate to your Infisical instance by typing:

```bash
infisical login
```

When prompted, select **Self Hosting**. Paste the public domain of your Infisical instance when prompted. Infisical will open a browser tab and, assuming you are already logged in, prompt you to choose your organization to confirm the authentication.

Next, navigate to your project's directory. If you don't have a project and simply want to test the CLI, you can navigate to the `/tmp` directory. Initialize Infisical in the project directory by typing:

```bash
infisical init
```

Select the **Infisical organization** that your project is a part of when prompted (this will be "Admin Org" unless you changed it). Afterwards, select the project you created ("Koyeb" in our example).

The Infisical CLI created an `.infisical.json` file in the current directory with information about the Infisical project that should be used in this context. Now, we can retrieve secrets by typing:

```bash
infisical secrets
```

The output will show you the secrets and values declared for the development environment by default:

```
┌─────────────┬──────────────┬─────────────┐
│ SECRET NAME │ SECRET VALUE │ SECRET TYPE │
├─────────────┼──────────────┼─────────────┤
│ MY_SECRET   │ surprise!    │ shared      │
└─────────────┴──────────────┴─────────────┘
```

You can get the values for other environments by passing the `--env` flag with `prod` or `staging`:

```bash
infisical secrets --dev prod
```

The output will reflect the appropriate value for the specified environment:

```
┌─────────────┬──────────────────────────┬─────────────┐
│ SECRET NAME │ SECRET VALUE             │ SECRET TYPE │
├─────────────┼──────────────────────────┼─────────────┤
│ MY_SECRET   │ serious production value │ shared      │
└─────────────┴──────────────────────────┴─────────────┘
```

To format the secrets for your applications, use the `export` command instead:

```bash
infisical export
```

By default, it formats the secrets using the `.env` file format:

```ini
MY_SECRET='surprise!'
```

You can choose an alternative format by passing the `--format` flag with `dotenv` (the default), `json`, or `csv`:

```bash
infisical export --format json
```

When piped to `jq`, the output would now include a JSON object with some additional metadata:

```json
[
  {
    "key": "MY_SECRET",
    "workspace": "",
    "value": "surprise!",
    "type": "shared",
    "_id": "d1c53fcd-f724-478b-a80e-80c1f72ebe10",
    "tags": [],
    "comment": ""
  }
]
```

You can again pass the `--env` flag to get values for other environments.

To run an application with your environment, you can use the `infisical run` command. To demonstrate, create a simple shell script called `test.sh` in your current directory. Inside, enter the following:

```bash
#!/usr/bin/env bash

echo "My secret value is: ${MY_SECRET}"
```

Make the script executable and the Infisical command line can run your script directly with:

```bash
chmod +x test.sh
infisical run --env=prod -- ./test.sh
```

You should see the results as expected:

```
My secret value is: serious production value
```

<Banner
  title="No StressOps"
  description="Run your services on the best serverless platform and enjoy the built-in CI/CD pipeline, global load balancing, real-time metrics and monitoring, autoscaling, and more."
  type="claim-free"
  buttonText="Deploy Now"
  buttonLink="https://app.koyeb.com/"
/>

## Conclusion

In this guide, we showed how to set up an Infisical instance in production to manage your secret and configuration data for applications and users. We provisioned a PostgreSQL database to store application data and a Redis instance to handle sessions. We also set up SMTP email so that Infisical can send emails for various user account flows.

While we primarily demonstrated how to work with Infisical using their provided command line client, their vast [collection of integrations](https://infisical.com/docs/integrations/overview) allows for easier access in many cases. As you incorporate Infisical into your environment, take a look at the available providers to learn how to connect seamlessly with your applications.