Phoenix(Elixir)中Gettext在Debian预发布环境无法加载翻译求助
遇到这种开发环境正常、预发布环境掉链子的问题确实闹心,结合你描述的情况(自定义Plug能正确解析并传递sv_se locale,翻译文件已推送),可以从以下几个方向逐步排查:
检查翻译文件的编译与存在性
Gettext在生产环境依赖编译后的.mo文件而非.po文件,你可以先确认Debian服务器上的priv/gettext/sv_se/LC_MESSAGES目录下是否存在对应的.mo文件。如果没有,手动执行MIX_ENV=prod mix gettext.compile --force重新编译翻译文件,再重启服务试试。另外,如果你是手动部署而非用mix release,要确保编译后的.mo文件也一起上传到服务器了。验证文件权限
Debian上运行Phoenix服务的系统用户,需要拥有读取priv/gettext目录及所有翻译文件的权限。可以用ls -l priv/gettext/sv_se/LC_MESSAGES/查看文件权限,确保运行服务的用户(比如www-data或者你自定义的用户)有读权限,必要时用chmod或chown调整。手动强制设置Locale测试
先排除Plug传递Locale的问题:在某个测试接口或页面的代码里,手动添加Gettext.put_locale(MyApp.Gettext, :sv_se),然后调用一个带翻译的函数(比如Gettext.dgettext(MyApp.Gettext, "errors", "invalid_email")),看返回的是翻译后的文本还是原文。如果手动设置后能正常加载翻译,那可能是Plug传递Locale的逻辑有隐藏问题(比如没正确传递到Gettext的上下文);如果还是不行,那问题就出在Gettext加载翻译文件的环节。检查Gettext的配置与路径
打开config/prod.exs确认Gettext的配置:- 有没有正确指定支持的locale列表:
config :my_app, MyApp.Gettext, locales: ["sv_se", "en"], default_locale: "en" - 有没有自定义
priv目录路径?如果有,要确保路径指向的目录确实存在翻译文件
另外,可以在代码里打印Application.app_dir(:my_app, "priv/gettext"),确认Gettext查找翻译文件的根路径是否正确,对应的路径下有没有sv_se的子目录。
- 有没有正确指定支持的locale列表:
开启Debug日志排查细节
在config/prod.exs里临时把日志级别调到debug:config :logger, level: :debug,然后重启服务,发起请求后查看日志:- 确认自定义Plug输出的Locale确实是
sv_se - 有没有Gettext相关的错误日志(比如“could not find translation file”之类的提示)
这些日志能帮你定位到具体是加载环节的哪一步出了问题。
- 确认自定义Plug输出的Locale确实是
清除编译缓存重新构建
有时候生产环境的编译缓存会导致新的翻译文件没被加载,你可以在Debian服务器上执行:MIX_ENV=prod mix clean MIX_ENV=prod mix compile --force MIX_ENV=prod mix phx.server彻底清除旧缓存后重新编译启动,看看是否能解决问题。
内容的提问来源于stack exchange,提问作者Alisso

