From f67510b7062403d5646a0008ef7270c4f305be2f Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Sun, 15 Feb 2026 22:21:49 +0100 Subject: [PATCH] docs: switch email provider recommendation from Mailgun to SendGrid SendGrid handles both transactional emails and marketing campaigns under one account. Updated alertmanager SMTP placeholders, hetzner setup guide (Step 19.5), and environment reference to recommend SendGrid as the primary email provider. Co-Authored-By: Claude Opus 4.6 --- docs/deployment/environment.md | 6 +-- docs/deployment/hetzner-server-setup.md | 57 ++++++++++++++++-------- monitoring/alertmanager/alertmanager.yml | 13 +++--- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/docs/deployment/environment.md b/docs/deployment/environment.md index fc62a9ef..c930bc63 100644 --- a/docs/deployment/environment.md +++ b/docs/deployment/environment.md @@ -331,9 +331,9 @@ marked **critical** will trigger a startup warning if left at their default valu !!! info "Required for specific features" - [x] **Payments:** `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET` - - [x] **Email (SendGrid):** `SENDGRID_API_KEY` - - [x] **Email (Mailgun):** `MAILGUN_API_KEY`, `MAILGUN_DOMAIN` - - [x] **Email (SES):** `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` + - [x] **Email (SendGrid — recommended):** `EMAIL_PROVIDER=sendgrid`, `SENDGRID_API_KEY` — handles transactional + marketing in one account + - [x] **Email (Mailgun):** `MAILGUN_API_KEY`, `MAILGUN_DOMAIN` — transactional only, no marketing features + - [x] **Email (SES):** `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` — cheapest at scale - [x] **R2 Storage:** `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY` ### Example `.env` file (production) diff --git a/docs/deployment/hetzner-server-setup.md b/docs/deployment/hetzner-server-setup.md index 66d426ac..67ceaeb6 100644 --- a/docs/deployment/hetzner-server-setup.md +++ b/docs/deployment/hetzner-server-setup.md @@ -1176,16 +1176,27 @@ The `docker-compose.yml` includes: - `prometheus` volumes: mounts `alert.rules.yml` as read-only - `prometheus.yml`: `alerting:` section pointing to alertmanager:9093, `rule_files:` for alert rules, new scrape job for alertmanager -### 19.5 Alertmanager SMTP Setup (Mailgun) +### 19.5 Alertmanager SMTP Setup (SendGrid) -Alertmanager needs SMTP to send email notifications. Mailgun's free tier (1,000 emails/month) is ideal for low-volume alerting. +Alertmanager needs SMTP to send email notifications. SendGrid handles both transactional emails and marketing campaigns under one account — set it up once and use it for everything. -**1. Create Mailgun account:** +**Free tier**: 100 emails/day (~3,000/month). Covers alerting + transactional emails through launch. -1. Sign up at [mailgun.com](https://www.mailgun.com/) (free Flex plan) -2. Add and verify your sending domain (e.g. `mg.wizard.lu`) — Mailgun provides DNS records to add -3. Go to **Sending** > **Domain settings** > **SMTP credentials** -4. Note: SMTP server, port, username, and password +**1. Create SendGrid account:** + +1. Sign up at [sendgrid.com](https://sendgrid.com/) (free plan) +2. Complete **Sender Authentication**: go to **Settings** > **Sender Authentication** > **Domain Authentication** +3. Authenticate your sending domain (`wizard.lu`) — SendGrid provides CNAME records to add to DNS +4. Create an API key: **Settings** > **API Keys** > **Create API Key** (Full Access) +5. Save the API key — you'll need it for both Alertmanager and the app's `EMAIL_PROVIDER` + +!!! info "SendGrid SMTP credentials" + SendGrid uses a single credential pattern for SMTP: + + - **Server**: `smtp.sendgrid.net` + - **Port**: `587` (STARTTLS) + - **Username**: literally the string `apikey` (not your email) + - **Password**: your API key (starts with `SG.`) **2. Update alertmanager config on the server:** @@ -1197,24 +1208,34 @@ Replace the SMTP placeholders: ```yaml global: - smtp_smarthost: 'smtp.mailgun.org:587' - smtp_from: 'alerts@mg.wizard.lu' - smtp_auth_username: 'postmaster@mg.wizard.lu' - smtp_auth_password: 'your-mailgun-smtp-password' + smtp_smarthost: 'smtp.sendgrid.net:587' + smtp_from: 'alerts@wizard.lu' + smtp_auth_username: 'apikey' + smtp_auth_password: 'SG.your-sendgrid-api-key-here' smtp_require_tls: true ``` Update the `to:` addresses in both receivers to your actual email. -**3. Restart alertmanager:** +**3. Update app email config** in `~/apps/orion/.env`: + +```bash +# SendGrid for all application emails (password reset, order confirmation, etc.) +EMAIL_PROVIDER=sendgrid +SENDGRID_API_KEY=SG.your-sendgrid-api-key-here +EMAIL_FROM_ADDRESS=noreply@wizard.lu +EMAIL_FROM_NAME=Orion +``` + +**4. Restart services:** ```bash cd ~/apps/orion -docker compose --profile full restart alertmanager +docker compose --profile full restart alertmanager api curl -s http://localhost:9093/-/healthy # Should return OK ``` -**4. Test by triggering a test alert (optional):** +**5. Test by triggering a test alert (optional):** ```bash # Send a test alert to alertmanager @@ -1235,11 +1256,11 @@ curl -s http://localhost:9093/api/v1/alerts | python3 -m json.tool ``` !!! tip "Alternative SMTP providers" - Any SMTP service works. Common alternatives: + Any SMTP service works if you prefer a different provider: - - **SendGrid**: `smtp.sendgrid.net:587`, username `apikey`, password is your API key - - **Amazon SES**: `email-smtp.eu-west-1.amazonaws.com:587` - - **Gmail**: `smtp.gmail.com:587` with an App Password (less reliable, not recommended for production) + - **Amazon SES**: `email-smtp.eu-west-1.amazonaws.com:587` — cheapest at scale ($0.10/1K emails) + - **Mailgun**: `smtp.mailgun.org:587` — transactional only, no built-in marketing + - **Gmail**: `smtp.gmail.com:587` with an App Password (not recommended for production) ### 19.6 Deploy diff --git a/monitoring/alertmanager/alertmanager.yml b/monitoring/alertmanager/alertmanager.yml index 3cc9d03e..0e405d4d 100644 --- a/monitoring/alertmanager/alertmanager.yml +++ b/monitoring/alertmanager/alertmanager.yml @@ -4,12 +4,13 @@ global: resolve_timeout: 5m - # ─── SMTP Configuration ────────────────────────────────────────────── - # Fill in your SMTP credentials below - smtp_smarthost: 'smtp.example.com:587' # TODO: Replace with your SMTP server - smtp_from: 'alerts@wizard.lu' # TODO: Replace with your sender address - smtp_auth_username: '' # TODO: Fill in SMTP username - smtp_auth_password: '' # TODO: Fill in SMTP password + # ─── SMTP Configuration (SendGrid) ────────────────────────────────── + # Sign up at sendgrid.com, create an API key, authenticate wizard.lu domain + # Username is literally the string "apikey", password is your SG.xxx API key + smtp_smarthost: 'smtp.sendgrid.net:587' # SendGrid SMTP relay + smtp_from: 'alerts@wizard.lu' # Must match authenticated domain + smtp_auth_username: 'apikey' # Always "apikey" for SendGrid + smtp_auth_password: '' # TODO: Paste your SG.xxx API key here smtp_require_tls: true route: