Ubuntu 22.04 安装 Accent v1.32.1 指南

在 Ubuntu 22.04 上源码构建 Accent v1.32.1 OTP Release 并 systemd 托管:OTP 29.1.2/Elixir 1.20.4/Node 24/PG14 工具链安装、前后端构建、迁移、验证,含离线 Release 迁移方案与 build-production-inline 等实测坑。

AccentAccent翻译管理ElixirUbuntu2026/10/27

Ubuntu 22.04 安装 Accent v1.32.1 指南

目标:在 Ubuntu 22.04 服务器上从零构建并运行 Accent v1.32.1(Elixir/Phoenix 源码 → OTP Release → systemd 托管),含在线与离线两种方案。全文命令与回显均已在 Ubuntu 22.04.5 LTS 实测环境逐条验证通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64,systemd)
  • 目标软件:Accent v1.32.1(GitHub tag v1.32.1,commit 58be7e0,2026-10-16 发布)
  • 运行时栈(实测落位版本):Erlang/OTP 29.1.2、Elixir 1.20.4、Node.js v24.22.1(NodeSource)、PostgreSQL 14.24(jammy 官方仓库)
  • 监听端口:4000(HTTP/Web 与 GraphQL 同端口)
  • 部署路径:源码 /opt/accent,Release 产物 /opt/accent-release,systemd 单元 accent.service

⚠️ 网络说明:OTP/Elixir 预编译包托管于 builds.hex.pm(境外 CDN),国内直连可能缓慢或中断,实测经代理(192.168.1.62:7897)下载稳定;NodeSource 与 jammy 仓库国内直连可用。若下载失败请按「官方源 → 代理」降级链处理。

二、前置条件

  • 一台干净的 Ubuntu 22.04 服务器,root 或具备 sudo 权限的账号
  • 内存 ≥ 2 GB(前端 vite 构建阶段峰值较高,实测 1 GB 构建会 OOM,建议 2 GB 以上)
  • 磁盘 ≥ 10 GB(OTP+Node 依赖+构建产物约 2.5 GB)
  • 可访问:jammy apt 源、deb.nodesource.com、builds.hex.pm、github.com、registry.npmjs.org、hex.pm

三、版本选型说明

Accent 官方只发布两种交付形态:GitHub 源码 tag 与官方镜像(mirego/accent,镜像形态见《Accent v1.32.1 Docker Compose 部署指南》)。没有 deb/rpm 包、没有预编译 Release tarball。因此在裸机/虚拟机上安装的唯一路径是源码构建 OTP Release,本文方案 A 即此路径(官方 Dockerfile 的内核同样是这条路径)。

版本号选取说明:

  • 服务端最新稳定 tag:v1.32.1(2026-10-16),本文实测版本;
  • 官方 README 要求 erlang ~> 26.1、elixir ~> 1.15——该约束滞后于实际,v1.32.1 实测在 OTP 29.1.2 + Elixir 1.20.4 上构建与运行正常(官方 CI 同样已升级到 OTP 27+ 线),本文采用该组合并如实记录;
  • Node.js 仅用于构建前端(vite/Ember),运行时不需要;官方要求 >= 16.19,实测 NodeSource 24.x 可用。

四、方案 A:在线源码构建 OTP Release(推荐)

4.1 安装基础依赖

apt-get update
apt-get install -y git curl wget unzip build-essential \
  libssl-dev libncurses5-dev libpq-dev ca-certificates gnupg

4.2 安装 Erlang/OTP 29.1.2(hex.pm 预编译包)

hex.pm 的 bob 构建服务提供按发行版编译的 OTP tarball,免去 30 分钟以上的源码编译:

cd /tmp
wget https://builds.hex.pm/builds/otp/amd64/ubuntu-22.04/OTP-29.1.2.tar.gz -O otp29.tar.gz
mkdir -p /usr/local/lib/erlang
tar xzf otp29.tar.gz -C /usr/local/lib/erlang --strip-components=1
/usr/local/lib/erlang/Install -minimal /usr/local/lib/erlang   # 修正安装内绝对路径
ln -sf /usr/local/lib/erlang/bin/* /usr/local/bin/

验证:

erl -eval 'io:format("~s~n",[erlang:system_info(otp_release)]),halt().' -noshell
# 回显:29

4.3 安装 Elixir 1.20.4(hex.pm 预编译 zip)

cd /tmp
wget https://builds.hex.pm/builds/elixir/v1.20.4-otp-29.zip -O elixir.zip
unzip -q elixir.zip -d /usr/local/lib/elixir
ln -sf /usr/local/lib/elixir/bin/* /usr/local/bin/
mix local.hex --force && mix local.rebar --force

验证(回显照抄):

elixir --version
# Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:...]
# Elixir 1.20.4 (compiled with Erlang/OTP 29)

⚠️ 注意:Elixir 预编译 zip 文件名带 -otp-29 后缀,必须与上一步 OTP 大版本对齐;混用 -otp-26 包与 OTP 29 会在编译期抛语法/行为不兼容错误。

4.4 安装 Node.js 24(NodeSource 仓库)

curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt-get install -y nodejs
node --version
# 回显:v24.22.1

4.5 安装并初始化 PostgreSQL 14

apt-get install -y postgresql
systemctl enable --now postgresql

创建应用角色与库(演示环境口令 q1w2e3r4):

su - postgres -c "psql -c \"CREATE ROLE accent LOGIN PASSWORD 'q1w2e3r4' CREATEDB;\""
# 回显:CREATE ROLE
su - postgres -c "createdb -O accent accent_prod"

💡 技术拓展:Accent 的数据库访问层是 Ecto(Elixir 生态标准 ORM),连接串格式为 postgresql://用户:口令@主机:端口/库名;官方要求 PostgreSQL >= 9.4,生产建议 14+。同类 ORM 对照:Rails 的 ActiveRecord、Django ORM——Ecto 的差异点在于「显式 changeset 校验」而非隐式模型回调。

4.6 拉取 Accent v1.32.1 源码

cd /opt
git clone https://github.com/mirego/accent.git
cd accent
git checkout v1.32.1
git describe --tags
# 回显:v1.32.1

4.7 编译后端依赖与前端资源

cd /opt/accent
export MIX_ENV=prod
mix deps.get --only prod
mix deps.compile

⚠️ 注意:mix deps.get 结束阶段可能输出依赖安全公告(实测命中 aka: CVE-2026-105963 — Secret key base exposed in stack trace arguments on wrong-typed Plug.Crypto arguments,来源 mix_audit/osv.dev)。该问题影响的是错误堆栈中密钥泄露风险,生产部署应确保错误页不外露;升级依赖属上游行为,本文不改版本锁定。

构建前端并内联到应用静态目录(这是关键步骤,选错脚本会导致运行时 500,见「八、常见问题」Q1):

cd /opt/accent/webapp
npm install
npm run build-production-inline
ls ../priv/static/webapp/index.html
# 回显:../priv/static/webapp/index.html

💡 说明:webapp/package.json 中有三个构建脚本——build(输出到默认 dist)、build-production(输出到 webapp-dist)、build-production-inline(输出到 ../priv/static/webapp)。OTP Release 运行时从 priv/static/webapp/index.html 读页面,只有 inline 变体与 Release 匹配。

编译 Elixir 工程:

cd /opt/accent
export MIX_ENV=prod
mix compile
# 回显节选:Compiling 339 files (.ex) / Generated accent app

⚠️ 若系统 locale 非 UTF-8,编译与运行期会出现警告 the VM is running with native name encoding of latin1 ...,处理:localectl set-locale LANG=C.UTF-8 并重新登录,或全局设置 ELIXIR_ERL_OPTIONS="+fnu"。

4.8 数据库迁移

cd /opt/accent
export MIX_ENV=prod \
  DATABASE_URL=postgresql://accent:q1w2e3r4@localhost/accent_prod \
  SECRET_KEY_BASE=$(openssl rand -hex 64)
mix ecto.migrate
# 回显节选:
# [info] == Running 20260603000000 Accent.Repo.Migrations.RemoveProjectLintEntriesIgnore.change/0 forward
# [info] == Migrated 20260603000000 in 0.0s

4.9 构建 OTP Release

cd /opt/accent
export MIX_ENV=prod
mix release
# 回显节选:
# * assembling accent-1.32.1 on MIX_ENV=prod
# Release created at _build/prod/rel/accent
ls _build/prod/rel/accent/bin/
# 回显:accent  accent.bat

4.10 部署 Release 与 systemd 托管

mkdir -p /opt/accent-release
cp -r /opt/accent/_build/prod/rel/accent/* /opt/accent-release/

cat > /etc/systemd/system/accent.service <<'EOF'
[Unit]
Description=Accent translation platform
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/accent-release
Environment=PORT=4000
Environment=DATABASE_URL=postgresql://accent:q1w2e3r4@localhost/accent_prod
Environment=SECRET_KEY_BASE=<替换为 openssl rand -hex 64 生成的固定值>
Environment=SIGNING_SALT=accent_signing_salt_b1
Environment=DUMMY_LOGIN_ENABLED=1
Environment=CANONICAL_URL=http://localhost:4000
ExecStart=/opt/accent-release/bin/accent start
ExecStop=/opt/accent-release/bin/accent stop
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now accent

⚠️ 注意:SECRET_KEY_BASE 必须为 64 字节随机串且在重启间保持固定,否则既有会话 Cookie 全部失效;DUMMY_LOGIN_ENABLED=1 是无密码登录(仅邮箱),仅限内网评估,生产改配 OAuth/OIDC(见《Accent v1.32.1 配置参数详解》)。

4.11 验证

systemctl is-active accent
# 回显:active

journalctl -u accent --no-pager | head -5
# 回显节选:
# [info] Running Accent.Endpoint with Bandit 1.13.0 at 0.0.0.0:4000 (http)
# [info] Access Accent.Endpoint at http://localhost:4000
# [info] LanguageTool was not configured. Use LANGUAGE_TOOL_LANGUAGES environment variable ...

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://localhost:4000/
# 回显:HTTP 200

curl -s http://localhost:4000/ | grep -oE 'version%22%3A%22[0-9.]+%22'
# 回显:version%22%3A%221.32.1%22   (即 version:1.32.1,前端元数据)

curl -s -X POST http://localhost:4000/graphql \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ __schema { queryType { name } } }"}'
# 回显:{"data":{"__schema":{"queryType":{"name":"RootQueryType"}}}}

至此,浏览器访问 http://<服务器IP>:4000,用任意邮箱(Dummy 登录)即可进入 Accent 控制台创建项目。

五、方案 B:离线 Release 包迁移部署

适用于目标机完全断网的内网场景:在一台与目标机同 OS 版本的联网构建机上完成 4.1~4.9,然后打包迁移。

构建机:

cd /opt/accent/_build/prod/rel
tar czf accent-1.32.1-otp29-ubuntu22.04.tar.gz accent/
sha256sum accent-1.32.1-otp29-ubuntu22.04.tar.gz

目标机(仍需预装 PostgreSQL 与 libssl3、libncurses5 等运行库):

apt-get install -y postgresql libssl3 libncurses5
mkdir -p /opt/accent-release
tar xzf accent-1.32.1-otp29-ubuntu22.04.tar.gz -C /opt/accent-release --strip-components=1
# 建库/迁移(用 Release 内嵌命令,无需 mix):
/opt/accent-release/bin/accent eval "Accent.Release.migrate()"
# systemd 单元同 4.10

💡 说明:OTP Release 自带 ERTS(Erlang 运行时),目标机无需安装 Erlang/Elixir/Node——这正是 OTP Release 相对源码目录部署的最大优势。但 ERTS 与构建机的 glibc/OpenSSL 绑定,跨发行版(如构建于 22.04 跑在 24.04)不保证可用,离线包必须与目标系统同代。

六、方案对比与选择建议

维度方案 A 在线源码构建方案 B 离线 Release 迁移
目标机联网需要(构建期)不需要
目标机依赖Erlang/Elixir/Node/PG 全套仅 PG + 运行库
构建耗时15~30 分钟秒级(解包)
升级方式重新构建替换 tar 包
适用场景可联网服务器、需就地调整源码内网隔离、批量同构部署

选择建议:能联网的开发/测试环境直接走方案 A;生产内网一律走方案 B,构建机固定为「与生产同 OS 的构建专用机」。

七、配置说明

Accent 遵循 Twelve-Factor,全部配置走环境变量(systemd 单元 Environment= 注入)。安装期最少必须配置 4 项:

变量作用本文示例
DATABASE_URLPostgreSQL 连接串postgresql://accent:q1w2e3r4@localhost/accent_prod
SECRET_KEY_BASE会话 Cookie 加密密钥(64 字节)openssl rand -hex 64 生成
PORTHTTP 监听端口4000
CANONICAL_URL站点对外 URL(邮件/回调用)http://localhost:4000

完整 40+ 项变量(认证提供商、邮件、机器翻译、OpenTelemetry 等)见《Accent v1.32.1 配置参数详解》。

八、常见问题

Q1:服务 active 但访问首页 HTTP 500,日志报 could not read file ".../priv/static/webapp/index.html": no such file or directory? 根因:前端构建用了 npm run build-production(输出到 webapp-dist),而 Release 从 priv/static/webapp 读页面。修复:改用 npm run build-production-inline 重新构建后 mix release --overwrite 并重部署。本文实测复现并验证该修复路径。

Q2:cp -r 覆盖已部署 Release 时报 Text file busy? 根因:服务运行中覆盖正在执行的 beam.smp/epmd 等二进制。必须先 systemctl stop accent,拷贝完成后再 systemctl start accent。本文实测复现。

Q3:编译/运行期大量 native name encoding of latin1 警告? 系统 locale 不是 UTF-8。执行 localectl set-locale LANG=C.UTF-8 后重新登录,或在 systemd 单元加 Environment=ELIXIR_ERL_OPTIONS=+fnu。

Q4:启动日志出现 LanguageTool was not configured? 这是拼写检查增强功能 LanguageTool 未配置的语言列表提示,非错误;不需要拼写检查可忽略,需要则设置 LANGUAGE_TOOL_LANGUAGES=fr,en 等逗号分隔语言码。

Q5:jammy 仓库的 PostgreSQL 是 14,官方要求 >= 9.4,能用吗? 实测 v1.32.1 在 PostgreSQL 14.24 上迁移与运行全部正常;官方镜像配套文档常用 15/16。追求更高版本可加装 PGDG 官方仓库的 16。

九、卸载与清理

systemctl disable --now accent
rm -f /etc/systemd/system/accent.service && systemctl daemon-reload
rm -rf /opt/accent /opt/accent-release
su - postgres -c "dropdb accent_prod"
su - postgres -c "psql -c 'DROP ROLE accent;'"
# 如需一并移除运行时:apt-get purge -y postgresql* nodejs;rm -rf /usr/local/lib/erlang /usr/local/lib/elixir

十、参考链接