使用 Erts 发布不同的目标包括

Release for different target with Erts include

我想知道是否有人可以提供帮助...

我正在尝试从我的 Elixir 应用程序连接到 MS SQL 服务器,但我收到错误 :odbc.start/0 is undefined (module :odbc is not available)

在我的 Mac 上,我安装了支持 ODBC 的 Erlang 并且一切正常,但是当我在 Ubuntu 服务器上使用 distillery 和 edeliver 进行部署时(我为此安装了 erlang-odbc 以及在哪里构建发生)它失败了。我也尝试不包括 erts 并在我的机器上复制 Erlang 的库后在本地构建它,但都无济于事。

这是 edeliver 配置文件的一个片段:

BUILD_HOST="search-dev"
BUILD_USER="ubuntu"
BUILD_AT="/home/ubuntu/app_build"

STAGING_HOSTS="search-dev search-demo"
STAGING_USER="ubuntu"
TEST_AT="/home/ubuntu/app_release"
...

更新

mix.exs

defmodule SearchService.Mixfile do
  use Mix.Project

  def project do
    [
      app: :search_service,
      version: "0.9.0",
      elixir: "~> 1.7",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps()
    ]
  end

  def application do
    [
      mod: {SearchService.Application, []},
      extra_applications: [
        :logger,
        :timex,
        :geo,
        :geo_postgis,
        :postgrex,
        :ecto,
        :runtime_tools,
        :distillery,
        :edeliver,
        :ssl,
        :httpoison
      ]
    ]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp deps do
    [
      {:phoenix, "~> 1.4.0", override: true},
      {:phoenix_pubsub, "~> 1.0"},
      {:plug_cowboy, "~> 2.0"},
      {:plug, "~> 1.7"},
      {:jason, "~> 1.1"},
      {:ecto_sql, "~> 3.0"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_ecto, "~> 4.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:elixir_uuid, "~> 1.2"},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 2.5"},
      {:scrivener_ecto, "~> 2.0"},
      {:erlport, "~> 0.10.0"},
      {:export, "~> 0.1.0"},
      {:cors_plug, "~> 1.2"},
      {:plug_static_index_html, "~> 1.0"},
      {:geo_postgis, "~> 2.0"},
      {:geo, "~> 3.0"},
      {:blue_bird, "~> 0.4"},
      {:edeliver, "~> 1.7"},
      {:distillery, "~> 2.1"},
      {:inflex, "~> 1.8.1"},
      {:guardian, "~> 1.0"},
      {:comeonin, "~> 4.0"},
      {:argon2_elixir, "~> 1.2"},
      {:elixlsx, "~> 0.4.0"},
      {:quantum, "~> 2.3"},
      {:timex, "~> 3.1"},
      {:httpoison, "~> 1.0"},
      {:sweet_xml, "~> 0.6.5"},
      {:math, "~> 0.3.0"},
      {:color_utils, "0.2.0"},
      {:paper_trail, "~> 0.8.1"},
      {:ex_aws, "~> 2.1"},
      {:ex_aws_s3, "~> 2.0"},
      {:ex_aws_lambda, "~> 2.0"},
      {:hackney, "~> 1.9"},
      {:policy_wonk, "~> 1.0.0"}
    ]
  end

  defp aliases do
    [
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet -r SearchService.Repo", "ecto.migrate -r SearchService.Repo", "test"]
    ]
  end

  def blue_bird_info do
    [
      host: "https://search_service.com",
      title: " Search API",
      description: """
        API requires authorization. All requests must have valid authorization header containing token like:

        `Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...`
      """
    ]
  end
end

我期待 :odbc 模块可用,从而允许我连接到 SQL服务器,而当我 运行 服务器上的远程控制台时,我得到

Interactive Elixir (1.9.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(search_service@127.0.0.1)1> SearchService.WorkOrderSyncOut.createWO('c765bc7f-6308-42b3-b5da-647830d5cceb')
** (UndefinedFunctionError) function :odbc.start/0 is undefined (module :odbc is not available)
    :odbc.start()
    (search_service) lib/search_service/sync/odbc.ex:5: SearchService.ODBC.start_link/2
    (search_service) lib/search_service/sync/db_connect.ex:45: SearchService.DBConnect.getMSSQLConnection/0
    (search_service) lib/search_service/sync/work_order_sync_out.ex:7: SearchService.WorkOrderSyncOut.createWO/1

提前感谢您的指点!

要将应用程序包含到版本中,应该明确地这样做。

def application do
  [
      mod: {SearchService.Application, []},
      included_applications: [:odbc], # ⇐ THIS
      extra_applications: [:logger, ...]
  ]
end

该版本与本地运行不同,因为在本地您仍然编译了包,并且相应的 .beammix 运行者可见。

生产版本已打包,并且该包仅包含那些明确指定的应用程序/库。

旁注: 从发布代码调用 Mix.env() 或类似的尝试以同样的方式失败,因为 mix 应用程序 默认情况下也不包含在发行版中