Heroku Buildpack for Middleware

The Middleware Heroku buildpack installs and runs mw-agent on each dyno to collect metrics and traces, forwarding them to the Middleware Observability platform. It does not handle logs, and you are required to use the Heroku Log Drain integration for log collection instead.

Prerequisites

  • Heroku CLI installed and authenticated.
  • An existing Heroku app.
  • Your Middleware API Key (MW_API_KEY) and Tenant URL (MW_TARGET).

1. Set APPNAME

1export APPNAME=<YOUR_HEROKU_APPLICATION_NAME>

2. Add & Configure the Buildpack

1cd <HEROKU_APPLICATION_DIRECTORY>
2
3# Enable Dyno metadata (needed for hostname continuity)
4heroku labs:enable runtime-dyno-metadata -a $APPNAME
5
6# Supply your Middleware credentials
7heroku config:add MW_API_KEY=<MW_API_KEY> -a $APPNAME
8heroku config:add MW_TARGET=https://<MW_UID>.middleware.io:443 -a $APPNAME
9
10# Add the Middleware buildpack
11heroku buildpacks:add https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAME
12
13# Rebuild your slug
14git commit --allow-empty -m "Add Middleware buildpack"
15git push heroku main

3. Buildpack Ordering

Your application’s primary buildpack must follow the Middleware buildpack. Otherwise, Middleware will override the Dyno’s process type and prevent your app from starting correctly.

Additionally, any buildpacks that override /app directory should be listed before the Middleware buildpack. For example, if your application requires Node, Middleware, and apt buildpacks, the output of heroku buildpacks should be as follows:

1https://github.com/heroku/heroku-buildpack-apt.git
2https://github.com/middleware-labs/heroku-buildpack-middleware.git
3heroku/nodejs           # or ruby, python, etc.

4. Pinning Versions (Optional)

Pin buildpack to a Git tag:

1heroku buildpacks:add https://github.com/middleware-labs/heroku-buildpack-middleware.git#<TAG_NAME>

Pin agent version:

1heroku config:add MW_AGENT_VERSION=1.7.7 -a $APPNAME

Rebuild the slug after changes:

1git commit --allow-empty -m "Rebuild slug"
2git push heroku main

5. Configuration Variables

Below is the list of all environment variables that you can set in your Heroku application to change the behavior of the Middleware buildpack and mw-agent.

VariableRequiredDescription
MW_API_KEYYesYour Middleware API key.
MW_TARGETYesYour tenant URL (https://<MW_UID>.middleware.io:443).
MW_AGENT_VERSIONNoOverride the default mw-agent tag.
MW_DYNO_DISABLE_AGENTNoIf true, disables mw-agent on this Dyno.
MW_DYNO_HOSTNAMENoIf true, use appname.type.num as hostname (see below).
MW_DYNO_PREEXEC_SCRIPTNoPath to a script to run before starting mw-agent.
MW_HOST_TAGSNoComma-separated key:value pairs (e.g. env:prod,role:web).
MW_FLUENT_PORTNoFluent receiver port (default 8006).
MW_AGENT_FEATURES_METRIC_COLLECTIONNoEnable infra metrics (default true).
MW_AGENT_FEATURES_LOG_COLLECTIONNoEnable log collection (not used by this buildpack).

6. Dyno Hostnames

By default, dynos report their internal container ID as hostname. To maintain continuity across dyno restarts, set:

1heroku config:add MW_DYNO_HOSTNAME=true -a $APPNAME

This requires runtime-dyno-metadata to be enabled

7. Preexec Script

If you need to adjust config vars or disable the agent for certain dyno types, point MW_DYNO_PREEXEC_SCRIPT at a script bundled with your app:

1heroku config:add MW_DYNO_PREEXEC_SCRIPT=/app/preexec.sh -a $APPNAME

Inside preexec.sh, you might do:

1#!/bin/bash
2DYNO_TYPE="${DYNO%%.*}"
3if [ "$DYNO_TYPE" == "run" ]; then
4  export MW_DYNO_DISABLE_AGENT=true
5fi
6# ...additional setup...

8. Exposed Endpoints

mw-agent listens locally for:

  • OTLP gRPC: port 9313
  • OTLP HTTP: port 9320
  • Fluent Forward: port 8006

9. Managing the Agent

Use Heroku CLI to inspect and debug the agent on your dynos:

ActionCommand
List dynosheroku ps -a $APPNAME
Exec into a dynoheroku ps:exec -a $APPNAME
Check mw-agent processps aux grep mw-agent (inside dyno)
View live agent logsheroku logs --ps web -a $APPNAME --num 1500 grep mw-agent
Cat agent log fileheroku ps:exec -a $APPNAME → cat /app/mw-agent/mw-agent.log

Troubleshooting

  1. Is the agent running?
    1heroku ps:exec -a $APPNAME
    2ps aux | grep mw-agent
  2. Inspect logs inside dyno:
    1cat /app/mw-agent/mw-agent.log
  3. Verify config vars:
    1heroku config -a $APPNAME
  4. Network check: Ensure outbound HTTPS (443) to <MW_UID>.middleware.io isn’t blocked.

Uninstall

  1. Remove the buildpack:

    1heroku buildpacks:remove https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAME
  2. Unset all Middleware vars:

    1heroku config:unset MW_API_KEY MW_TARGET MW_AGENT_VERSION MW_DYNO_DISABLE_AGENT \
    2MW_DYNO_HOSTNAME MW_DYNO_PREEXEC_SCRIPT MW_HOST_TAGS MW_FLUENT_PORT \
    3MW_AGENT_FEATURES_METRIC_COLLECTION MW_AGENT_FEATURES_LOG_COLLECTION -a $APPNAME
  3. Rebuild the slug to apply the removal:

    1git commit --allow-empty -m "Remove Middleware buildpack"
    2git push heroku main
  4. (Optional) Clear all buildpacks:

    1heroku buildpacks:clear -a $APPNAME