Ubuntu 22.04 安装 Modoboa 指南

在 Ubuntu 22.04 上以 pip/venv+systemd 主线实测安装 Modoboa 2.11.1 面板核心:系统依赖、PostgreSQL/Redis、Nginx+uWSGI、后台进程托管、登录与 API 双验证及高频排障实录。

Modoboa邮件服务器Modoboa2026/10/21

Ubuntu 22.04 安装 Modoboa 指南

目标:在一台全新的 Ubuntu 22.04 LTS 服务器上,把 Modoboa 2.11.1(管理面板核心 + PostgreSQL + Redis + Nginx/uWSGI + 后台任务进程)完整跑起来并通过登录与 API 双验证。本篇所有命令与回显均在下述实测环境逐条执行并照实记录;如需"面板 + Postfix + Dovecot + 反垃圾"整台邮件服务器的一键全家桶,见第四章方案 A(官方流程,非本篇实测)。

一、环境信息

  • 实测环境:Ubuntu 22.04.5 LTS(jammy),内核 5.15,Python 3.10.12,systemd 运行模式
  • 组件版本:Modoboa 2.11.1(PyPI,2026-10-09 发布);PostgreSQL 14(Ubuntu 22.04 软件源);Redis 6.0.16;Nginx 1.18.0;uWSGI 2.0.20-4(Ubuntu 软件源)
  • 实测时间:2026-10-21
  • 部署路径约定:venv 与实例目录分别为 /opt/modoboa/env、/home/modoboa/instance(与官方 Manual Installation 文档路径约定一致)
  • 域名约定:mail.example.com(示例域名,生产替换为你自己的 FQDN 并解析到本机)

二、前置条件

  1. 一台全新 Ubuntu 22.04 LTS 服务器(物理机/虚拟机均可),可访问公网软件源;内存建议 2GB 以上(官方要求安装期编译依赖需 2GB,modoboa-installer README,查询日期 2026-10-21)。
  2. 服务器已设置 FQDN:编辑 /etc/hostname 为 mail,并在 /etc/hosts 添加 127.0.0.1 mail.example.com mail(生产环境应为公网解析)。
  3. 具备 sudo 权限的普通账号;/tmp 分区未挂 noexec(依赖编译需要可执行位,官方 README 警告项)。
  4. 端口占用检查:Modoboa 面板需要 80(HTTP)/443(HTTPS),数据库 5432,Redis 6379,策略守护默认 9999;确认无冲突(本篇实测环境为 22/53/80/631/3128/3306/5432/6010/6081/6082/6379/8080 中 80 未占用,5432/6379 由本机新建服务占用属预期)。
  5. Python 与编译链就绪(第三章统一安装)。

三、版本选型说明

  • 发行形态:Modoboa 官方不提供容器发行(modoboa 组织下无 docker 仓库,2026-10-21 核查),标准形态就是"原生 Linux + pip/venv + systemd",本章即按此路线。
  • 版本选择:安装 PyPI 最新稳定版 2.11.1;需要锁版本时用 pip install modoboa==<版本>;升级统一走 pip install --upgrade modoboa 后重跑迁移(见第八章)。
  • 数据库选择:官方支持 PostgreSQL 与 MySQL/MariaDB(install 文档 dburl 语法),本篇选 PostgreSQL(官方推荐与 install 文档主例)。
  • Web 栈选择:官方 Web server 文档给出 Nginx+uWSGI 与 Apache+mod_wsgi 两套模板,本篇选 Nginx+uWSGI(Ubuntu 软件源可直接安装,配置模板最贴近官方)。

四、方案 A:官方一键安装器(整台邮件服务器,官方流程)

适用场景:从零起步要一台"能收发邮件"的完整服务器(Modoboa 面板 + Postfix + Dovecot + 反垃圾 + OpenDKIM + Radicale 全家桶)。以下流程摘自官方 modoboa-installer README(查询日期 2026-10-21),本篇未在实测环境执行方案 A,输出细节以官方文档为准:

# 前置:全新 Debian 12+ / Ubuntu 20.04+,FQDN 已设置,2GB+ 内存,/tmp 未挂 noexec
git clone https://github.com/modoboa/modoboa-installer
cd modoboa-installer
sudo python3 run.py <your domain>      # 例:sudo python3 run.py example.com
  • 首次运行会生成 installer.cfg 配置文件(含数据库口令、证书、反垃圾引擎等段落),按需修改后重新执行同一命令即开始安装。
  • 支持参数:--debug、--force、--stop-after-configfile-check(只生成配置文件即停)、--version=<X.X.X>(安装指定 Modoboa 版本)。
  • 官方警告:口令中含特殊字符可能导致安装失败;安装模式(upgrade 模式)标注为 experimental。

若只需要管理面板本身(本篇实测主线,不连带 MTA/MDA),用方案 B。

五、方案 B:手动安装 Modoboa 核心面板(本篇实测主线)

5.1 安装系统依赖

按官方 Manual Installation 文档的 Debian/Ubuntu 软件包清单执行(另含 PostgreSQL、Redis、Nginx):

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  build-essential python3-dev python3-venv libxml2-dev libxslt-dev \
  libjpeg-dev librrd-dev rrdtool libffi-dev libssl-dev pkg-config \
  libcairo2-dev postgresql postgresql-contrib redis-server nginx

实测回显(节选):

Setting up postgresql-14 (14.19-0ubuntu0.22.04.1) ...
Creating new PostgreSQL cluster 14/main ...
...
Processing triggers for man-db (2.10.1-1) ...

⚠️ 排障实录:若通过 HTTP 代理安装,apt-get install 可能出现 E: Failed to fetch ... 502 Bad Gateway(实测发生,代理对部分源不稳定)。处理:直接重跑同一条安装命令,apt 会续传已完成部分;或改直连源。

再补装 Web 栈与后续验证工具(官方"Recommend packages for debian"推荐 uwsgi 系统包):

sudo DEBIAN_FRONTEND=noninteractive apt-get install -y uwsgi uwsgi-plugin-python3 curl

5.2 创建专用用户与虚拟环境

官方推荐以专用系统用户运行,并用 venv 隔离依赖:

sudo useradd -m -s /bin/bash modoboa
sudo mkdir -p /opt/modoboa && sudo chown modoboa:modoboa /opt/modoboa
sudo -u modoboa -i bash -c 'python3 -m venv /opt/modoboa/env'

5.3 pip 安装 Modoboa

sudo -u modoboa -i bash -c '/opt/modoboa/env/bin/pip install --upgrade pip'
sudo -u modoboa -i bash -c '/opt/modoboa/env/bin/pip install modoboa "psycopg[binary]>=3.1"'

实测回显(节选,完整依赖树见 PyPI):

Installing collected packages: pytz, progressbar33, oath, wassima, urllib3, uritemplate, tzdata, typing-extensions, sqlparse, six, rrdtool-bindings, rpds-py, qrcode, qh3, pyyaml, python-magic, pycparser, psycopg-binary, pillow, phonenumbers, packaging, oauthlib, lxml, libpass, jh2, inflection, idna, html2text, h11, filelock, feedparser-sgmllib, dnspython, django-environ, defusedxml, click, charset-normalizer, certifi, bcrypt, attrs, async-timeout, aiosmtplib, urllib3-future, sievelib, requests, reportlab, referencing, redis, python-dateutil, psycopg, lxml_html_clean, feedparser, cffi, asgiref, vobject, requests-oauthlib, requests-file, niquests, jsonschema-specifications, icalendar, django, cryptography, croniter, x-wr-timezone, tldextract, rq, ovh, jwcrypto, jsonschema, fido2, djangorestframework, django-xforwardedfor-middleware, django-reversion, django-rename-app, django-phonenumber-field, django-otp, django-filter, django-cors-headers, dj-database-url, recurring-ical-events, drf-spectacular, drf-nested-routers, django-rq, django-oauth-toolkit, icalendar-searcher, caldav, modoboa

Successfully installed django-5.2.17 djangorestframework-3.18.3 django-oauth-toolkit-3.4.1 django-rq-4.2.0 drf-spectacular-0.30.0 modoboa-2.11.1 psycopg-3.3.6 redis-8.1.0 rq-2.12.0 ...

版本核对(实测回显):

$ /opt/modoboa/env/bin/pip show modoboa | head -8
Name: modoboa
Version: 2.11.1
Summary: Mail hosting made simple
Home-page: http://modoboa.org/
Author:
Author-email: Antoine Nguyen <tonio@ngyn.org>
License: ISC License

5.4 准备 PostgreSQL

sudo -u postgres psql -c "CREATE USER modoboa WITH PASSWORD 'q1w2e3r4';"
sudo -u postgres psql -c 'CREATE DATABASE modoboa OWNER modoboa;'

实测回显:

CREATE ROLE
CREATE DATABASE

5.5 部署实例(deploy)

先看官方参数全景(实测回显):

$ source /opt/modoboa/env/bin/activate
$ modoboa-admin.py help deploy
usage: modoboa-admin.py deploy [-h] [--collectstatic]
                               [--dburl DBURL [DBURL ...]]
                               [--redisurl REDISURL] [--domain DOMAIN]
                               [--lang LANG] [--timezone TIMEZONE] [--devel]
                               [--extensions [EXTENSIONS ...]]
                               [--dont-install-extensions]
                               [--admin-username ADMIN_USERNAME]
                               name

Create a fresh django project (calling startproject) and apply Modoboa
specific settings.

positional arguments:
  name                  The name of your Modoboa instance

options:
  -h, --help            show this help message and exit
  --collectstatic       Run django collectstatic command
  --dburl DBURL [DBURL ...]
                        A database-url with a name
  --redisurl REDISURL   A Redis URL (for example
                        unix:///var/run/redis/redis.sock?db=0 when Redis only
                        listens on a unix socket)
  --domain DOMAIN       The domain under which you want to deploy modoboa
  --lang LANG           Set the default language
  --timezone TIMEZONE   Set the local timezone
  --devel               Create a development instance
  --extensions [EXTENSIONS ...]
                        The list of extension to deploy
  --dont-install-extensions
                        Do not install extensions using pip
  --admin-username ADMIN_USERNAME
                        Username of the initial super administrator

执行部署(非交互、不装扩展、指定域名与数据库):

sudo -u modoboa -i bash -c 'source /opt/modoboa/env/bin/activate && \
  modoboa-admin.py deploy instance --collectstatic \
  --domain mail.example.com \
  --dburl default:postgres://modoboa:q1w2e3r4@localhost/modoboa \
  --dont-install-extensions --admin-username admin'

实测结论:deploy 成功时静默无任何输出(退出码 0),验证靠目录与后续登录:

$ ls /home/modoboa/instance/
frontend  instance  manage.py  media  sitestatic

⚠️ 排障实录(三个高频坑,均为实测复现):

  1. Error loading psycopg2 or psycopg module → 缺数据库驱动,先 pip install "psycopg[binary]>=3.1"(官方 Manual Installation 明确要求,漏装必报)。
  2. ImportError: failed to find libmagic. Check your installation → 缺系统库 libmagic1,sudo apt-get install -y libmagic1 后重试(DMARC 组件依赖 python-magic)。
  3. CommandError: '/home/modoboa/instance' already exists → 上次 deploy 半途失败残留了目录;清理 rm -rf /home/modoboa/instance 后重跑(deploy 不会复用半成品目录)。另外 deploy 的实例名必须是合法 Python 标识符(如 instance),带连字符的名字会报 is not a valid project name。

5.6 设置超级管理员口令

静默部署创建的 admin 账号默认没有可用口令,用 manage.py 设置:

sudo -u modoboa -i bash -c 'source /opt/modoboa/env/bin/activate && \
  cd /home/modoboa/instance && python manage.py shell -c \
  "from modoboa.core.models import User; u=User.objects.get(username=\"admin\"); u.set_password(\"q1w2e3r4\"); u.save(); print(\"password set\")"'

实测回显:

password set

5.7 uWSGI 应用服务

/etc/uwsgi/apps-available/modoboa.ini(来自官方 Web server 文档模板,按本机路径改写):

[uwsgi]
plugins = python3
uid = modoboa
gid = modoboa
virtualenv = /opt/modoboa/env
chdir = /home/modoboa/instance
module = instance.wsgi:application
socket = /run/uwsgi/app/modoboa/socket
chmod-socket = 666
processes = 4
harakiri = 60
vacuum = true
master = true
sudo ln -sf /etc/uwsgi/apps-available/modoboa.ini /etc/uwsgi/apps-enabled/modoboa.ini
sudo mkdir -p /run/uwsgi/app && sudo chown modoboa:modoboa /run/uwsgi/app
sudo systemctl restart uwsgi

5.8 Nginx 站点

/etc/nginx/sites-available/modoboa(官方模板:API/账号走 uWSGI,其余静态走 Vue 前端构建产物):

upstream modoboa {
    server unix:/run/uwsgi/app/modoboa/socket fail_timeout=0;
}

server {
    listen 80;
    listen [::]:80;
    server_name mail.example.com;
    root /home/modoboa/instance;

    access_log /var/log/nginx/modoboa-access.log;
    error_log /var/log/nginx/modoboa-error.log;

    client_max_body_size 10M;

    location /sitestatic/ {
        try_files $uri $uri/ =404;
    }

    location /media/ {
        try_files $uri $uri/ =404;
    }

    location ~ ^/(api|accounts|autodiscover) {
        include uwsgi_params;
        uwsgi_param UWSGI_SCRIPT instance.wsgi:application;
        uwsgi_pass modoboa;
    }

    location / {
        alias /home/modoboa/instance/frontend/;
        index index.html;
        expires -1;
        add_header Pragma "no-cache";
        add_header Cache-Control "no-store, no-cache, must-revalidate";

        try_files $uri $uri/ /index.html = 404;
    }
}
sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -sf /etc/nginx/sites-available/modoboa /etc/nginx/sites-enabled/modoboa
sudo nginx -t && sudo systemctl restart nginx

实测回显:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

5.9 后台任务进程(systemd 托管)

Modoboa 面板正常工作还需要策略守护与 RQ worker 常驻(官方 Manual Installation 以 supervisor 示例,本篇按 Ubuntu 惯例改写为 systemd 原生单元)。

/etc/systemd/system/modoboa-policyd.service:

[Unit]
Description=Modoboa Policy Daemon
After=network.target redis-server.service

[Service]
Type=simple
User=modoboa
Group=modoboa
WorkingDirectory=/home/modoboa/instance
ExecStart=/opt/modoboa/env/bin/python /home/modoboa/instance/manage.py policy_daemon
Restart=on-failure

[Install]
WantedBy=multi-user.target

/etc/systemd/system/modoboa-worker-modoboa.service(普通队列):

[Unit]
Description=Modoboa RQ Worker (modoboa queue)
After=network.target redis-server.service

[Service]
Type=simple
User=modoboa
Group=modoboa
WorkingDirectory=/home/modoboa/instance
ExecStart=/opt/modoboa/env/bin/python /home/modoboa/instance/manage.py rqworker modoboa
Restart=on-failure

[Install]
WantedBy=multi-user.target

/etc/systemd/system/modoboa-worker-privileged.service(特权队列,需 root):

[Unit]
Description=Modoboa RQ Worker (privileged queue)
After=network.target redis-server.service

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/home/modoboa/instance
ExecStart=/opt/modoboa/env/bin/python /home/modoboa/instance/manage.py rqworker privileged
Restart=on-failure

[Install]
WantedBy=multi-user.target

启用并启动(实测回显):

$ sudo systemctl daemon-reload
$ sudo systemctl enable modoboa-policyd modoboa-worker-modoboa modoboa-worker-privileged
Created symlink /etc/systemd/system/multi-user.target.wants/modoboa-policyd.service → /etc/systemd/system/modoboa-policyd.service.
Created symlink /etc/systemd/system/multi-user.target.wants/modoboa-worker-modoboa.service → /etc/systemd/system/modoboa-worker-modoboa.service.
Created symlink /etc/systemd/system/multi-user.target.wants/modoboa-worker-privileged.service → /etc/systemd/system/modoboa-worker-privileged.service.
$ sudo systemctl start modoboa-policyd modoboa-worker-modoboa modoboa-worker-privileged
$ systemctl is-active modoboa-policyd modoboa-worker-modoboa modoboa-worker-privileged
active
active
active

状态抽样(实测回显):

$ systemctl status modoboa-policyd --no-pager -n 3
● modoboa-policyd.service - Modoboa Policy Daemon
     Loaded: loaded (/etc/systemd/system/modoboa-policyd.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-10-21 01:00:58 UTC; 39min ago
   Main PID: 8714 (python)
      Tasks: 2 (limit: 94371)
     Memory: 84.8M
        CPU: 650ms
     CGroup: /system.slice/modoboa-policyd.service
             └─8714 /opt/modoboa/env/bin/python /home/modoboa/instance/manage.py policy_daemon

Oct 21 01:00:58 mail.example.com systemd[1]: Started Modoboa Policy Daemon.
Oct 21 01:00:59 mail.example.com modoboa.policyd[8714]: INFO Started policy daemon

5.10 验证

端口监听(实测回显,80=Nginx、9999=策略守护、5432=PostgreSQL、6379=Redis):

$ ss -ltn
LISTEN 0      511          0.0.0.0:80         0.0.0.0:*
LISTEN 0      100        127.0.0.1:9999       0.0.0.0:*
LISTEN 0      511        127.0.0.1:6379       0.0.0.0:*
LISTEN 0      244        127.0.0.1:5432       0.0.0.0:*
LISTEN 0      511             [::]:80            [::]:*

面板可达与登录闭环(实测回显,-H 'Host: mail.example.com' 用于让请求匹配 ALLOWED_HOSTS):

$ curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: mail.example.com' http://127.0.0.1/
200
$ # 模拟登录:取 CSRF → 提交凭据 → 302 跳转即登录成功
$ curl -s -c jar.txt -H 'Host: mail.example.com' http://127.0.0.1/accounts/login/ >/dev/null
$ CSRF=$(grep csrftoken jar.txt | awk '{print $7}')
$ curl -s -b jar.txt -c jar.txt -H 'Host: mail.example.com' \
    -H 'Referer: http://mail.example.com/accounts/login/' \
    --data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4' \
    --data-urlencode "csrfmiddlewaretoken=$CSRF" \
    -o /dev/null -w 'login POST: %{http_code} -> %{redirect_url}\n' \
    http://127.0.0.1/accounts/login/
login POST: 302 -> http://127.0.0.1/

浏览器访问 http://mail.example.com/(或服务器 IP)即见 Modoboa 登录页,用 admin 与上一步口令登录进入管理面板。

API 验证:先生成 API Token(见同专栏《Modoboa 2.11.1 管理 API 使用详解》),再实测:

$ curl -s -H 'Host: mail.example.com' -H "Authorization: Token <TOKEN>" \
    http://127.0.0.1/api/v2/account/me/ | head -c 400
{"date_joined":"2026-10-21T00:39:21.174547Z","language":"en","phone_number":null,
"secondary_email":null,"first_name":"","last_name":"","timezone":null,
"is_superuser":true,"is_active":true,"master_user":false,"username":"admin","role":"SuperAdmins","id":2}

5.11 上线后收尾:改为开机自启并固化 cron

  1. 上述 systemd 单元均已 enable;uwsgi、nginx、postgresql、redis-server 为系统包默认自启。
  2. 会话清理任务加入系统 cron(官方文档要求):sudo crontab -e 添加一行 0 0 * * * /opt/modoboa/env/bin/python /home/modoboa/instance/manage.py clearsessions。

六、多方案对比与选择建议

维度方案 A:modoboa-installer 一键全家桶方案 B:手动 pip/venv 面板核心(本篇实测)
交付物整台邮件服务器(面板+Postfix+Dovecot+反垃圾+DKIM+Radicale)Modoboa 管理面板核心(本篇实测)+ 自选组件
操作复杂度低(一条命令,交互确认配置)中(约 8 个步骤,全程可控)
组件控制粒度低(安装器统一编排)高(每组件独立选型/升级)
与既有 MTA/MDA 集成不适合(会重装覆盖)适合(只装面板,映射表/策略接入既有 Postfix/Dovecot)
排障难度高(一层黑盒)低(每步可回看日志)
适用人群从零建站、要"开箱即收发"已有邮件栈/自动化需求/需精细管控

选择建议:全新服务器且目标就是完整邮件服务 → 方案 A;已有 Postfix/Dovecot、CI 自动化、或只需面板与 API 能力 → 方案 B。两方案不混用(安装器会接管并覆盖系统组件配置)。

七、配置说明

7.1 实例配置文件

部署生成的核心配置在 /home/modoboa/instance/instance/settings.py(Django 标准),关键项(实测文件节选,注释为本篇补充):

# 安全密钥:deploy 自动生成,切勿丢失(丢失=无法解密会话/重置口令哈希盐)
SECRET_KEY = '...自动生成...'

DEBUG = False

# deploy --domain 写入;用其他域名/IP 访问会 400
ALLOWED_HOSTS = [
    'mail.example.com',
]

# 生效应用集(元组;含 webmail/sievefilters/calendars 等随主包内置的应用)
MODOBOA_APPS = (
    'modoboa',
    'modoboa.core',
    'modoboa.lib',
    'modoboa.admin',
    'modoboa.autoconfig',
    'modoboa.transport',
    'modoboa.relaydomains',
    'modoboa.limits',
    'modoboa.parameters',
    'modoboa.dnstools',
    'modoboa.policyd',
    'modoboa.maillog',
    'modoboa.pdfcredentials',
    'modoboa.dmarc',
    'modoboa.imap_migration',
    'modoboa.autoreply',
    'modoboa.sievefilters',
    'modoboa.contacts',
    'modoboa.calendars',
    'modoboa.webmail',
    # Modoboa extensions here.
)

INSTALLED_APPS += MODOBOA_APPS

# Cookie 安全开关:启用 HTTPS 前保持 True;
# 仅 HTTP 内网验证时必须改 False,否则浏览器不回传 Cookie,登录会静默失败(本篇实测踩坑)
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True

7.2 平台参数(管理面板/数据库层)

面板级参数(反垃圾、DKIM、日志、PDF 凭据、Sieve、自动回复等分组)存于数据库、经 Settings → Modoboa → Parameters 界面修改,其默认值与帮助文案由各应用的参数注册表提供;逐组解析见同专栏《Modoboa 2.11.1 配置参数详解》。

7.3 与 Postfix/Dovecot 集成要点(方案 B 进阶)

  • Postfix 收信映射:Modoboa 提供映射表生成命令 python manage.py generate_postfix_maps(manage.py help 可见),产物写入 /var/lib/modoboa/ 下 relay_domains、virtual_mailbox_domains、virtual_mailbox_maps、virtual_alias_maps 等 .cf 文件,Postfix 的 main.cf 按文件指向查询数据库。
  • 发送限额:Postfix smtpd_recipient_restrictions 加入 check_policy_service inet:127.0.0.1:9999 接入本篇 5.9 的策略守护(限额在面板按域名/账号配置)。
  • Dovecot 账号验证与 Sieve:SQL 查询配置 + dovecot 队列 worker 推送 Sieve 脚本(以 vmail 身份运行,官方 Manual Installation 给出 systemd 样例)。

八、常见问题(FAQ)

Q1:登录页能打开,但输入正确口令后仍回到登录页/无反应? 检查 settings.py 的 CSRF_COOKIE_SECURE/SESSION_COOKIE_SECURE:仅 HTTP 访问时必须为 False(本篇实测:改 False 并 systemctl restart uwsgi 后,登录 POST 返回 302 即成功)。生产请配 TLS 后恢复 True。

Q2:访问报 400 Bad Request? 请求的 Host 不在 ALLOWED_HOSTS。deploy --domain 只写入了部署域名;临时用 IP 访问需把 IP 加进列表并重启 uwsgi。

Q3:面板 403、日志里 Nginx 报 permission denied? Nginx(www-data)无法穿越 /home/modoboa。chmod o+x /home/modoboa 后即可(本篇实测踩坑)。

Q4:deploy 报 Error loading psycopg2 or psycopg module? 漏装数据库驱动:pip install "psycopg[binary]>=3.1"(官方文档要求项,见 5.5 排障实录)。

Q5:deploy 报 ImportError: failed to find libmagic? apt-get install -y libmagic1(DMARC 组件依赖)。

Q6:重跑 deploy 报 /home/modoboa/instance' already exists? 上次失败残留,rm -rf 该目录后重跑;deploy 不做增量复用。实例名必须为合法 Python 标识符。

Q7:如何升级 Modoboa?

sudo -u modoboa -i bash -c '/opt/modoboa/env/bin/pip install --upgrade modoboa'
sudo -u modoboa -i bash -c 'cd /home/modoboa/instance && source /opt/modoboa/env/bin/activate && python manage.py migrate && python manage.py collectstatic --noinput'
sudo systemctl restart uwsgi modoboa-policyd modoboa-worker-modoboa modoboa-worker-privileged

升级前务必备份数据库;锁版本升级用 pip install modoboa==<目标版本>。

Q8:RQ worker(privileged 队列)为什么要 root? 该队列处理需要特权的任务(如写系统目录),官方 Manual Installation 明确该队列以 root 运行;其余队列用 modoboa 用户。

九、卸载与清理

# 1. 停止并禁用 Modoboa 自建单元
sudo systemctl disable --now modoboa-policyd modoboa-worker-modoboa modoboa-worker-privileged
sudo rm -f /etc/systemd/system/modoboa-*.service && sudo systemctl daemon-reload

# 2. 下线 Web 站点
sudo rm -f /etc/nginx/sites-enabled/modoboa /etc/nginx/sites-available/modoboa
sudo rm -f /etc/uwsgi/apps-enabled/modoboa.ini /etc/uwsgi/apps-available/modoboa.ini
sudo systemctl reload nginx && sudo systemctl restart uwsgi

# 3. 删除数据与应用(不可逆,先确认备份)
sudo -u postgres psql -c 'DROP DATABASE IF EXISTS modoboa;'
sudo -u postgres psql -c 'DROP USER IF EXISTS modoboa;'
sudo rm -rf /home/modoboa /opt/modoboa

十、参考链接