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: