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

export APPNAME=<YOUR_HEROKU_APPLICATION_NAME>

2. Add & Configure the Buildpack

cd <HEROKU_APPLICATION_DIRECTORY>

# Enable Dyno metadata (needed for hostname continuity)
heroku labs:enable runtime-dyno-metadata -a $APPNAME

# Supply your Middleware credentials
heroku config:add MW_API_KEY=<MW_API_KEY> -a $APPNAME
heroku config:add MW_TARGET=https://<MW_UID>.middleware.io:443 -a $APPNAME

# Add the Middleware buildpack
heroku buildpacks:add https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAME

# Rebuild your slug
git commit --allow-empty -m "Add Middleware buildpack"
git 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:

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

4. Pinning Versions (Optional)

Pin buildpack to a Git tag:

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

Pin agent version:

heroku config:add MW_AGENT_VERSION=1.7.7 -a $APPNAME

Rebuild the slug after changes:

git commit --allow-empty -m "Rebuild slug"
git 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:

heroku 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:

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

Inside preexec.sh, you might do:

#!/bin/bash
DYNO_TYPE="${DYNO%%.*}"
if [ "$DYNO_TYPE" == "run" ]; then
  export MW_DYNO_DISABLE_AGENT=true
fi
# ...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?
    heroku ps:exec -a $APPNAME
    ps aux | grep mw-agent
  2. Inspect logs inside dyno:
    cat /app/mw-agent/mw-agent.log
  3. Verify config vars:
    heroku config -a $APPNAME
  4. Network check: Ensure outbound HTTPS (443) to <MW_UID>.middleware.io isn’t blocked.

Uninstall

  1. Remove the buildpack:

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

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

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

    heroku buildpacks:clear -a $APPNAME