Phoenix 运维与部署(Elixir/BEAM)
生产可用的 Phoenix 应用依赖 release、运行时配置、遥测、集群与安全端点。BEAM 在配置正确时可支持滚动重启与监督树弹性。
Release 与运行时配置
构建与运行示例:
MIX_ENV=prod PHX_SERVER=true mix assets.deploy MIX_ENV=prod mix release _build/prod/rel/my_app/bin/my_app eval "IO.puts(:os.type())" _build/prod/rel/my_app/bin/my_app start
使用 config/runtime.exs 做环境驱动配置:
config :my_app, MyApp.Repo, url: System.fetch_env!("DATABASE_URL"), pool_size: String.to_integer(System.get_env("POOL_SIZE", "10")), ssl: true
config :my_app, MyAppWeb.Endpoint, url: [host: System.fetch_env!("PHX_HOST"), port: 443, scheme: "https"], http: [ip: {0,0,0,0}, port: String.to_integer(System.get_env("PORT", "4000"))], secret_key_base: System.fetch_env!("SECRET_KEY_BASE"), server: true
密钥:优先使用环境变量或密钥存储(AWS/GCP KMS、Vault),避免写入配置;用 mix phx.gen.secret 生成 SECRET_KEY_BASE。
集群与 PubSub/Presence
加入 libcluster 实现节点自动发现:
mix.exs deps
{:libcluster, "~> 3.3"}, {:phoenix_pubsub, "~> 2.1"},
application.ex
topologies = [ dns_poll: [ strategy: Cluster.Strategy.DNSPoll, config: [poll_interval: 5_000, query: "my-app.internal"], connect: {:net_adm, :ping} ] ]
children = [ {Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]}, {Phoenix.PubSub, name: MyApp.PubSub}, MyAppWeb.Endpoint ]
准则:各节点共享 secret_key_base 以保证会话签名一致;Presence 使用分布式 PubSub,启用前确保节点连通;蓝绿部署时保持 cookie 兼容。
遥测、日志与指标
安装 opentelemetry_phoenix 与 opentelemetry_ecto 获取追踪/指标;加入 Plug.Telemetry 与 LoggerJSON 或结构化日志;通过 :telemetry_poller 导出 VM 指标(reductions、内存、调度器)到 Prometheus/OpenTelemetry;生产设 LOGGER_LEVEL=info,仅在排障时用 :debug。
HTTP 与网络安全加固
强制 HTTPS(force_ssl)、HSTS、安全 cookie(same_site、secure)与合适的 content_security_policy;CORS 用 cors_plug 配置 API 来源;限流可用插件(ETS/Cachex 令牌桶)或边缘(NGINX/Cloudflare);上传优先预签名 URL,限制请求体大小(:max_request_line_length、:max_header_value_length)。
资源与静态交付
mix assets.deploy 运行 npm/tailwind/esbuild 并生成资源摘要;静态文件经 CDN/反向代理提供,在 Endpoint 设置 cache-control;生产禁用无用 watcher 以减小镜像体积。
后台任务
推荐 Oban 处理重试/退避、定时任务与隔离,在 application.ex 中监督;通过运行时环境配置队列,用 Oban Web/Pro 或遥测监控;CPU 密集任务考虑池化或外部 worker,避免阻塞调度器。
部署模式
容器:多阶段构建,依次 mix deps.get --only prod、mix compile、mix assets.deploy、mix release。Systemd:以服务运行 release 二进制,用 Environment= 注入密钥,加 Restart=on-failure。Fly/Gigalixir/Render:提供环境变量,挂载 Postgres/Redis,开放长连接 WebSocket 端口。蓝绿或金丝雀:保持数据库迁移兼容,先部署代码再执行迁移,用功能开关处理模式变更。
可观测性与健康检查
添加 /health 与 /ready 端点(Repo 检查 + PubSub/Presence 检查);用 :telemetry_poller 导出调度器利用率与内存等 VM 指标;对错误率、数据库超时、队列深度与 VM 内存设置告警。
常见陷阱
构建 release 时未设 PHX_SERVER=true(端点不会启动);缺少 config/runtime.exs 运行时配置,依赖编译期配置存放密钥;未配置集群发现导致 Presence 跨节点不一致;保留默认 secret_key_base 或每节点不同密钥导致部署后会话失效;大体积资源未加摘要/CDN 导致冷加载缓慢。