docs: machine requirements by what is switched on, measured
test / test (push) Waiting to run

Owner, 2026-10-19: "Нам нужно записать в документы для деплоя минимальные
требования к машине в зависимости от включённых опций." The README's
"1 vCPU, 512 MB-1 GB RAM, 8-10 GB disk" had never been measured.

Measured on the test installation (2.16.0, inbound relay and rspamd on,
2 vCPU / 4 GB), 2026-10-19:
- the SelfPost container: cgroup 55 MB at rest, 78 MB peak since the
  rollout; panel and supervisord ~30 MB RSS each, Postfix daemons 6-12 MB;
- the rspamd sidecar: 117 MB, peak 120 MB, five processes;
- CPU at rest under 0.1 %; images 315 MB and 311 MB;
- the build step of build/Dockerfile, cold, in golang:1.26-trixie held by
  docker run --memory/--memory-swap and --cpus 1: killed at 512 MB and 1 GB
  (compile of modernc.org/libc, modernc.org/sqlite), passed at 1.5 GB
  (269 s) and 2 GB; unlimited on 2 CPUs 150 s, cgroup peak 1.5 GB. Build
  cache per build: go mod download 577 MB, compile step 403 MB; the Go
  image 1.28 GB;
- send log: dbstat pages and 4.9 lines of ~150 B per message give about
  2-3 KB a message (the guide's env table already said 1-2 KB for the lines);
  mail.log ~400 KB a day of mostly port-25 noise on the test server.
Postfix's own refusal for a short disk cited from src/smtpd/smtpd_check.c,
smtpd_check_queue(). What is worked out rather than measured (the 1 000 and
10 000 a day figures, the host memory column) says so or is framed as a
minimum with room for the host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-19 00:23:35 +03:00
co-authored by Claude Opus 5.5
parent 91dadf7b35
commit 839a752341
3 changed files with 95 additions and 3 deletions
+10
View File
@@ -5,6 +5,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
## [Unreleased]
### Documentation
- **Machine requirements by what is switched on** (guide § Installation,
README § Requirements), measured on the test installation instead of the
old unmeasured "1 vCPU, 512 MB-1 GB, 8-10 GB": 512 MB of host memory for
outbound mail with or without port 25, 1 GB with the spam filter; one
vCPU. Building the image needs 1.5 GB of memory - a build held to 1 GB was
killed in the Go compiler - and about 3 GB of free disk. The send log
grows about 2-3 KB a message for its retention.
## [2.16.0] - 2026-10-18
The queues as the 2.0 mockups drew them: Outbound › Queue a table, Inbound ›
+13 -3
View File
@@ -62,9 +62,19 @@ missing PTR record for you. Details: [Operator guide](docs/guide.md).
- Docker + Compose v2 on the host
- A reverse proxy in front of the panel (SelfPost never terminates HTTPS itself)
- Rough sizing: **1 vCPU**, **512 MB–1 GB RAM**, **8–10 GB disk** (send log and
rotated `mail.log` are the main growth drivers; both sit in the `./data`
volume, and both are capped — 90 days and 14 files by default)
- Machine, by what is switched on (measured; details and disk growth in the
guide's [Machine requirements](docs/guide.md#machine-requirements)):
| Switched on | Host memory, at least | Images on disk |
|---|---|---|
| Outbound only (465/587), or with port 25 (inbound relay, DMARC reports) | 512 MB | 315 MB |
| With the spam filter (rspamd sidecar) | 1 GB | 626 MB |
One vCPU is enough. **Building the image needs 1.5 GB of memory and about
3 GB of free disk** (the Go compiler: a 1 GB build was killed) - on a
smaller machine, build elsewhere and `docker load` the image. The send log
is what grows: about 2-3 KB a message for the retention (90 days by
default) - 10 000 messages a day keep about 2.5 GB.
### Network and IP
+72
View File
@@ -19,6 +19,7 @@ changed (see the CHANGELOG, *Removed*).
## Table of contents
- [Installation](#installation)
- [Machine requirements](#machine-requirements)
- [Ports](#ports)
- [Local trial](#local-trial)
- [Initial setup](#initial-setup)
@@ -56,6 +57,77 @@ changed (see the CHANGELOG, *Removed*).
## Installation
### Machine requirements
What SelfPost needs of the host depends on what is switched on. The figures
were measured on the test installation on 2026-10-19 - SelfPost 2.16.0 with
the inbound relay and the spam filter on, a host of 2 vCPU and 4 GB - and,
for the build, in a container held to a given memory and one CPU. What is
worked out from them rather than measured says so.
**Running**
| Switched on | What it uses (measured) | Host memory, at least | Images on disk |
|---|---|---|---|
| Outbound only: 465, and 587 if enabled | 55 MB at rest, 80 MB the most seen: the panel about 30 MB, supervisord 30 MB, Postfix's daemons 6-12 MB each, most of that shared libraries | 512 MB | 315 MB, the SelfPost image |
| Port 25: the inbound relay and/or DMARC reports | the same at rest; each SMTP connection being served is one more Postfix `smtpd`, of the size of its resident siblings (6 MB, mostly shared) | 512 MB | the same |
| The spam filter: the rspamd sidecar, `deploy/antispam/` | 120 MB more, rspamd's five processes | 1 GB | 311 MB more, the rspamd image |
The host's own system and Docker come on top of what SelfPost uses, and
are what the third column leaves room for. Docker's daemon grows with the
images and the build cache it keeps: on the test server, after a week of
builds for three projects, `dockerd` held 600 MB - prune what you do not
need (below).
One vCPU is enough to run it: at rest SelfPost and rspamd use under 0.1 % of
a CPU. The
image is built and run on `amd64` and `arm64`; rspamd's image is published
for both.
**Building the image.** As long as no 2.x image is published (see [Fixed
image tag](#fixed-image-tag)), every installation builds its own, and the
build needs more than running does:
- **Memory: 1.5 GB.** The Go compiler is the largest part: the build was
killed for want of memory at 1 GB and at 512 MB (on `modernc.org/sqlite`
and `modernc.org/libc`) and passed at 1.5 GB - from cold, on one CPU, in
4.5 minutes (2.5 on two). On a smaller machine, build the image on
another one and bring it over:
`docker save ghcr.io/mixeme/selfpost:<tag> | ssh <host> docker load`.
Swap would give the compiler room too, but was not tried.
- **Disk: about 3 GB free while it builds** - the Go image (1.3 GB), the
downloaded modules (0.6 GB), the compile step (0.4 GB) and the image
(315 MB). Each rebuild leaves another 0.4 GB compile step in Docker's build
cache (the test server had gathered 16 GB of them in a week);
`docker builder prune` gives it back.
**Data, under `./data`.** What grows, and what bounds it:
- **The send log** - the main driver: a row per recipient, with the
`mail.log` lines Postfix wrote about it, about 2-3 KB a message, kept for
the send-log retention (90 days by default, Server › Settings). Worked
out from that: 1 000 messages a day keep about 250 MB, 10 000 about
2.5 GB.
- **`mail.log`** - today's file and 14 rotated, compressed ones. About
750 bytes of log a message before compression, and the noise of scanners
on port 25 when it is open (400 KB a day on the test server). Worked out
from that: under 20 MB in all at 10 000 messages a day.
- **The mail queue** (`/data/postfix/queue`) - empty while mail flows. While
a receiving server, or an inbound domain's upstream, does not take mail,
it holds that mail up to the queue lifetime (5 days by default, [Queue and
System log](#queue-and-system-log)): leave room for an outage's worth -
on port 25 a message may be up to `INBOUND_MESSAGE_SIZE_LIMIT` (25 MiB).
Postfix itself refuses mail with `452 4.3.1 Insufficient system storage`
once the free space is under 1.5 times a listener's message size limit
(Postfix 3.10.13, `src/smtpd/smtpd_check.c`, `smtpd_check_queue()`).
- **The inbound log** keeps at most 10 000 rows; DMARC reports, the DKIM
keys and the rest of the database are small.
A full backup holds the database, the DKIM keys, the SASL credentials, the
deployment files and `certs/`, so it is about the size of the send log; `mail.log` and
the queue are left out of it ([Full backup and
restore](#full-backup-and-restore)).
### Ports
`deploy/docker-compose.yml` maps **465**, **587**, and **25** to the host. Port