release: 1.5.0: Send-log retention configurable in panel Settings
Send-log retention is configurable from panel **Settings** (global administrator); `SEND_LOG_RETENTION_DAYS` seeds the initial default only. Added: - Panel **Settings** (global administrator): **Send log retention (days)** — Changed: - Deliveries list and delivery detail pages show the configured retention Full detail: CHANGELOG.md (1.5.0).
This commit is contained in:
+1
-1
@@ -102,7 +102,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
||||
2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
|
||||
[§ Release image](#release-image)).
|
||||
|
||||
**Planned version cuts** (from pin `1.4.0`; adjust if semver changes mid-track):
|
||||
**Planned version cuts** (from pin `1.5.0`; adjust if semver changes mid-track):
|
||||
|
||||
| Stage | ID | Cut |
|
||||
|---|---|---|
|
||||
|
||||
+10
-7
@@ -169,7 +169,7 @@ cat ./data/setup-token
|
||||
#### Fixed image tag
|
||||
|
||||
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`),
|
||||
deliberately never `:latest`. The current pin is `1.4.0`. Intermediate
|
||||
deliberately never `:latest`. The current pin is `1.5.0`. Intermediate
|
||||
CHANGELOG sections (`0.2.0`…`0.6.0`) record development cuts from before that
|
||||
image was published. Pinning matters because of the backup version check (see
|
||||
[Full backup and restore](#full-backup-and-restore)): the panel binary's
|
||||
@@ -196,7 +196,7 @@ expected to set; defaults match the code exactly.
|
||||
| `INBOUND_MESSAGE_SIZE_LIMIT` | Maximum message size in bytes on inbound smtpd (`message_size_limit`). | `26214400` (25 MiB) | `.env` |
|
||||
| `RATE_LIMIT_MESSAGES_PER_IP` | Level-1 backstop: maximum messages one client IP may submit per window (Postfix `smtpd_client_message_rate_limit`). See [Rate limiting — level 1](#rate-limiting--level-1-ip-backstop). | `100` | `.env` |
|
||||
| `RATE_LIMIT_WINDOW_SECONDS` | Level-1 window length in seconds (Postfix `anvil_rate_time_unit`). | `3600` | `.env` |
|
||||
| `SEND_LOG_RETENTION_DAYS` | Days of send-log history kept before the background sweep deletes rows — the main driver of `/data` growth over time. | `90` | `.env` |
|
||||
| `SEND_LOG_RETENTION_DAYS` | Initial default for how many days of send-log history are kept before the background sweep deletes rows — the main driver of `/data` growth over time. After the first panel start, change retention on **Settings** (global administrator); the env value is only used to seed SQLite when the setting has never been saved. | `90` | `.env` |
|
||||
| `PANEL_SESSION_IDLE_DAYS` | Sliding idle timeout for the panel login session, in days. There is no absolute cap: an admin who keeps coming back stays signed in indefinitely. | `7` | `.env` |
|
||||
| `SELFPOST_DNS_RESOLVERS` | Comma-separated recursive resolvers the panel's PTR/SPF/DKIM/DMARC checks query directly (so they report what the internet sees, not what this host's stub resolver synthesises). | `1.1.1.1:53`, `8.8.8.8:53`, `9.9.9.9:53` when unset | `.env` |
|
||||
| `TRUSTED_PROXY_CIDR` | Comma-separated CIDRs (bare IPs allowed) of reverse proxies allowed to supply `X-Forwarded-For` for login, setup, and account-change rate-limiting. **Leave unset unless you know the exact address of your reverse proxy.** A wrong value lets a client spoof its rate-limit key by sending a forged `X-Forwarded-For` header — the panel trusts the last hop only when the TCP peer matches one of these CIDRs. Behind the default Apache host-network setup this is typically the Docker bridge gateway, e.g. `172.18.0.1`. | *(empty — XFF ignored)* | `.env` |
|
||||
@@ -347,8 +347,10 @@ shows after manual edits under `/data`.
|
||||
`/settings` changes the signed-in user's username and/or password. **Global
|
||||
administrators** also set the panel-wide default DMARC report address (`rua=`)
|
||||
offered when a domain doesn't set its own — see
|
||||
[Domain-level DNS](#domain-level-dns-spf-dkim-dmarc). Application SASL logins
|
||||
are separate and are not changed here.
|
||||
[Domain-level DNS](#domain-level-dns-spf-dkim-dmarc) — and how many days
|
||||
**Deliveries** rows are kept before the background sweep deletes them (7–365
|
||||
days; takes effect on the next six-hour prune cycle without a container
|
||||
restart). Application SASL logins are separate and are not changed here.
|
||||
|
||||
### Users
|
||||
|
||||
@@ -489,7 +491,7 @@ A version mismatch at step 5 refuses to start and leaves `/data` untouched —
|
||||
the panel exits with a message naming the tag to use, e.g.:
|
||||
|
||||
```
|
||||
backup: this backup was created by SelfPost 1.2.3 but this image is 1.4.0 — restore into the matching image (selfpost:1.2.3)
|
||||
backup: this backup was created by SelfPost 1.2.3 but this image is 1.5.0 — restore into the matching image (selfpost:1.2.3)
|
||||
```
|
||||
|
||||
Fix the tag in `docker-compose.yml`, `docker compose pull && docker compose up
|
||||
@@ -741,8 +743,9 @@ administrators see them here because they cannot open Mail queue. Under
|
||||
both sit the `mail.log` lines for its queue id: the connection to the
|
||||
receiving server, the server's reply, and the status that reply was filed
|
||||
as. Rows outlive `mail.log`, so an older message's lines may have rotated
|
||||
away; the page says so. Retention is controlled by
|
||||
`SEND_LOG_RETENTION_DAYS`.
|
||||
away; the page says so. Retention is set on **Settings** (global
|
||||
administrator); `SEND_LOG_RETENTION_DAYS` in `.env` is only the initial
|
||||
default until it is changed there.
|
||||
|
||||
### Exporting and importing a single domain
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Plan: send-log-retention
|
||||
|
||||
**Status:** candidate
|
||||
**Status:** done — shipped in `[1.5.0]` (2026-08-18)
|
||||
**Date:** 2026-08-17
|
||||
**Version:** `1.x` MINOR; no schema migration required (uses existing `settings` table).
|
||||
**Version:** `1.5.0` MINOR; no schema migration required (uses existing `settings` table).
|
||||
|
||||
---
|
||||
|
||||
@@ -129,11 +129,11 @@ Target version cut: **`1.5.0`** (MINOR). One commit per step; code only after
|
||||
roadmap status is **agreed**. See [development.md](../development.md) § Plan
|
||||
checklists.
|
||||
|
||||
- [ ] `GetSendLogRetentionDays` / `SetSetting` key `send_log_retention_days` (7–365) — **Opus**
|
||||
- [ ] Bootstrap from `SEND_LOG_RETENTION_DAYS` when settings empty — **Opus**
|
||||
- [ ] `logtail.retentionLoop`: read setting each prune cycle — **Opus**
|
||||
- [ ] Settings card on `/settings` (`settings.html`) — **Sonnet**
|
||||
- [ ] Remove hardcoded «ninety days» in handlers and templates — **Sonnet**
|
||||
- [ ] Tests: save/load, range, loop without restart — **Sonnet**
|
||||
- [ ] [guide.md](../guide.md) — **Sonnet**
|
||||
- [ ] `go vet`, `go test` on touched packages — **Haiku**
|
||||
- [x] `GetSendLogRetentionDays` / `SetSetting` key `send_log_retention_days` (7–365) — **Opus**
|
||||
- [x] Bootstrap from `SEND_LOG_RETENTION_DAYS` when settings empty — **Opus**
|
||||
- [x] `logtail.retentionLoop`: read setting each prune cycle — **Opus**
|
||||
- [x] Settings card on `/settings` (`settings.html`) — **Sonnet**
|
||||
- [x] Remove hardcoded «ninety days» in handlers and templates — **Sonnet**
|
||||
- [x] Tests: save/load, range, loop without restart — **Sonnet**
|
||||
- [x] [guide.md](../guide.md) — **Sonnet**
|
||||
- [x] `go vet`, `go test` on touched packages — **Haiku**
|
||||
|
||||
+4
-4
@@ -58,11 +58,11 @@ Explicitly excluded to prevent scope creep:
|
||||
The **domain-admin** role ships in the current line (global administrator plus
|
||||
domain administrators with assigned domains). The optional **inbound relay**
|
||||
(backup-MX / forwarder on port 25) ships in `[1.4.0]`, off by default behind
|
||||
`INBOUND_RELAY_ENABLE`; it is relay/forward, not IMAP/webmail. Items
|
||||
marked *candidate* in the
|
||||
`INBOUND_RELAY_ENABLE`; it is relay/forward, not IMAP/webmail. **Send-log
|
||||
retention in Settings** ships in `[1.5.0]`. Items marked *candidate* in the
|
||||
[roadmap](roadmap.md) require explicit approval before coding (including
|
||||
**send-log retention in Settings**, **30-day send statistics**, and **auto
|
||||
level-2 rate limits** — see linked plans there).
|
||||
**30-day send statistics** and **auto level-2 rate limits** — see linked
|
||||
plans there).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+5
-25
@@ -28,7 +28,6 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
||||
|
||||
| ID | Topic | Status | Progress | Plan |
|
||||
|---|---|---|---|---|
|
||||
| send-log-retention | Send-log retention days in panel Settings | candidate | 0/8 | [plans/send-log-retention.md](plans/send-log-retention.md) |
|
||||
| domain-stats-auto-ratelimit | 30-day send stats + auto level-2 rate limit | candidate | 0/11 | [plans/domain-stats-auto-ratelimit.md](plans/domain-stats-auto-ratelimit.md) |
|
||||
| contributing | `CONTRIBUTING.md` | candidate | — | — |
|
||||
| dmarc-reports | DMARC aggregate report ingestion and panel UI | candidate | 0/8 | [plans/dmarc-reports.md](plans/dmarc-reports.md) |
|
||||
@@ -36,12 +35,11 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
||||
| schema-squash | Squash SQLite migrations into a 2.x baseline | **2.x** | — | — |
|
||||
|
||||
**Recommended order** (not binding): the next feature is
|
||||
**send-log-retention** once agreed. It can land before or beside
|
||||
**domain-stats-auto-ratelimit** (panel retention ≥ 30 days helps the stats
|
||||
window). inbound-relay shipped in
|
||||
[CHANGELOG.md](../CHANGELOG.md) `[1.4.0]`; queue-retries in `[1.3.1]`; the
|
||||
2026-08-13 full-tree review follow-ups are in `[1.3.0]`. Candidates need
|
||||
explicit agreement before they join the queue.
|
||||
**domain-stats-auto-ratelimit** once agreed (panel retention ≥ 30 days helps
|
||||
the stats window). send-log-retention shipped in
|
||||
[CHANGELOG.md](../CHANGELOG.md) `[1.5.0]`; inbound-relay in `[1.4.0]`;
|
||||
queue-retries in `[1.3.1]`; the 2026-08-13 full-tree review follow-ups are in
|
||||
`[1.3.0]`. Candidates need explicit agreement before they join the queue.
|
||||
|
||||
After a context reset, pick an item marked `agreed` or `in progress`, then work
|
||||
the **Implementation checklist** in its linked plan. The `Progress` column above
|
||||
@@ -50,24 +48,6 @@ is `done/total` checklist steps in that plan ([development.md](development.md)
|
||||
|
||||
---
|
||||
|
||||
## send-log-retention
|
||||
|
||||
**Goal:** global administrator sets how many days of delivery journal rows
|
||||
(`send_log`, `/deliveries`) are kept, from `/settings` — stored in SQLite
|
||||
`settings`, with `SEND_LOG_RETENTION_DAYS` as bootstrap default only.
|
||||
|
||||
**Boundary:** instance-wide retention; not per-domain. Does not change
|
||||
`mail.log` rotation. Today retention is env-only (default 90 days); the panel
|
||||
has no control.
|
||||
|
||||
**Done when:** see [plans/send-log-retention.md](plans/send-log-retention.md).
|
||||
|
||||
**Dependencies / risks:** log-tailer must re-read settings each prune cycle;
|
||||
delivery UI must stop hardcoding «ninety days».
|
||||
**Version:** `1.x` MINOR; `candidate` until explicitly agreed.
|
||||
|
||||
---
|
||||
|
||||
## domain-stats-auto-ratelimit
|
||||
|
||||
**Goal:** 30-day sending statistics per domain and application (total, peak and
|
||||
|
||||
Reference in New Issue
Block a user