首页 > 解决方案 > 在 docker 内以 ejabberd 生产模式运行 ecto 时出错 (failed_to_start_child)

问题描述

我将 ecto 添加到 ejabberd 中,它在开发模式下运行良好(使用 iex -S mix 运行),但是当 ejabberd 编译并启动时,我收到此错误:

07:02:09.214 [error] Failed to start module <module-name>: 
{error,
    {shutdown,
        {failed_to_start_child,'Elixir.Ejabberd.Repo',
            {undef,
                [{'Elixir.Ecto.Adapters.Postgres',init,
                     [[{repo,'Elixir.Ejabberd.Repo'},
                       {telemetry_prefix,[ejabberd,repo]},
                       {otp_app,ejabberd},
                       {timeout,15000},
                       {pool_size,10}]],
                     []},
                 {'Elixir.Ecto.Repo.Supervisor',init,1,
                     [{file,"lib/ecto/repo/supervisor.ex"},{line,162}]},
                 {supervisor,init,1,[{file,"supervisor.erl"},{line,295}]},
                 {gen_server,init_it,2,[{file,"gen_server.erl"},{line,374}]},
                 {gen_server,init_it,6,[{file,"gen_server.erl"},{line,342}]},
                 {proc_lib,init_p_do_apply,3,
                     [{file,"proc_lib.erl"},{line,249}]}]}}}}

我从自定义 ejabberd 模块开始 Ejabberd.Repo:

def init(:ok) do
    children = [
    worker(Ejabberd.Repo, [])
   ]

   Supervisor.init(children, strategy: :one_for_one)
end

def start(host, _opts) do
  info("Starting ejabberd module #{__MODULE__} at #{host}")
  :gen_iq_handler.add_iq_handler(:ejabberd_local, host, @namespace, __MODULE__, :on_iq_received)
  Supervisor.start_link(__MODULE__, :ok, [])
end

Ejabberd.Repo 在 lib/ejabberd/repo.ex 中定义:

defmodule Ejabberd.Repo do 
  use Ecto.Repo,           
    otp_app: :ejabberd,
    adapter: Ecto.Adapters.Postgres 
end

连接设置 inisde config/config.exs:

config :ejabberd, ecto_repos: [Ejabberd.Repo]

config :ejabberd, Ejabberd.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "<database-name>",
  username: "<username>",    
  password: "<password>",      
  hostname: "<host>"

来自 mix.exs 的应用程序设置:

def application do       
  [mod: {:ejabberd_app, []},
   applications: [:kernel, :stdlib, :sasl, :ssl],
   included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
                           :fast_tls, :stringprep, :fast_xml, :xmpp, :mqtree,
                           :stun, :fast_yaml, :esip, :jiffy, :p1_oauth2,
                           :eimp, :base64url, :jose, :pkix, :os_mon, :ecto, :postgrex, :telemetry]
   ++ cond_apps()]       
end

来自 mix.exs 的部门:

defp deps do
  [
    {:lager, "~> 3.6.0"},
    {:p1_utils, "~> 1.0"},
    {:fast_xml, "~> 1.1"},
    {:xmpp, "~> 1.3.0"},
    {:cache_tab, "~> 1.0"},
    {:stringprep, "~> 1.0"},
    {:fast_yaml, "~> 1.0"},
    {:fast_tls, "~> 1.1"},
    {:stun, "~> 1.0"},
    {:esip, "~> 1.0"},
    {:p1_mysql, "~> 1.0"},
    {:mqtree, "~> 1.0"},
    {:p1_pgsql, "~> 1.1"},
    {:jiffy, "~> 0.14.7"},
    {:p1_oauth2, "~> 0.6.1"},
    {:distillery, "~> 2.0"},
    {:pkix, "~> 1.0"},
    {:ex_doc, ">= 0.0.0", only: :dev},
    {:eimp, "~> 1.0"},
    {:base64url, "~> 0.0.1"},
    {:jose, "~> 1.8"},
    {:ecto_sql, "~> 3.0"},
    {:postgrex, ">= 0.0.0"}
  ]
  ++ cond_deps()
end

链接到官方 docker repo ( https://github.com/processone/docker-ejabberd/tree/master/ecs ),对 docker 文件的唯一更改是它从本地版本复制文件而不是克隆它

我猜 ejabberd 找不到 ecto 的配置,但我不知道把它放在哪里。我已经尝试将设置添加到 rel/prod.exs,但这并没有什么不同。

我错过了什么吗?我怎样才能更了解这个错误?

标签: dockerelixirejabberdecto

解决方案


归功于@legoscia,版本不包括 Elixir.Ecto.Adapters.Postgres 的梁文件,将 ecto_sql 添加到 included_applications 解决了这个问题。mix.exs 中的应用程序设置:

def application do       
  [mod: {:ejabberd_app, []},
   applications: [:kernel, :stdlib, :sasl, :ssl],
   included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
                           :fast_tls, :stringprep, :fast_xml, :xmpp, :mqtree,
                           :stun, :fast_yaml, :esip, :jiffy, :p1_oauth2,
                           :eimp, :base64url, :jose, :pkix, :os_mon, :ecto_sql, :ecto, :postgrex, :telemetry]
   ++ cond_apps()]       
end

似乎 applications 和 included_applications 定义了哪些应用程序将在发布中捆绑


推荐阅读