Files
Stalwart/tests/docker/INSTRUCTIONS.md
2026-03-19 19:29:17 +01:00

168 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stalwart Test Infrastructure
Ephemeral Docker Compose stack for testing Stalwart against external services.
All data is lost on `docker compose down` every restart is a clean slate.
## Quick Start
```bash
cd stalwart-test
docker compose up -d
```
Wait ~30 seconds for all services to initialize (Keycloak takes the longest).
## Connection Reference
| Service | Host | Port(s) | Credentials / Notes |
|----------------|-------------------|-----------------|--------------------------------------------|
| PostgreSQL | localhost | 5432 | `stalwart` / `stalwart`, db: `stalwart` |
| MySQL | localhost | 3306 | `stalwart` / `stalwart`, db: `stalwart` |
| FoundationDB | localhost | 4500 | Cluster file from container |
| Redis | localhost | 6379 | No auth |
| OpenSearch | localhost | 9200 | No auth, security plugin disabled |
| Meilisearch | localhost | 7700 | Master key: `stalwart-master-key` |
| MinIO (S3) | localhost | 9000 / 9001 | `minioadmin` / `minioadmin`, bucket: `stalwart` |
| Keycloak (OIDC)| localhost | 9080 | Admin: `admin` / `admin` |
| OpenLDAP | localhost | 389 / 636 (TLS) | Admin DN: `cn=admin,dc=stalwart,dc=test`, pw: `admin` |
| Pebble (ACME) | localhost | 14000 / 15000 | Self-signed TLS, auto-valid challenges |
| PowerDNS | localhost | 5300 / 8081 | API key: `stalwart-api-key` |
| NATS | localhost | 4222 / 8222 | No auth |
## OIDC (Keycloak) Details
- **OIDC Discovery**: `http://localhost:9080/realms/stalwart/.well-known/openid-configuration`
- **Token Endpoint**: `http://localhost:9080/realms/stalwart/protocol/openid-connect/token`
- **Client ID**: `stalwart`
- **Client Secret**: `stalwart-secret`
- **Realm**: `stalwart`
### Test Users
| Username | Password | Groups |
|---------------------------|--------------------------|----------------------------------------|
| john.doe@example.org | this is an OIDC password | sales@example.org |
| jane.smith@example.org | this is an OIDC password | sales@example.org, corporate@example.org |
| bill.foobar@example.org | this is an OIDC password | corporate@example.org |
### Example: Get a Token
```bash
curl -X POST http://localhost:9080/realms/stalwart/protocol/openid-connect/token \
-d "grant_type=password" \
-d "client_id=stalwart" \
-d "client_secret=stalwart-secret" \
-d "username=john.doe@example.org" \
-d "password=this is an OIDC password"
```
## LDAP Details
- **Base DN**: `dc=stalwart,dc=test`
- **Admin DN**: `cn=admin,dc=stalwart,dc=test`
- **Admin Password**: `admin`
- **Read-only DN**: `cn=readonly,dc=stalwart,dc=test`
- **Read-only Password**: `readonly`
- **User DN pattern**: `uid={username},ou=users,dc=stalwart,dc=test`
### Test Users
| DN | Mail | Password |
|------------------------------------------------|--------------------------|--------------------------|
| uid=john.doe,ou=users,dc=stalwart,dc=test | john.doe@example.org | this is an LDAP password |
| uid=jane.smith,ou=users,dc=stalwart,dc=test | jane.smith@example.org | this is an LDAP password |
| uid=bill.foobar,ou=users,dc=stalwart,dc=test | bill.foobar@example.org | this is an LDAP password |
### Groups
| DN | Mail | Members |
|---------------------------------------------|-------------------------|------------------|
| cn=sales,ou=groups,dc=stalwart,dc=test | sales@example.org | john.doe, jane.smith |
| cn=corporate,ou=groups,dc=stalwart,dc=test | corporate@example.org | bill.foobar, jane.smith |
### Example: Search by Email
```bash
ldapsearch -x -H ldap://localhost:389 \
-D "cn=admin,dc=stalwart,dc=test" -w admin \
-b "dc=stalwart,dc=test" "(mail=john.doe@example.org)"
```
## S3 (MinIO) Details
- **Endpoint**: `http://localhost:9000`
- **Access Key**: `minioadmin`
- **Secret Key**: `minioadmin`
- **Bucket**: `stalwart`
- **Console**: `http://localhost:9001`
- **Region**: `us-east-1` (MinIO default)
## DNS (PowerDNS) Details
- **DNS port**: 5300 (TCP+UDP)
- **API**: `http://localhost:8081` (API key: `stalwart-api-key`)
- **Zone**: `stalwart.test`
- **TSIG key name**: `stalwart-update-key`
- **TSIG algorithm**: `hmac-sha256`
- **TSIG secret (base64)**: `c3RhbHdhcnQtdGVzdC10c2lnLXNlY3JldC1rZXkxMjM0NTY3ODkw`
> **Note on SIG(0):** PowerDNS does not support SIG(0) authentication for RFC2136
> updates. Only BIND has (limited) SIG(0) support. If you need to test SIG(0),
> a separate BIND instance would be required.
### Example: Query TLSA Record
```bash
dig @localhost -p 5300 _25._tcp.mail.stalwart.test TLSA
```
### Example: RFC2136 Dynamic Update
```bash
nsupdate -y hmac-sha256:stalwart-update-key:c3RhbHdhcnQtdGVzdC10c2lnLXNlY3JldC1rZXkxMjM0NTY3ODkw <<EOF
server 127.0.0.1 5300
zone stalwart.test
update add test.stalwart.test 300 A 192.168.1.100
send
EOF
```
## ACME (Pebble) Details
- **Directory URL**: `https://localhost:14000/dir`
- **Management URL**: `https://localhost:15000`
- **TLS**: Self-signed (use `PEBBLE_VA_ALWAYS_VALID=1` — all challenges auto-pass)
- Stalwart must be configured to trust the Pebble CA or skip TLS verification.
## Self-Signed TLS Certificate
A shared self-signed certificate is generated at startup and mounted into services
that need it. The cert is valid for:
- `localhost`, `keycloak`, `openldap`, `pebble`, `*.stalwart.test`, `127.0.0.1`
To extract the cert for use with Stalwart:
```bash
docker compose cp cert-init:/certs/cert.pem ./test-cert.pem
docker compose cp cert-init:/certs/key.pem ./test-key.pem
```
## Troubleshooting
```bash
# Check all services are running
docker compose ps
# View logs for a specific service
docker compose logs -f keycloak
# Restart everything fresh
docker compose down && docker compose up -d
# Check FoundationDB status
docker compose exec foundationdb fdbcli --exec "status"
# Verify TSIG key is loaded
docker compose exec powerdns pdnsutil list-tsig-keys
```