Elixir Release #

一、Release概述 #

1.1 什么是Release #

Release是Elixir应用的完整打包,包含:

  • 编译后的代码
  • Erlang虚拟机
  • 依赖库
  • 配置文件
  • 启动脚本

1.2 Release优势 #

  • 自包含,无需安装Elixir
  • 快速启动
  • 代码热更新
  • 系统命令支持

二、构建Release #

2.1 配置mix.exs #

elixir
defmodule MyApp.MixProject do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: "0.1.0",
      elixir: "~> 1.16",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      releases: releases()
    ]
  end

  def releases do
    [
      my_app: [
        include_executables_for: [:unix],
        applications: [runtime_tools: :permanent]
      ]
    ]
  end

  def application do
    [
      extra_applications: [:logger, :runtime_tools],
      mod: {MyApp.Application, []}
    ]
  end

  defp deps do
    []
  end
end

2.2 构建命令 #

bash
MIX_ENV=prod mix release

2.3 构建输出 #

text
Build a release for my_app-0.1.0

Release created at _build/prod/rel/my_app

    # To start your system
    _build/prod/rel/my_app/bin/my_app start

Once the release is running:

    # To connect to it remotely
    _build/prod/rel/my_app/bin/my_app remote

    # To stop it gracefully (you may also send SIGINT/SIGTERM)
    _build/prod/rel/my_app/bin/my_app stop

    # To generate a tarball
    _build/prod/rel/my_app/bin/my_app tar

三、Release结构 #

3.1 目录结构 #

text
_build/prod/rel/my_app/
├── bin/
│   ├── my_app
│   ├── my_app.bat
│   └── start.boot
├── erts-14.2/
├── lib/
│   ├── my_app-0.1.0/
│   ├── elixir-1.16.0/
│   └── ...
├── releases/
│   ├── 0.1.0/
│   │   ├── elixir
│   │   ├── my_app.rel
│   │   ├── sys.config
│   │   └── vm.args
│   ├── RELEASES
│   └── start_erl.data
└── tmp/

3.2 关键文件 #

  • bin/my_app - 启动脚本
  • releases/0.1.0/sys.config - 运行时配置
  • releases/0.1.0/vm.args - 虚拟机参数

四、运行Release #

4.1 启动方式 #

bash
# 前台启动
_build/prod/rel/my_app/bin/my_app start

# 后台启动
_build/prod/rel/my_app/bin/my_app daemon

# 交互模式
_build/prod/rel/my_app/bin/my_app start_iex

4.2 管理命令 #

bash
# 查看状态
./bin/my_app pid
./bin/my_app ping

# 停止
./bin/my_app stop

# 重启
./bin/my_app restart

# 远程连接
./bin/my_app remote

# 控制台
./bin/my_app eval "IO.puts(:hello)"

五、配置管理 #

5.1 运行时配置 #

elixir
# config/runtime.exs
import Config

config :my_app, MyApp.Repo,
  database: System.get_env("DB_NAME") || "my_app",
  username: System.get_env("DB_USER") || "postgres",
  password: System.get_env("DB_PASS") || "postgres",
  hostname: System.get_env("DB_HOST") || "localhost",
  port: String.to_integer(System.get_env("DB_PORT") || "5432")

config :my_app, MyAppWeb.Endpoint,
  http: [
    port: String.to_integer(System.get_env("PORT") || "4000")
  ],
  secret_key_base: System.get_env("SECRET_KEY_BASE")

config :my_app,
  environment: config_env()

5.2 vm.args #

bash
# rel/vm.args.eex
-name my_app@127.0.0.1
-setcookie my_app_cookie
+spp true
+smp enable

5.3 自定义vm.args #

elixir
def releases do
  [
    my_app: [
      include_executables_for: [:unix],
      vm_args: "rel/vm.args"
    ]
  ]
end

六、多环境Release #

6.1 配置多个Release #

elixir
def releases do
  [
    my_app: [
      include_executables_for: [:unix]
    ],
    my_app_staging: [
      include_executables_for: [:unix],
      cookie: "staging_cookie"
    ],
    my_app_prod: [
      include_executables_for: [:unix],
      cookie: "prod_cookie"
    ]
  ]
end

6.2 构建特定Release #

bash
MIX_ENV=prod mix release my_app_prod

七、热代码升级 #

7.1 配置appup #

elixir
# lib/my_app.appup
{"0.1.1",
 [{<<"0.1.0">>, [{load_module, MyApp.Worker}]}],
 [{<<"0.1.0">>, [{load_module, MyApp.Worker}]}]}.

7.2 生成appup #

bash
mix appup.generate

7.3 执行升级 #

bash
./bin/my_app upgrade "0.1.1"

八、Docker部署 #

8.1 Dockerfile #

dockerfile
FROM elixir:1.16-alpine AS builder

WORKDIR /app

RUN mix local.hex --force && \
    mix local.rebar --force

ENV MIX_ENV=prod

COPY mix.exs mix.lock ./
COPY config config
RUN mix deps.get --only prod

COPY lib lib
RUN mix release

FROM alpine:3.19

RUN apk add --no-cache openssl ncurses-libs

WORKDIR /app

RUN addgroup -g 1000 -S app && \
    adduser -u 1000 -S app -G app

USER app

COPY --from=builder --chown=app:app /app/_build/prod/rel/my_app ./

ENV HOME=/app

CMD ["bin/my_app", "start"]

8.2 构建和运行 #

bash
docker build -t my_app:0.1.0 .
docker run -p 4000:4000 -e SECRET_KEY_BASE=xxx my_app:0.1.0

九、监控和运维 #

9.1 日志 #

elixir
# config/prod.exs
config :logger, :console,
  format: "$time $metadata[$level] $message\n",
  metadata: [:request_id]

9.2 远程控制台 #

bash
./bin/my_app remote

9.3 运行命令 #

bash
./bin/my_app eval "MyApp.some_function()"

9.4 健康检查 #

elixir
defmodule MyApp.HealthCheck do
  def check do
    :ok
  end
end

十、最佳实践 #

10.1 版本管理 #

elixir
def project do
  [
    app: :my_app,
    version: "0.1.0",
    ...
  ]
end

10.2 环境变量 #

bash
export SECRET_KEY_BASE=$(mix phx.gen.secret)
export DATABASE_URL=postgres://user:pass@host/db

10.3 启动前检查 #

elixir
def start(_type, _args) do
  check_required_env_vars!()
  ...
end

defp check_required_env_vars! do
  required = ["SECRET_KEY_BASE", "DATABASE_URL"]

  Enum.each(required, fn var ->
    unless System.get_env(var) do
      raise "Missing required environment variable: #{var}"
    end
  end)
end

十一、总结 #

本章学习了:

特性 用途
mix release 构建Release
bin/my_app start 启动应用
runtime.exs 运行时配置
vm.args 虚拟机参数
Docker 容器化部署

准备好学习高级特性了吗?让我们进入下一章。

最后更新:2026-03-27