# Deployment Notifications

> Send deployment notifications from Docker Compose, Kubernetes, Vercel, and Netlify when deploys start, succeed, or fail, routed to the right team.

Source: https://docs.alphorn.dev/use-cases/deployments/

Deployments affect everyone. Whether it's a new feature going live or a hotfix rolling out, the right people need to know - in real time, not via a status page they might not check.

## Docker / Docker Compose

Wrap your deploy script with notifications:

```bash title="deploy.sh"
#!/bin/bash
WEBHOOK="https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT"
ALPHORN_API_KEY="${ALPHORN_API_KEY:-alp_...}"  # or export it in the environment
SERVICE="my-app"
VERSION=$(git describe --tags --always)

# Notify start
curl -fsS -X POST "$WEBHOOK" \
  -H "Authorization: Bearer $ALPHORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"title\": \"Deploy started: $SERVICE\",
    \"message\": \"Deploying $VERSION to production\",
    \"priority\": 2,
    \"tags\": [\"deploy\", \"started\", \"$SERVICE\"]
  }"

# Deploy
docker compose pull && docker compose up -d
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
  curl -fsS -X POST "$WEBHOOK" \
    -H "Authorization: Bearer $ALPHORN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"title\": \"Deploy succeeded: $SERVICE\",
      \"message\": \"$VERSION is live in production\",
      \"priority\": 2,
      \"tags\": [\"deploy\", \"success\", \"$SERVICE\"]
    }"
else
  curl -fsS -X POST "$WEBHOOK" \
    -H "Authorization: Bearer $ALPHORN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"title\": \"Deploy FAILED: $SERVICE\",
      \"message\": \"$VERSION failed to deploy (exit $EXIT_CODE)\",
      \"priority\": 5,
      \"tags\": [\"deploy\", \"failure\", \"$SERVICE\"]
    }"
fi
```

## Kubernetes

Send a notification from a Kubernetes Job or post-deploy hook:

```yaml title="post-deploy-job.yaml"
apiVersion: batch/v1
kind: Job
metadata:
  name: deploy-notify
spec:
  template:
    spec:
      containers:
        - name: notify
          image: curlimages/curl
          command:
            - curl
            - -fsS
            - -X
            - POST
            - $(ALPHORN_WEBHOOK)
            - -H
            - "Authorization: Bearer $(ALPHORN_API_KEY)"
            - -H
            - "Content-Type: application/json"
            - -d
            - '{"title":"Deployed to k8s","message":"$(APP_VERSION) rolled out","priority":2,"tags":["deploy","k8s"]}'
          env:
            - name: ALPHORN_WEBHOOK
              valueFrom:
                secretKeyRef:
                  name: alphorn
                  key: webhook-url
            - name: ALPHORN_API_KEY
              valueFrom:
                secretKeyRef:
                  name: alphorn
                  key: api-key
            - name: APP_VERSION
              value: "v1.2.3"
      restartPolicy: Never
```

## Vercel

Use deploy webhooks: Vercel can call a URL on deploy events - point it at your Alphorn webhook endpoint.

1. Go to **Team Settings → Webhooks** and add a webhook for deployment events (webhook availability depends on your Vercel plan, so check yours). **Deploy Hooks** under **Project Settings → Git** are the opposite direction: incoming URLs that trigger a deploy.
2. Or use the [Vercel API](https://vercel.com/docs/rest-api) in a GitHub Action to POST to Alphorn after deploy completes

Platform deploy webhooks can't send an `Authorization` header, so create that webhook with the API key switched off (**No API key (URL is the secret)**) and keep the URL private. A GitHub Action step can send the header like the [CI/CD examples](/use-cases/ci-cd-pipelines).

Vercel nests the event data under `payload` (for example `payload.deployment.url`), with the event name in the top-level `type`. Without templates, Alphorn finds no message-like field, so the notification body is the raw JSON. Shape it with [field templates](/webhook-templates), for example Title `Vercel: {type}` and Message `{payload.deployment.url}` (an example; check the field names against a real delivery, as they vary by event).

## Netlify

1. In Alphorn, create a webhook with the API key switched off (**No API key (URL is the secret)**). Netlify can't send a custom `Authorization` header, so keep the URL private.
2. In Netlify, open your site and go to **Site configuration → Notifications → Deploy notifications**
3. Click **Add notification → HTTP POST request**
4. Pick the event (for example **Deploy failed** or **Deploy succeeded**) and paste your Alphorn webhook URL
5. Repeat for each event you want

Netlify posts its deploy object, which has top-level fields such as `name` (the site name), `state`, `error_message`, and usually `title` (the commit title); check a real delivery for the exact fields. Without templates, Alphorn guesses the title (`title` wins over `name`), and since there's no message-like field, the message is the raw JSON. Shape it with [field templates](/webhook-templates) when creating the webhook, for example Title `Netlify: {name} {state}` and Message `{error_message}` for a failed-deploy webhook.

## Routing examples

| Channel | Filter | Purpose |
|---|---|---|
| Slack (#deployments) | Tags has any of `deploy` | All deploy activity |
| Slack (#engineering) | Tags has any of `failure` | Only failed deploys |
| PagerDuty | Priority greater than 3 and tags has any of `deploy` | Page on-call for deploy failures |
| Discord | Tags has any of `success` | Celebrate successful releases |
