DeployAngel

Docs

Get started

DeployAngel watches each Rails deploy in production and tells you when it's safe to stop watching. Setup takes a few minutes: add the gem, give it a token, and deploy as usual. It works with Rails 7.1 or later on Ruby 3.1 or later, wherever the app runs.

1. Install the agent

  1. Create an account and an app, then create its app token. The setup checklist has a button for it, or use Settings, API tokens, "Deployed application".
  2. Add the gem, and run bundle install:
# Gemfile
gem "deployangel"

Then set the token as DEPLOYANGEL_TOKEN in the app's environment, on every process: web servers and job workers. The next section shows how for your host.

Each process sends one small summary a minute: request and job counts, response times, and exceptions with their details cleaned of IDs and values. It never sends request bodies, cookies, parameters, or records from your database. See the privacy policy for exactly what's collected. If DeployAngel is ever unreachable, your app keeps running normally.

2. Set it up where your app runs

DeployAngel needs to know which release each process is running. On most hosts, the agent works it out with no setup.

Heroku

The easiest way is the DeployAngel add-on, which sets the token and registers every release for you. Without the add-on:

heroku config:set DEPLOYANGEL_TOKEN=da_live_…
heroku labs:enable runtime-dyno-metadata

Dyno metadata tells the agent which release it's running. Then connect Heroku in the app's Settings, under Integrations, so every release is registered, including config changes and rollbacks. Heroku's Dev Center article covers the add-on in detail.

Kamal

Pass the token to the app through Kamal's secrets:

# .kamal/secrets
DEPLOYANGEL_TOKEN=$DEPLOYANGEL_TOKEN

# config/deploy.yml
env:
  secret:
    - DEPLOYANGEL_TOKEN

The agent reads the release from KAMAL_VERSION, which Kamal sets in every container. To register each deploy and link it to your CI run, add a post-deploy hook:

bundle exec deployangel install kamal

It writes .kamal/hooks/post-deploy, or, if you already have one, tells you the line to add. The hook needs a "CI deploys" token in DEPLOYANGEL_API_TOKEN wherever you run kamal deploy, and it never fails a deploy. Without it, DeployAngel still notices each new release.

Render

In the Render dashboard, add DEPLOYANGEL_TOKEN to the service's environment variables. That's all: the agent reads the release from RENDER_GIT_COMMIT, which Render sets, and DeployAngel notices each new release when the agent reports it.

Fly.io

fly secrets set DEPLOYANGEL_TOKEN=da_live_…

The agent uses the image tag Fly.io gives each deploy as the release. Fly.io doesn't tell the app its commit, so to see what changed in each release, pass it in when you build:

# Dockerfile
ARG GIT_SHA
ENV DEPLOYANGEL_REVISION=$GIT_SHA

# when deploying
fly deploy --build-arg GIT_SHA=$(git rev-parse HEAD)

Railway, Coolify, and Dokku

Add DEPLOYANGEL_TOKEN to the app's environment variables. That's all: the agent reads the commit from RAILWAY_GIT_COMMIT_SHA on Railway, SOURCE_COMMIT on Coolify, or GIT_REV on Dokku, and DeployAngel notices each new release. On Railway, a deploy that didn't come from GitHub, such as railway up, is identified by its deployment ID instead.

Docker: compose, Swarm, ECS, Kubernetes

The agent runs inside your app's process, so containers work like any other host. Plain Docker doesn't tell the app which commit it's running, and .dockerignore usually leaves .git out of the image, so bake the commit in when you build:

# Dockerfile
ARG GIT_SHA
ENV DEPLOYANGEL_REVISION=$GIT_SHA

# when building
docker build --build-arg GIT_SHA=$(git rev-parse HEAD) .

Then set DEPLOYANGEL_TOKEN in the container's environment: under environment: in compose, in an ECS task definition, or from a Kubernetes Secret. Web and worker containers built from the same image report the same release, and each container counts as its own instance, merged every minute.

Capistrano

Set DEPLOYANGEL_TOKEN in the app's environment on each server, for example in its .env file or systemd unit. The agent reads the release from the REVISION file Capistrano writes. To register each deploy, add one line to the Capfile:

# Capfile
require "deployangel/capistrano"

and set DEPLOYANGEL_API_TOKEN (a "CI deploys" token) wherever you run cap. To make cap wait for the release's first check, and exit with an error if it fails, add set :deployangel_wait, "initial" to config/deploy.rb.

Anywhere else: AWS, DigitalOcean, a VPS

Without containers, set both in the app's environment:

DEPLOYANGEL_TOKEN=da_live_…
DEPLOYANGEL_REVISION=<the deployed commit>

On DigitalOcean App Platform, use DEPLOYANGEL_REVISION: ${_self.COMMIT_HASH} in the app spec. Writing the commit to a REVISION file in the app's root at build time works too.

3. How deploys are registered

You don't have to do anything: when the agent first reports a new release, DeployAngel registers the deploy and starts verifying it. The releases running when you install the agent are the baseline, so the next deploy gets the first verdict.

Registering deploys from CI is optional. It labels each release with the CI run, links back to it, and starts verification as soon as the deploy finishes. Create a "CI deploys" token, save it as a secret, and run deployangel release after deploying:

# .github/workflows/deploy.yml, after the deploy step
- run: bundle exec deployangel release
  env:
    DEPLOYANGEL_API_TOKEN: ${{ secrets.DEPLOYANGEL_API_TOKEN }}

In GitHub Actions, GitLab CI, CircleCI, and Buildkite, it fills in the commit, the run, and the link by itself. Elsewhere, pass --commit=$GIT_SHA. Redeploying a commit that's already been deployed isn't a new release, so register it if you want it verified again.

4. Staging

Add staging as an environment of the same app in the dashboard. It gets its own token and its own verdicts, and its notifications are quiet by default. The agent only reports from RAILS_ENV=production, so if staging runs with a different environment, also set DEPLOYANGEL_ENABLED=true there.

5. Wait for a verdict in CI or a coding agent

With a "CI deploys" or "CLI & coding agents" token in DEPLOYANGEL_API_TOKEN, the CLI waits for a release's verdict and exits with a code a pipeline can act on:

bundle exec deployangel verify --wait --until=initial

Coding agents can use the same evidence through DeployAngel's MCP server:

claude mcp add deployangel -- bundle exec deployangel mcp

6. Troubleshooting

"The agent doesn't say which release it's running"

The agent is reporting, but couldn't find its release, so nothing it sends can be tied to a deploy. Set DEPLOYANGEL_REVISION to the deployed commit, or follow the steps for your host above. On Heroku, enable dyno metadata. If only some processes are affected, it's usually a job worker missing the setting.

The app page says "Agent hasn't reported yet"

Check that DEPLOYANGEL_TOKEN is set on every process, that the app runs with RAILS_ENV=production (or set DEPLOYANGEL_ENABLED=true), and that it can reach https://api.deployangel.com.

A release is stuck waiting for its first telemetry

The release DeployAngel was told about doesn't match the one the agent reports. Make sure your CI registers the same commit the app runs, for example --commit=$GIT_SHA from the build that was deployed.

Nobody gets notification emails

Team emails go only to members who have verified their email address and haven't turned team emails off in their profile. If the dashboard shows a reminder to verify, use the link we emailed, or "Send it again". Which verdicts send email is set per app, in its notification settings, where "Send test" checks delivery.

Still stuck? Contact us.