docs: rewrite README with structured overview and quick start guide
Replaces the minimal project description with a comprehensive README including a component overview table, quick start instructions, common Ansible operations, and links to detailed documentation. Aligns with Red Panda Approval™ standards.
This commit is contained in:
191
docs/smtp4dev.md
Normal file
191
docs/smtp4dev.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# smtp4dev - Development SMTP Server
|
||||
|
||||
## Overview
|
||||
|
||||
smtp4dev is a fake SMTP server for development and testing. It accepts all incoming email without delivering it, capturing messages for inspection via a web UI and IMAP client. All services in the Agathos sandbox that send email (Casdoor, Gitea, etc.) are wired to smtp4dev so email flows can be tested without a real mail server.
|
||||
|
||||
**Host:** Oberon (container_orchestration)
|
||||
**Web UI Port:** 22085 → `https://smtp4dev.ouranos.helu.ca`
|
||||
**SMTP Port:** 22025 (used by all services as `smtp_host:smtp_port`)
|
||||
**IMAP Port:** 22045
|
||||
**Syslog Port:** 51405 (Alloy)
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Oberon Host │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ smtp4dev Container (Docker) │ │
|
||||
│ │ │ │
|
||||
│ │ Port 80 → host 22085 (Web UI) │ │
|
||||
│ │ Port 25 → host 22025 (SMTP) │ │
|
||||
│ │ Port 143 → host 22045 (IMAP) │ │
|
||||
│ │ │ │
|
||||
│ │ Volume: smtp4dev_data → /smtp4dev │ │
|
||||
│ │ Logs: syslog → Alloy:51405 → Loki │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
▲ ▲
|
||||
│ SMTP :22025 │ SMTP :22025
|
||||
┌──────┴──────┐ ┌──────┴──────┐
|
||||
│ Casdoor │ │ Gitea │
|
||||
│ (Titania) │ │ (Rosalind) │
|
||||
└─────────────┘ └─────────────┘
|
||||
|
||||
External access:
|
||||
https://smtp4dev.ouranos.helu.ca → HAProxy (Titania) → oberon.incus:22085
|
||||
```
|
||||
|
||||
## Shared SMTP Variables
|
||||
|
||||
smtp4dev connection details are defined once in `ansible/inventory/group_vars/all/vars.yml` and consumed by all service templates:
|
||||
|
||||
| Variable | Value | Purpose |
|
||||
|----------|-------|---------|
|
||||
| `smtp_host` | `oberon.incus` | SMTP server hostname |
|
||||
| `smtp_port` | `22025` | SMTP server port |
|
||||
| `smtp_from` | `noreply@ouranos.helu.ca` | Default sender address |
|
||||
| `smtp_from_name` | `Agathos` | Default sender display name |
|
||||
|
||||
Any service that needs to send email references these shared variables rather than defining its own SMTP config. This means switching to a real SMTP server only requires changing `group_vars/all/vars.yml`.
|
||||
|
||||
## Ansible Deployment
|
||||
|
||||
### Playbook
|
||||
|
||||
```bash
|
||||
# Deploy smtp4dev on Oberon
|
||||
ansible-playbook smtp4dev/deploy.yml
|
||||
|
||||
# Redeploy HAProxy to activate the smtp4dev.ouranos.helu.ca backend
|
||||
ansible-playbook haproxy/deploy.yml
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `ansible/smtp4dev/deploy.yml` | Main deployment playbook |
|
||||
| `ansible/smtp4dev/docker-compose.yml.j2` | Docker Compose template |
|
||||
|
||||
### Deployment Steps
|
||||
|
||||
The `deploy.yml` playbook:
|
||||
|
||||
1. Filters hosts — only runs on hosts with `smtp4dev` in their `services` list (Oberon)
|
||||
2. Creates `smtp4dev` system group and user
|
||||
3. Adds `ponos` user to the `smtp4dev` group (for `docker compose` access)
|
||||
4. Creates `/srv/smtp4dev` directory owned by `smtp4dev:smtp4dev`
|
||||
5. Templates `docker-compose.yml` into `/srv/smtp4dev/`
|
||||
6. Resets SSH connection to apply group membership
|
||||
7. Starts the service with `community.docker.docker_compose_v2: state: present`
|
||||
|
||||
### Host Variables
|
||||
|
||||
Defined in `ansible/inventory/host_vars/oberon.incus.yml`:
|
||||
|
||||
```yaml
|
||||
# smtp4dev Configuration
|
||||
smtp4dev_user: smtp4dev
|
||||
smtp4dev_group: smtp4dev
|
||||
smtp4dev_directory: /srv/smtp4dev
|
||||
smtp4dev_port: 22085 # Web UI (container port 80)
|
||||
smtp4dev_smtp_port: 22025 # SMTP (container port 25)
|
||||
smtp4dev_imap_port: 22045 # IMAP (container port 143)
|
||||
smtp4dev_syslog_port: 51405 # Alloy syslog collector
|
||||
```
|
||||
|
||||
## Service Integrations
|
||||
|
||||
### Casdoor
|
||||
|
||||
The Casdoor email provider is declared in `ansible/casdoor/init_data.json.j2` and seeded automatically on a **fresh** Casdoor deployment:
|
||||
|
||||
```json
|
||||
{
|
||||
"owner": "admin",
|
||||
"name": "provider-email-smtp4dev",
|
||||
"displayName": "smtp4dev Email",
|
||||
"category": "Email",
|
||||
"type": "SMTP",
|
||||
"host": "oberon.incus",
|
||||
"port": 22025,
|
||||
"disableSsl": true,
|
||||
"fromAddress": "noreply@ouranos.helu.ca",
|
||||
"fromName": "Agathos"
|
||||
}
|
||||
```
|
||||
|
||||
> ⚠️ For **existing** Casdoor installs, create the provider manually:
|
||||
> 1. Log in to `https://id.ouranos.helu.ca` as admin
|
||||
> 2. Navigate to **Identity → Providers → Add**
|
||||
> 3. Set **Category**: `Email`, **Type**: `SMTP`
|
||||
> 4. Fill host `oberon.incus`, port `22025`, disable SSL, from `noreply@ouranos.helu.ca`
|
||||
> 5. Save and assign the provider to the `heluca` organization under **Organizations → heluca → Edit → Default email provider**
|
||||
|
||||
### Gitea
|
||||
|
||||
Configured directly in `ansible/gitea/app.ini.j2`:
|
||||
|
||||
```ini
|
||||
[mailer]
|
||||
ENABLED = true
|
||||
SMTP_ADDR = {{ smtp_host }}
|
||||
SMTP_PORT = {{ smtp_port }}
|
||||
FROM = {{ smtp_from }}
|
||||
```
|
||||
|
||||
Redeploy Gitea to apply:
|
||||
|
||||
```bash
|
||||
ansible-playbook gitea/deploy.yml
|
||||
```
|
||||
|
||||
## External Access
|
||||
|
||||
smtp4dev's web UI is exposed via HAProxy on Titania at `https://smtp4dev.ouranos.helu.ca`.
|
||||
|
||||
Backend entry in `ansible/inventory/host_vars/titania.incus.yml`:
|
||||
|
||||
```yaml
|
||||
- subdomain: "smtp4dev"
|
||||
backend_host: "oberon.incus"
|
||||
backend_port: 22085
|
||||
health_path: "/"
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Check container is running
|
||||
ssh oberon.incus "cd /srv/smtp4dev && docker compose ps"
|
||||
|
||||
# Check logs
|
||||
ssh oberon.incus "cd /srv/smtp4dev && docker compose logs --tail=50"
|
||||
|
||||
# Test SMTP delivery (sends a test message)
|
||||
ssh oberon.incus "echo 'Subject: test' | sendmail -S oberon.incus:22025 test@example.com"
|
||||
|
||||
# Check web UI is reachable internally
|
||||
curl -s -o /dev/null -w "%{http_code}" http://oberon.incus:22085
|
||||
|
||||
# Check external HTTPS route
|
||||
curl -sk -o /dev/null -w "%{http_code}" https://smtp4dev.ouranos.helu.ca
|
||||
```
|
||||
|
||||
## site.yml Order
|
||||
|
||||
smtp4dev is deployed after Docker (it requires the Docker engine) and before Casdoor (so the SMTP endpoint exists when Casdoor initialises):
|
||||
|
||||
```yaml
|
||||
- name: Deploy Docker
|
||||
import_playbook: docker/deploy.yml
|
||||
|
||||
- name: Deploy smtp4dev
|
||||
import_playbook: smtp4dev/deploy.yml
|
||||
|
||||
- name: Deploy PPLG Stack # ...continues
|
||||
```
|
||||
Reference in New Issue
Block a user