Ver código fonte

fix: tune mail runtime for low resource hosts

AI-Co-Authored-By: Codex
chendeben 1 mês atrás
pai
commit
d29071fd8f
4 arquivos alterados com 25 adições e 2 exclusões
  1. 2 0
      .env.example
  2. 3 2
      docker-compose.yml
  3. 4 0
      docker/dovecot/mailhub.conf
  4. 16 0
      test/dovecot-config.test.js

+ 2 - 0
.env.example

@@ -39,6 +39,8 @@ DOVECOT_AUTH_ENABLED=true
 DOVECOT_AUTH_HOST=0.0.0.0
 DOVECOT_AUTH_PORT=3001
 DOVECOT_AUTH_SECRET_FILE=/run/secrets/dovecot_auth_secret
+# Low-resource hosts should keep CPU-bound password verification concurrency modest.
+UV_THREADPOOL_SIZE=2
 # Relative path for host-side migration commands. Compose overrides this with /data/maildir.
 MAILDIR_ROOT=./data/maildir
 MAILDIR_SYNC_INTERVAL_MS=300000

+ 3 - 2
docker-compose.yml

@@ -12,6 +12,7 @@ services:
       POSTFIX_LOG_FILE: /data/postfix-logs/mail.log
       MAIL_ACCESS_BACKEND: dovecot
       MAILDIR_ROOT: /data/maildir
+      UV_THREADPOOL_SIZE: ${UV_THREADPOOL_SIZE:-2}
       DOVECOT_AUTH_ENABLED: "true"
       DOVECOT_AUTH_HOST: 0.0.0.0
       DOVECOT_AUTH_PORT: 3001
@@ -39,8 +40,8 @@ services:
       test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
       interval: 30s
       timeout: 5s
-      retries: 3
-      start_period: 15s
+      retries: 4
+      start_period: 120s
 
   dovecot:
     image: dovecot/dovecot:2.4.4

+ 4 - 0
docker/dovecot/mailhub.conf

@@ -41,6 +41,8 @@ namespace inbox {
 
 service imap-login {
   chroot =
+  process_min_avail = 1
+  process_limit = 24
 
   inet_listener imaps {
     ssl = yes
@@ -49,6 +51,8 @@ service imap-login {
 
 service pop3-login {
   chroot =
+  process_min_avail = 0
+  process_limit = 8
 
   inet_listener pop3s {
     ssl = yes

+ 16 - 0
test/dovecot-config.test.js

@@ -46,6 +46,22 @@ test('Compose delegates public IMAP and POP3 ports to rootless Dovecot', () => {
   assert.match(compose, /doveadm service status imap-login pop3-login/);
 });
 
+test('MailHub app healthcheck allows slow production startup before Dovecot depends on it', () => {
+  assert.match(appService, /healthcheck:[\s\S]*interval: 30s/);
+  assert.match(appService, /healthcheck:[\s\S]*retries: 4/);
+  assert.match(appService, /healthcheck:[\s\S]*start_period: 120s/);
+  assert.match(dovecotService, /condition: service_healthy/);
+});
+
+test('Dovecot and app defaults stay modest on low-resource mail hosts', () => {
+  assert.match(appService, /UV_THREADPOOL_SIZE: \$\{UV_THREADPOOL_SIZE:-2\}/);
+  assert.match(envExample, /^UV_THREADPOOL_SIZE=2$/m);
+  assert.match(mailConfig, /service imap-login \{[\s\S]*process_min_avail = 1/);
+  assert.match(mailConfig, /service imap-login \{[\s\S]*process_limit = 24/);
+  assert.match(mailConfig, /service pop3-login \{[\s\S]*process_min_avail = 0/);
+  assert.match(mailConfig, /service pop3-login \{[\s\S]*process_limit = 8/);
+});
+
 test('Dovecot uses Lua passdb, a static rootless userdb, and Maildir storage', () => {
   assert.match(authConfig, /passdb lua \{/);
   assert.match(authConfig, /SUBMISSION_TLS_CERT = %\{env:SUBMISSION_TLS_CERT\}/);