How to Deploy Directus as a Backend-as-a-Service (BaaS) on Koyeb
Tags: webdev, tutorial, opensource, api
Published: 2024-04-25 15:32:53

[Directus](https://directus.io/) is an open data platform built to serve as a headless CMS, API, or Backend-as-a-Service (BaaS) for other applications. It is designed to make data accessible to people of all technical levels and to make it easy to build data-centric applications. Directus is extensible and can be integrated with many different frontend technologies to create stable, well-structured development and user experiences.

In this tutorial, we will show how to deploy Directus to Koyeb to enable you to build your own data backend. To ensure that our deployment is both scalable and resilient, we will configure Directus to use a number of accompanying components and services. We will deploy an external PostgreSQL database for long-term data persistence, an S3-compatible object storage bucket for storing uploads and images, and a Redis database for caching and to help our application stay in sync even when scaled to multiple instances.

You can deploy the application from this guide with [our Directus One-Click app](https://www.koyeb.com/deploy/directus) or by clicking the [Deploy to Koyeb button](https://www.koyeb.com/docs/build-and-deploy/deploy-to-koyeb-button) below:

[![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?name=directus&type=docker&image=directus%2Fdirectus&instance_type=small&env%5BADMIN_EMAIL%5D=CHANGE_ME&env%5BADMIN_PASSWORD%5D=CHANGE_ME&env%5BCACHE_AUTO_PURGE%5D=true&env%5BCACHE_ENABLED%5D=true&env%5BCACHE_STORE%5D=redis&env%5BDB_CLIENT%5D=pg&env%5BDB_CONNECTION_STRING%5D=CHANGE_ME&env%5BKEY%5D=CHANGE_ME&env%5BPUBLIC_URL%5D=CHANGE_ME&env%5BREDIS%5D=CHANGE_ME&env%5BSECRET%5D=CHANGE_ME&env%5BSTORAGE_S3_BUCKET%5D=CHANGE_ME&env%5BSTORAGE_S3_DRIVER%5D=s3&env%5BSTORAGE_S3_ENDPOINT%5D=CHANGE_ME&env%5BSTORAGE_S3_KEY%5D=CHANGE_ME&env%5BSTORAGE_S3_REGION%5D=CHANGE_ME&env%5BSTORAGE_S3_SECRET%5D=CHANGE_ME&env%5BSTORAGE_LOCATIONS%5D=s3&env%5BSYNCHRONIZATION_STORE%5D=redis&ports=8055%3Bhttp%3B%2F)

Be sure to modify all of the environment variables values set to `CHANGE_ME` to reflect your own data. You can consult the information in this guide if you need additional information.

## Requirements

To successfully follow and complete this guide, you need:

- A [Koyeb account](https://app.koyeb.com) to provision the PostgreSQL database and the Directus application.
- A [Backblaze B2](https://www.backblaze.com/cloud-storage) account to create an S3-compatible object storage bucket.
- An [Aiven Redis instance](https://aiven.io/redis) to cache data and synchronize between Directus instances. This is optional if you only plan on running a single Directus instance, but helps with performance and reliability.

## Steps

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

1. [Provision a PostgreSQL database on Koyeb](#provision-a-postgre-sql-database-on-koyeb)
2. [Provision a Backblaze B2 object storage bucket](#provision-a-backblaze-b2-object-storage-bucket)
3. [Provision a Redis instance on Aiven (Optional)](<#provision-a-redis-instance-on-aiven-(optional)>)
4. [Deploy Directus to Koyeb](#deploy-directus-to-koyeb)

## Provision a PostgreSQL database on Koyeb

Before we can deploy Directus, we need to provision a PostgreSQL database that we can use to persist application data including data collections, user data, and API configuration. We will use [Koyeb's PostgreSQL service](https://www.koyeb.com/docs/databases) which includes a free tier that we can use to get started.

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 on the `.env` option of the **Connection Details** tab. Click the **copy icon** to save the connection details for later.

## Provision a Backblaze B2 object storage bucket

By default, Directus will store uploads and other file objects on the local filesystem where the application is running. In a serverless environment, this storage is ephemeral and would be lost when redeploying or reconfiguring the application. To avoid this, we will configure Directus to store these objects in an external object storage bucket. We will use Backblaze B2 for this.

To create an object storage bucket for Directus, log into your [Backblaze account](https://secure.backblaze.com/user_signin.htm) and follow these steps:

1. In the **B2 Cloud Storage** section on the left side of the dashboard, click **Buckets**.
2. Click **Create a Bucket** to begin configuring a new bucket.
3. Choose a name for the bucket. This must be globally unique, so choose a name not likely to be used by another user.
4. Set the bucket privacy to **Private**.
5. Use the provided defaults for the rest of the settings.
6. Click **Create a Bucket** to create the new bucket.

Copy and save the following information about your new bucket. You'll need it later to configure Directus:

| Backblaze B2 item | Example value                       |
| ----------------- | ----------------------------------- |
| Bucket name       | `some-bucket-name`                  |
| Endpoint          | `s3.eu-central-003.backblazeb2.com` |

Now that you have a bucket, you need to create API credentials so that Directus can authenticate to Backblaze as well as upload and manage objects:

1. In the **Account** section on the left side of the dashboard, click **Application Keys**.
2. Under **Your Application Keys**, click **Add a New Application Key** to begin configuring a new key.
3. Select a name for your key to help you identify it more easily.
4. Select the bucket you just created in the **Allow access to Bucket(s)** drop-down menu.
5. Select **Read and Write** as the access type.
6. Leave the remaining fields blank to accept the default policies.
7. Click **Create New Key** to generate the new key to manage your bucket.

Copy and save the following information related to your new API key. You'll need it to properly authenticate to your Backblaze account and perform object operations:

| Backblaze B2 item | Example value                     |
| ----------------- | --------------------------------- |
| `keyID`           | `008c587cb98cb3d0000000003`       |
| `applicationKey`  | `K002cbYLV/CkW/x+28zsqmpbIAtdzMM` |

## Provision a Redis instance on Aiven (Optional)

If you plan on scaling to multiple Directus instances, or if performance is an important factor, you can optionally configure a Redis database for caching and state synchronization. For this, we will use [Aiven Redis](https://aiven.io/redis).

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 Directus.
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.

## Deploy Directus to Koyeb

Now that we have the connection details for the PostgreSQL database, object storage bucket, and Redis instance, we can deploy Directus 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. Set the **Docker image** to `docker.io/directus/directus`. Optionally, append an [image tag](https://hub.docker.com/r/directus/directus/tags) if you'd like to deploy a specific version.
3. At the bottom of the page, in the **App and Service names** section, choose a name for your App and Service. Your App name will be a component of the public URL for your Service, using the following format: `https://<YOUR_APP_NAME>-<YOUR_KOYEB_ORG>.koyeb.app`.
4. In the **Environment variables** section, click **Bulk edit** to enter multiple environment variables at once. In the text box that appears, paste the following:

   ```
   KEY=
   SECRET=
   DB_CLIENT="pg"
   DB_CONNECTION_STRING=
   STORAGE_LOCATIONS="s3"
   STORAGE_S3_DRIVER="s3"
   STORAGE_S3_KEY=
   STORAGE_S3_SECRET=
   STORAGE_S3_BUCKET=
   STORAGE_S3_ENDPOINT=
   STORAGE_S3_REGION=
   REDIS=
   CACHE_ENABLED="true"
   CACHE_AUTO_PURGE="true"
   CACHE_STORE="redis"
   SYNCHRONIZATION_STORE="redis"
   PUBLIC_URL=
   ADMIN_EMAIL=
   ADMIN_PASSWORD=
   ```

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

   - `KEY`: A unique string that serves as an identifier for the current project. Set to a random number (for example, generated by `openssl rand -base64 24`).
   - `SECRET`: A unique string used to sign JSON web tokens for authentication. Set to a random number (for example, generated by `openssl rand -base64 24`).
   - `DB_CLIENT`: Set to `pg` to indicate a PostgreSQL database.
   - `DB_CONNECTION_STRING`: Set to your PostgreSQL connection string, with `?sslmode=require` appended to the end.
   - `STORAGE_LOCATIONS`: A name for the storage location to be configured. This will be used as part of the other variables used to configure it. Use `s3` here.
   - `STORAGE_S3_DRIVER`: The driver to use for the storage location. Set this to `s3`.
   - `STORAGE_S3_KEY`: The API key ID for authenticating to Backblaze.
   - `STORAGE_S3_SECRET`: The API key secret for authenticating to Backblaze.
   - `STORAGE_S3_BUCKET`: The name of your Backblaze B2 bucket.
   - `STORAGE_S3_ENDPOINT`: The Backblaze B2 endpoint URL. This should look something like `s3.eu-central-003.backblazeb2.com`.
   - `STORAGE_S3_REGION`: The name of the region where your Backblaze B2 bucket can be accessed. This is part of the endpoint URL. For the above endpoint, the region would be `eu-central-003`.
   - `REDIS`: The connection string for the Redis store. If you do not plan on running multiple Directus containers, you can optionally remove this requirement.
   - `CACHE_ENABLED`: Set to `true` to enable caching.
   - `CACHE_AUTO_PURGE`: Set to `true` to automatically purge cache when data is manipulated.
   - `CACHE_STORE`: Set to `redis` if using a Redis store. Set to `memory` if you are not using Redis.
   - `SYNCRHONIZATION_STORE`: Set to `redis` if using a Redis store. Set to `memory` if you are not using Redis.
   - `PUBLIC_URL`: Set to the public URL where the Directus service will run. Set to the Koyeb public URL for your service, which will use the following format: `https://<YOUR_APP_NAME>-<YOUR_KOYEB_ORG>.koyeb.app`.
   - `ADMIN_EMAIL`: Set to the email you wish to use to authenticate to the Directus admin account.
   - `ADMIN_PASSWORD`: Set to the password you wish to use to authenticate to the Directus admin account.

5. In the **Instance** section, select size **eco-micro** or larger. According to the [Directus documentation](https://docs.directus.io/self-hosted/docker-guide.html#requirements), the `eco-micro` Instance provides the minimum amount of resources required to run Directus. The `small` Instance includes the recommended resources.
6. If you wish to scale to more than one instance, adjust the scale values in the **Scaling** section.
7. In the **Exposed ports** section, change the **Port** value that the Service will run on to **8055**, the default port for Directus.
8. Click **Deploy**.

Koyeb will pull the Directus Docker image from Docker Hub and deploy it using the configuration you provided. During the deployment process, Directus will connect to the PostgreSQL database and initialize it to create the necessary data structures. It will perform similar preparatory steps to configure the object storage and Redis components.

Once the deployment is healthy, visit your Koyeb Service's subdomain (you can find this on your Service's detail page). It will have the following format:

```
https://<YOUR_APP_NAME>-<KOYEB_ORG_NAME>.koyeb.app
```

You will be redirected to the Directus login page. Enter the admin email address and password you provided as environment variables to authenticate.

## Conclusion

In this guide, we showed how to deploy and configure Directus on Koyeb to create a data backend for applications. We provisioned a PostgreSQL database to store persistent data, an object storage bucket to manage user uploads and other file-type objects, and a Redis instance to synchronize state between Directus instances and cache content. We deployed Directus using a configuration that'll allow us to scale out as needed in the future, providing our applications, sites, and clients with a reliable, easy-to-manage data backend.

We've left off on this tutorial with a functional Directus instance that you can integrate with your projects. To get started, consider walking through the [Directus Quickstart Guide](https://docs.directus.io/getting-started/quickstart.html) which shows how to create collections, configure data fields and items, and manage roles and permissions to make your data public. If you'd like to further customize your Directus service, take a look at the [Directus configuration options](https://docs.directus.io/self-hosted/config-options.html) in the documentation.