You can self-host Trigger.dev on your own infrastructure.
The self-hosting guide covers two alternative setups. The first option uses a simple setup where you run everything on one server. With the second option, the webapp and worker components are split on two separate machines.
You’re going to need at least one Debian (or derivative) machine with Docker and Docker Compose installed. We’ll also use Ngrok to expose the webapp to the internet.
It’s dangerous to go alone! Join the self-hosting channel on our Discord server.
This guide outlines a quick way to start self-hosting Trigger.dev for evaluation purposes - it won’t result in a production-ready deployment. Security, scaling, and reliability concerns are not fully addressed here.
As self-hosted deployments tend to have unique requirements and configurations, we don’t provide specific advice for securing your deployment, scaling up, or improving reliability.
Should the burden ever get too much, we’d be happy to see you on Trigger.dev cloud where we deal with these concerns for you.
Please consider these additional warnings
docker-provider
does not currently enforce any resource limits. This means your tasks can consume up to the total machine CPU and RAM. Having no limits may be preferable when self-hosting, but can impact the performance of other services.You will also need a way to expose the webapp to the internet. This can be done with a reverse proxy, or with a service like Ngrok. We will be using the latter in this guide.
This is the simplest setup. You run everything on one server. It’s a good option if you have spare capacity on an existing machine, and have no need to independently scale worker capacity.
Some very basic steps to get started:
On a Debian server, you can run these commands
Alternatively, you can follow these manual steps after cloning the docker repo:
.env
fileReplace the default secrets in the .env
file with the generated ones
Run docker compose to start the services
You will need to expose the webapp to the internet. You can use Ngrok for this. If you already have a working reverse proxy setup and a domain, you can skip to the last step.
Copy the domain from the output, for example: 1234-42-42-42-42.ngrok-free.app
Uncomment the TRIGGER_PROTOCOL
and TRIGGER_DOMAIN
lines in the .env
file. Set it to the domain you copied.
If you want to deploy v3 projects, you will need access to a Docker registry. The CLI deploy command will push the images, and then the worker machine can pull them when needed. We will use Docker Hub as an example.
Sign up for a free account at Docker Hub
Edit the .env
file and add the registry details
docker-provider
container so it can pull deployment images to run your tasks.With this setup, the webapp will run on a different machine than the worker components. This allows independent scaling of your workload capacity.
All steps are the same as for a single server, except for the following:
webapp
argument.env
file from the webapp to the worker machine:worker
argumentTunnelling. This is not required for the worker components.
Registry setup. Follow the registry setup section but run the last command on the worker machine - note the container name is different:
By default, payloads over 512KB will be offloaded to S3-compatible storage. If you don’t provide the required env vars, runs with payloads larger than this will fail.
For example, using Cloudflare R2:
Alternatively, you can increase the threshold:
There are several reasons to lock the version of your Docker images:
By default, the images will point at the latest versioned release via the v3
tag. You can override this by specifying a different tag in your .env
file. For example:
By default, magic link auth is the only login option. If the EMAIL_TRANSPORT
env var is not set, the magic links will be logged by the webapp container and not sent via email.
Depending on your choice of mail provider/transport, you will want to configure a set of variables like one of the following:
Note that setting SMTP_SECURE=false
does not mean the email is sent insecurely.
This simply means that the connection is secured using the modern STARTTLS protocol command instead of implicit TLS.
You should only set this to true when the SMTP server host directs you to do so (generally when using port 465)
Credentials are to be supplied as with any other program using the AWS SDK.
In this scenario, you would likely either supply the additional environment variables AWS_REGION
, AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
or, when running on AWS, use credentials supplied by the EC2 IMDS.
All email addresses can sign up and log in this way. If you would like to restrict this, you can use the WHITELISTED_EMAILS
env var. For example:
It’s currently impossible to restrict GitHub OAuth logins by account name or email like above, so this method is not recommended for self-hosted instances. It’s also very easy to lock yourself out of your own instance.
Your GitHub OAuth app needs a callback URL https://<your_domain>/auth/github/callback
and you will have to set the following env vars:
This requires an experimental Docker feature. Successfully checkpointing a task today, does not mean you will be able to restore it tomorrow. Your data may be lost. You’ve been warned!
Checkpointing allows you to save the state of a running container to disk and restore it later. This can be useful for long-running tasks that need to be paused and resumed without losing state. Think fan-out and fan-in, or long waits in email campaigns.
The checkpoints will be pushed to the same registry as the deployed images. Please see the registry setup section for more information.
Underneath the hood this uses Checkpoint and Restore in Userspace, or CRIU in short. We’ll have to do a few things to get this working:
/etc/docker/daemon.json
FORCE_CHECKPOINT_SIMULATION=0
in your .env
file. Alternatively, run this:Once you have everything set up, you will periodically want to update your Docker images. You can easily do this by running the update script and restarting your services:
Sometimes, we will make more extensive changes that require pulling updated compose files, scripts, etc from our docker repo:
Occasionally, you may also have to update your .env
file, but we will try to keep these changes to a minimum. Check the .env.example
file for new variables.
If you’re coming from the beta CLI package images, you will need to:
git stash
.git checkout main
in your docker repo.git pull
to get the latest updates.git stash pop
../update.sh
to pull them../stop.sh && ./start.sh
and you’re good to go.In summary, run this wherever you cloned the docker repo:
deploy
needs registry access:docker-provider
needs registry access:This section highlights some of the CLI commands and options that are useful when self-hosting. Please check the CLI reference for more in-depth documentation.
To avoid being redirected to the Trigger.dev Cloud login page when using the CLI, you can specify the URL of your self-hosted instance with the --api-url
or -a
flag. For example:
Once you’ve logged in, the CLI will remember your login details and you won’t need to specify the URL again with other commands.
You can specify a custom profile when logging in. This allows you to easily use the CLI with our cloud product and your self-hosted instance at the same time. For example:
You can then use this profile with other commands:
To list all your profiles, use the list-profiles
command:
It can be useful to check you have successfully logged in to the correct instance. You can do this with the whoami
command, which will also show the API URL:
On Trigger.dev Cloud, we build deployments remotely and push those images for you. When self-hosting you will have to do that locally yourself. This can be done with the --self-hosted
and --push
flags. For example:
When running the CLI in a CI environment, your login profiles won’t be available. Instead, you can use the TRIGGER_API_URL
and TRIGGER_ACCESS_TOKEN
environment
variables to point at your self-hosted instance and authenticate.
For more detailed instructions, see the GitHub Actions guide.
By default, the Trigger.dev webapp sends telemetry data to our servers. This data is used to improve the product and is not shared with third parties. If you would like to opt-out of this, you can set the TRIGGER_TELEMETRY_DISABLED
environment variable in your .env
file. The value doesn’t matter, it just can’t be empty. For example: