Deploying a Cowboy app fails with `missing option :key/:keyfile`

Hey everyone!
I’m trying to deploy a Cowboy app on Fly.io, but I’m getting the following error when starting the Application:

14:34:25.294 [notice] Application dora exited: exited in: Dora.Application.start(:normal, [])
** (EXIT) an exception was raised:
    ** (ArgumentError) could not start Cowboy2 adapter, missing option :key/:keyfile
    (plug_cowboy 2.6.0) lib/plug/cowboy.ex:409: Plug.Cowboy.fail/1
    (plug_cowboy 2.6.0) lib/plug/cowboy.ex:167: Plug.Cowboy.args/4
    (plug_cowboy 2.6.0) lib/plug/cowboy.ex:261: Plug.Cowboy.child_spec/1
    (elixir 1.14.3) lib/supervisor.ex:696: Supervisor.init_child/1
    (elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
    (elixir 1.14.3) lib/supervisor.ex:687: Supervisor.init/2
    (elixir 1.14.3) lib/supervisor.ex:617: Supervisor.start_link/2
    (kernel 8.5.3) application_master.erl:293: :application_master.start_it_old/4

It’s clear that it’s expecting the path for the certificate files (as described in the Cowboy docs, but the thing is that I’m not sure of what to put there, as certificates are managed automatically by Fly.io. I’ve tried ssh into the app and look for .pem files, but found nothing useful.

This is my :plug_cowboy config under runtime.exs:

config :plug_cowboy,
  port: String.to_integer(System.get_env("PORT") || "4000"),
  otp_app: :dora,
  ip: {0, 0, 0, 0, 0, 0, 0, 0}

Under prod.exs

config :plug_cowboy,
  scheme: :https

And the application has the following code:

@cowboy_scheme Application.compile_env!(:plug_cowboy, :scheme)

@impl true
def start(_type, _args) do
  children = [
    {Plug.Cowboy, scheme: @cowboy_scheme, plug: Dora.Router},
    Dora.Repo,
    Dora
  ]

To be honest, it’s not mandatory to use Cowboy directly, but for the use case, I felt that Phoenix was too much.

Hi @zediogoviana
I think to fix that error, you can either use the OS certificates or use something like CAStore

1 Like

Thanks @ouroboros ! That solved the deployment issue. Btw, I now have this in my Application:

options =
  if @cowboy_scheme == :https,
    do: [
      keyfile: CAStore.file_path(),
      certfile: CAStore.file_path()
    ],
    else: []

children = [
  {Plug.Cowboy, scheme: @cowboy_scheme, plug: TestApp.Router, options: options}
]
1 Like