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.
192 lines
6.7 KiB
Markdown
192 lines
6.7 KiB
Markdown
# 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
|
|
```
|