Prod Deploy

This page covers a production-ready deployment that requires multiple servers. If you want to deploy Hyvor Relay for hobby or small to medium-sized projects (less than 1,000,000 emails/day without high availability), refer to the Easy Deploy page.

Overview

By the end of this guide, you will have a production-ready Hyvor Relay deployment with the following characteristics:

  • Multiple app servers: One or more app servers running Hyvor Relay in a Docker Swarm cluster. Email sending is load balanced across the app servers.
  • Multiple IP Addresses: Each app server has one or more dedicated IP addresses for sending emails. Each IP address is assigned to a queue that sends transactional or distributional emails (user-dedicated queues are coming soon).
  • Dedicated PostgreSQL server: A dedicated PostgreSQL server for the database and email queue.

PostgreSQL

Hyvor Relay uses PostgreSQL as the database and also as the message queue. Set up a PostgreSQL server in a production-ready manner. Hyvor Relay has been tested with PostgreSQL 18. If your cloud provider offers a managed PostgreSQL service, feel free to use it. It will make backups, failover, and scaling easier. Otherwise, set up a dedicated PostgreSQL server.

Since setting up a PostgreSQL server depends a bit on how your infrastructure is set up, we will not go into details here. Whichever option you choose, make sure that:

  • A dedicated database is created for Hyvor Relay. Recommended name: hyvor_relay.
    CREATE DATABASE hyvor_relay;
  • A dedicated user is created with all privileges on the Hyvor Relay database and a strong password.
    CREATE USER relay_servers WITH ENCRYPTED PASSWORD 'strong_password';
    GRANT ALL PRIVILEGES ON DATABASE hyvor_relay TO relay_servers;
  • Configured to allow connections from the app servers (ideally via a private network).
    # In pg_hba.conf
    host    hyvor_relay    relay_servers xx.xx.xx.xx/yy    scram-sha-256
  • Backup strategies are in place.

App Servers

How many servers?

The number of app servers you need depends on your expected email volume. Here are some rough guidelines, which are mostly on the safer side:

Servers
Expected Email Volume
1 server, 4GB RAM, 2 CPUs
1,000,000 emails/day
2 servers, 8GB RAM, 4 CPUs
10,000,000 emails/day

See the Scaling page has more details on other factors that affect the number of servers you need.

How many IP addresses?

A queue is responsible for sending emails. By default, each project is assigned to the "transactional" or "distributional" queue based on the project type. Each queue has one or more IP addresses assigned to it. When an email is sent via a queue, one of the IP addresses assigned to that queue is used as the source IP address.

Why does this matter? Because email providers track the reputation of IP addresses. If, for some reason, an IP address gets blacklisted, only the emails sent via that IP address are affected. You can easily remove that IP address from the queue and add a new one without affecting the other IP addresses.

Therefore, we recommend having at least 2 IP addresses per queue (there are 2 default queues - "transactional" and "distributional") for production deployments.

OpenID Connect (OIDC) Provider

Hyvor Relay relies on OIDC for authentication. Create an application for Hyvor Relay in our OIDC provider. Make sure to allow the following URLs in your OIDC provider:

  • Callback URL: https://your-web-url/api/oidc/callback
  • Logout URL: https://your-web-url

Once the web domain is configured in the next steps, you can change the URLs to use the domain instead of the IP address.

Server Requirements

  • Hardware: Each server with at least 4GB RAM and 2 vCPUs. More resources may be needed based on your expected email volume.
  • Operating System: A Linux-based operating system. Hyvor Relay is tested on Ubuntu 24.04 LTS in production.
  • Private Network (optional but recommended): A private network between the app servers and the PostgreSQL server. If available, you can use this to advertise Docker Swarm nodes and connect to the PostgreSQL server securely.

Server Setup

1. Install Docker

Follow the official Docker installation guide for your Linux distribution: https://docs.docker.com/engine/install/

2. Create a Docker Swarm

On one of the app servers, run the following command to initialize the Docker Swarm cluster:

docker swarm init --advertise-addr <MANAGER-PRIVATE-IP-ADDRESS>

You will see a command to join other nodes to the swarm. Run that command on the other app servers to add them to the swarm.

docker swarm join --token <TOKEN> <MANAGER-PRIVATE-IP-ADDRESS>:2377

Finally, run docker node ls on the manager node to verify that all nodes have joined the swarm.

3. .env Configuration

First, SSH into the manager node and download the deployment files (view on Github).

curl -LO https://github.com/hyvor/relay/releases/latest/download/deploy.tar.gz
tar -xzf deploy.tar.gz
cd deploy/prod

deploy/prod directory contains two files:

.env 			 	# Environment variables
compose.yaml			# Docker Compose file

Edit the .env file to set the following variables:

  • APP_SECRET: A strong random string. You can generate one using the following command:
    openssl rand -base64 32
  • DATABASE_URL: Set this to point to your PostgreSQL server.
  • WEB_URL: The public URL where Hyvor Relay and its API will be accessible. Example: https://relay.yourdomain.com
  • INSTANCE_DOMAIN: The dedicated domain name used for the incoming mail server, EHLO identification, and PTR records. Example: mail.relay.yourdomain.com. Must be different from the Web URL.
  • OIDC_ISSUER_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET: Set these variables based on your OIDC provider configuration.
Important: Do not add quotes around the values in the .env file ( Docker Swarm bug)

Then, run the following command to verify that the configuration is correct:

docker compose run --rm relay bin/console verify

4. Deploy Hyvor Relay

Start the Hyvor Relay service:

docker stack deploy -c compose.yaml relay

To verify that the service is running, use:

docker service ls

Check logs to make sure everything is working correctly:

# on each server
docker ps
docker logs -f <CONTAINER_ID>

You should see the logs indicating that the application has run migrations, configured the server and the IP addresses, and started the application (email workers, webhook workers, etc.).

Setup

Next, head to the Setup page to continue the setup process.

Things to know

App Secret

The APP_SECRET variable is a 32-bytes key used to encrypt sensitive data (e.g., API keys, tokens) in the application. You should not change this value after the initial setup, as it will invalidate existing encrypted data. Key rotation is not supported yet, but planned.

Host Network

The application uses the host network mode to bind to the server's IP addresses directly. This allows Hyvor Relay to control the IP addresses used for sending emails. Other network modes (e.g., bridge, overlay) are not supported.