在 docker 内的 ejabberd 生产模式中 运行 ecto 时出错(failed_to_start_child)
Error (failed_to_start_child) when running ecto in ejabberd production mode inside docker
我将 ecto 添加到 ejabberd,它在开发模式下运行良好(运行 with 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
连接设置在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
link 到官方 docker repo (https://github.com/processone/docker-ejabberd/tree/master/ecs),唯一的变化是 docker 文件是从本地版本复制文件而不是克隆它
我猜 ejabberd 找不到 ecto 的配置,但我不知道该放在哪里。我已经尝试将设置添加到 rel/prod.exs,但没有任何区别。
我错过了什么吗?我怎样才能更清楚地理解这个错误?
感谢@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
应用程序和 included_applications 似乎定义了哪些应用程序将在发布时捆绑
我将 ecto 添加到 ejabberd,它在开发模式下运行良好(运行 with 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
连接设置在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
link 到官方 docker repo (https://github.com/processone/docker-ejabberd/tree/master/ecs),唯一的变化是 docker 文件是从本地版本复制文件而不是克隆它
我猜 ejabberd 找不到 ecto 的配置,但我不知道该放在哪里。我已经尝试将设置添加到 rel/prod.exs,但没有任何区别。
我错过了什么吗?我怎样才能更清楚地理解这个错误?
感谢@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
应用程序和 included_applications 似乎定义了哪些应用程序将在发布时捆绑