Supervision Tree Crashes in Release Serving Elasticsearch Child

I am trying to run a release of my phoenix umbrella app on kubernetes. When I am hitting the /app/bin/api_umbrella start command, I get this error: > ** (EXIT) an exception was raised:

    ** (MatchError) no match of right hand side value: {:error, {:shutdown, {:failed_to_start_child, My_App.Tools.ElasticsearchCluster, %{url: [{"must be valid", [validation: :by]}]}}}}

Now, the config,exs for elasticsearch is standard, this is the relevant line:

config :core, App.Tools.ElasticsearchCluster,
url: System.get_env(“ELASTIC_HOST”), …

Obviously, this worked perfectly fine in development so I am wondering what this error could be due to and a more general question of how to debug supervision trees.

Hey @PaulRusuTibreanu it looks like you’re starting your application via a release, and in that case you need to have your production Elasticsearch config in runtime.exs not config.exs. The config.exs and other env related files like prod.exs are all executed when the release is built not when it’s run.

2 Likes

Ok. I thought the config.exs is the configuration file common to all environments. Is the line url: System.get_env(“ELASTIC_HOST”), correct in runtime.exs, too? And is there a place where I could read up more about phoenix in production? Thanks already!

Hey yeah the configuration is good it just needs to be in runtime.exs for releases. I would consider System.fetch_env!("ELASTIC_HOST") as well to make sure that the configuration is there. It’ll give you an earlier more direct error if it is missing.

I’ll do some googling and see if I can find a good resource on modern config practices. You’re right, config.exs does apply to all environments, but it’s still setting the build environment not the runtime environment.

1 Like

Thanks a lot, I really appreciate it since this is my first time deploying (obviously :smiling_face:)!!!

1 Like

I am still getting that error. Is there a way to see what value is passed as the url to the supervisor? I have a hunch that there might be a problem with the loaded cert and that there might be a curl call at the core of this in which the certificate is passed as a flag and that the error message might be misleading.

Can you show how you have the child set up in your supervisor tree?

Do you mean this:

def start(_type, _args) do
import Supervisor.Spec, warn: false

{:ok, pid} =
  Supervisor.start_link(
    [
      supervisor(My_App.Repo, []),
      supervisor(My_App.Tools.ElasticsearchCluster, []),
      worker(Cachex, [:avia_cache, [limit: 1000]]),
      supervisor(Task.Supervisor, [[name: MailManager.TaskSupervisor]]),
      worker(MailManager, [[name: MailManager]])
    ],
    strategy: :one_for_one,
    name: My_App.Supervisor
  )

end

Yeah. When did you first make this project? The supervisor(My_App.Repo, []), helper functions were deprecated quite a long time ago at this point. Was this generated a long time ago?

Setting that aside, can you show the My_App.Tools.ElasticsearchCluster module?

It is true that we haven’t changed this part of the app much because it just worked.

Gotcha not a problem, I’m just trying to sort out how your ElasticsearchCluster fetches config, since it doesn’t do it there. Can you show it?

That was kind of my question to begin with. As I gather, this is the plain Elasticsearch module definition that is called by the supervision tree:

defmodule Energeia.Tools.ElasticsearchCluster do
@moduledoc false
use Elasticsearch.Cluster, otp_app: :core
end

That’s only a conduit to the elasticsearch library, but I cannot really detect how the supervisor navigates those files. By the way, I sorted out the original problem, but I would like to use this venue to understand supervision trees in general.