Pigeon :nofile error on deploying phoenix project

Hello. I’m using pigeon for sending notifications to iOS devices. And I use docker for deploying phoenix project on Ubuntu.

I can send notifications to my device in local environment, but in a container, it fails to start an application.

FROM elixir:1.9.4-alpine AS build

RUN apk add --no-cache build-base npm git python

WORKDIR /app

RUN mix local.hex --force && \
    mix local.rebar --force

ENV DATABASE_URL=ecto://postgres:postgres@db/pappap
ENV SECRET_KEY_BASE=uTG/s/VxvRixaWqRdW1MrtOqGxAUL/m3VIA5HZAaMHvU/PixTV5V+vUeWhv5UEnY
ENV MIX_ENV=prod

COPY mix.exs mix.lock ./
COPY config config
RUN mix do deps.get, deps.compile

COPY priv priv
RUN ls priv/cert
COPY lib lib
#COPY rel rel
RUN mix compile
#RUN mix ecto.create
#RUN mix ecto.migrate
RUN mix release

FROM alpine:3.9 AS app
RUN apk add --no-cache openssl ncurses-libs

WORKDIR /app

RUN chown nobody:nobody /app

USER nobody:nobody

COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/pappap ./

ENV HOME=/app

COPY ./entrypoint.sh .
RUN ls lib

USER root

RUN chmod +x entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

This is my Dockerfile of the application. It copies priv directory. My AuthKey is in it.

version: '3'

networks:
  backend:
    driver: bridge

services:
  db:
    build: ./dockerfiles/db
    volumes:
      - ./volumes/db/data:/var/lib/postgresql/0.1.0
    ports:
      - 5432:5432
    environment:
      - POSTGRES_DB=pappap
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    restart: always
    networks:
      - backend

  app:
    build:
      dockerfile: ./dockerfiles/app/Dockerfile
      context: .
    command: "bin/pappap start"
    environment:
      - DATABASE_URL=ecto://postgres:postgres@db/pappap
      - SECRET_KEY_BASE=tIQIht+gvi3rto8AHxzjr7WfqltNPBXWb4HnYzBS/tw0vBldMvSsxFe1rdpoOkYc
    ports:
      - 4001:4001
    tty: true
    networks:
      - backend

And this is my docker-compose.yml. I create image and container from them.
I create them with docker-compose build and docker-compose up -d db, then docker-compose up -d app.

Although the db container works, the app one does not work…
Log of the app container is

d logs pappap_app_1 --tail all                 20:09
11:09:50.550 [info] == Running 20200827152435 Pappap.Repo.Migrations.CreateDevices.change/0 forward
11:09:50.553 [info] create table devices
11:09:50.559 [info] create index devices_device_id_index
11:09:50.568 [info] == Migrated 20200827152435 in 0.0s
11:09:50.600 [info] == Running 20201023070157 Pappap.Repo.Migrations.CreateScheduler.change/0 forward
11:09:50.600 [info] create table notification_scheduler
11:09:50.604 [info] == Migrated 20201023070157 in 0.0s
11:09:52.745 [info] Application pigeon exited: Pigeon.start(:normal, []) returned an error: shutdown: failed to start child: :apns_default
    ** (EXIT) an exception was raised:
        ** (Pigeon.ConfigError) attempted to start without valid key

The following configuration was given:

%Pigeon.APNS.JWTConfig{
  key: {:error, {:invalid, "priv/cert/AuthKey_XXXXXp8"}},
  key_identifier: "XXXXX",
  keyfile: {:error, {:nofile, "priv/cert/AuthKey_XXXXX.p8"}},
  name: :apns_default,
  ping_period: 600000,
  port: 443,
  reconnect: false,
  team_id: "AAAAA",
  uri: "api.push.apple.com"
}

(pigeon) lib/pigeon/apns/jwt_config.ex:205: Pigeon.Configurable.Pigeon.APNS.JWTConfig.validate!/1
(pigeon) lib/pigeon/worker.ex:44: Pigeon.Worker.init/1
(gen_stage) lib/gen_stage.ex:1704: GenStage.init/1
(stdlib) gen_server.erl:374: :gen_server.init_it/2
(stdlib) gen_server.erl:342: :gen_server.init_it/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
{"Kernel pid terminated",application_controller,"{application_start_failure,pigeon,{{shutdown,{failed_to_start_child,apns_default,{#{'__exception__' => true,'__struct__' => 'Elixir.Pigeon.ConfigError',config => #{'__struct__' => 'Elixir.Pigeon.APNS.JWTConfig',key => {error,{invalid,<<\"priv/cert/AuthKey_XXXXX.p8\">>}},key_identifier => <<\"XXXXX\">>,keyfile => {error,{nofile,<<\"priv/cert/AuthKey_XXXXX.p8\">>}},name => apns_default,ping_period => 600000,port => 443,reconnect => false,team_id => <<\"AAAAA\">>,uri => <<\"api.push.apple.com\">>},reason => <<\"attempted to start without valid key\">>},[{'Elixir.Pigeon.Configurable.Pigeon.APNS.JWTConfig','validate!',1,[{file,\"lib/pigeon/apns/jwt_config.ex\"},{line,205}]},{'Elixir.Pigeon.Worker',init,1,[{file,\"lib/pigeon/worker.ex\"},{line,44}]},{'Elixir.GenStage',init,1,[{file,\"lib/gen_stage.ex\"},{line,1704}]},{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}]}]}}},{'Elixir.Pigeon',start,[normal,[]]}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,pigeon,{{shutdown,{failed_to_start_child,apns_default,{#{'__exception__' => true,'__struct__' => 'Elixir.Pigeon.ConfigError',

Crash dump is being written to: erl_crash.dump...done

I don’t know what is wrong… I’ll show you anything if it’s necessary for getting deployment well.
HELP!

I have no experience with Pigeon, but the error seems to indicate that you are providing an invalid key:

My recommendation is to double-check your :key and :keyfile, and make sure they are valid.

1 Like

It seems as if you are using relative pathes for the key file, you need to use an absolute path using :code priv_dir or how the function was called.

2 Likes

Thank you!
It was a path problem as you said!