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 main3. 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 $APPNAMERebuild the slug after changes:
git commit --allow-empty -m "Rebuild slug"
git push heroku main5. 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.
| Variable | Required | Description |
|---|---|---|
MW_API_KEY | Yes | Your Middleware API key. |
MW_TARGET | Yes | Your tenant URL (https://<MW_UID>.middleware.io:443). |
MW_AGENT_VERSION | No | Override the default mw-agent tag. |
MW_DYNO_DISABLE_AGENT | No | If true, disables mw-agent on this Dyno. |
MW_DYNO_HOSTNAME | No | If true, use appname.type.num as hostname (see below). |
MW_DYNO_PREEXEC_SCRIPT | No | Path to a script to run before starting mw-agent. |
MW_HOST_TAGS | No | Comma-separated key:value pairs (e.g. env:prod,role:web). |
MW_FLUENT_PORT | No | Fluent receiver port (default 8006). |
MW_AGENT_FEATURES_METRIC_COLLECTION | No | Enable infra metrics (default true). |
MW_AGENT_FEATURES_LOG_COLLECTION | No | Enable 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 $APPNAMEThis 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 $APPNAMEInside 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:
| Action | Command |
|---|---|
| List dynos | heroku ps -a $APPNAME |
| Exec into a dyno | heroku ps:exec -a $APPNAME |
Check mw-agent process | ps aux grep mw-agent (inside dyno) |
| View live agent logs | heroku logs --ps web -a $APPNAME --num 1500 grep mw-agent |
| Cat agent log file | heroku ps:exec -a $APPNAME → cat /app/mw-agent/mw-agent.log |
Troubleshooting
- Is the agent running?
heroku ps:exec -a $APPNAME ps aux | grep mw-agent - Inspect logs inside dyno:
cat /app/mw-agent/mw-agent.log - Verify config vars:
heroku config -a $APPNAME - Network check: Ensure outbound HTTPS (443) to <MW_UID>.middleware.io isn’t blocked.
Uninstall
Remove the buildpack:
heroku buildpacks:remove https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAMEUnset 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 $APPNAMERebuild the slug to apply the removal:
git commit --allow-empty -m "Remove Middleware buildpack" git push heroku main(Optional) Clear all buildpacks:
heroku buildpacks:clear -a $APPNAME