Secrets missing when deploying a Phoenix 1.6 App to Fly

I started a new Phoenix App with 1.6.rc-0 and tried to deploy it on fly after integrating tailwind and custom fonts. I created a new Postgres cluster with it and tried to deploy it, but when I deploy it the app exits with the error DATABASE_URL is missing.

Here is my runtime.exs file, which I edited which came generated with the project.

import Config

# config/runtime.exs is executed for all environments, including
# during releases. It is executed after compilation and before the
# system starts, so it is typically used to load production configuration
# and secrets from environment variables or elsewhere. Do not define
# any compile-time configuration in here, as it won't be applied.
# The block below contains prod specific runtime configuration.
if config_env() == :prod do
  database_url =
    System.get_env("DATABASE_URL") ||
      raise """
      environment variable DATABASE_URL is missing.
      For example: ecto://USER:PASS@HOST/DATABASE
      """

  config :indie_paper, IndiePaper.Repo,
    # ssl: true,
    socket_options: [:inet6],
    url: database_url,
    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")

  secret_key_base =
    System.get_env("SECRET_KEY_BASE") ||
      raise """
      environment variable SECRET_KEY_BASE is missing.
      You can generate one by calling: mix phx.gen.secret
      """

  app_name =
    System.get_env("FLY_APP_NAME") ||
      raise "FLY_APP_NAME not available"

  config :indie_paper, IndiePaperWeb.Endpoint,
    http: [
      url: [host: "#{app_name}.fly.dev", port: 80],
      # Enable IPv6 and bind on all interfaces.
      # Set it to  {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
      # See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html
      # for details about using IPv6 vs IPv4 and loopback vs public addresses.
      ip: {0, 0, 0, 0, 0, 0, 0, 0},
      port: String.to_integer(System.get_env("PORT") || "4000"),
      transport_options: [socket_opts: [:inet6]]
    ],
    secret_key_base: secret_key_base

  # ## Using releases
  #
  # If you are doing OTP releases, you need to instruct Phoenix
  # to start each relevant endpoint:
  #
  #     config :indie_paper, IndiePaperWeb.Endpoint, server: true
  #
  # Then you can assemble a release by calling `mix release`.
  # See `mix help release` for more information.
  config :indie_paper, IndiePaperWeb.Endpoint, server: true

  # ## Configuring the mailer
  #
  # In production you need to configure the mailer to use a different adapter.
  # Also, you may need to configure the Swoosh API client of your choice if you
  # are not using SMTP. Here is an example of the configuration:
  #
  #     config :indie_paper, IndiePaper.Mailer,
  #       adapter: Swoosh.Adapters.Mailgun,
  #       api_key: System.get_env("MAILGUN_API_KEY"),
  #       domain: System.get_env("MAILGUN_DOMAIN")
  #
  # For this example you need include a HTTP client required by Swoosh API client.
  # Swoosh supports Hackney and Finch out of the box:
  #
  #     config :swoosh, :api_client, Swoosh.ApiClient.Hackney
  #
  # See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details.
end

Here is the output of my fly secrets list

AME            DIGEST                           DATE      
DATABASE_URL    7fd2f264a8890fdfa2164c97995acc49 5m38s ago 
SECRET_KEY_BASE 1dce7fd111e6c3a0812767240e6d5b2a 2m33s ago 

Also trying

fly postgres attach --postgres-app indiepaper-dev-db -a indiepaper-dev throws An unknown error occured

I believe the fly postgres attach failure is due to the database already existing (attaching creates a database with the name of your app in the postgres cluster). Have you attached it previously? Or attached an app with the same name? Regardless, this is a bug we’ll be fixing.

If I manually inspect your app, I only see the SECRET_KEY_BASE secret (I cannot see the secret’s value, no worries).

I see both the DB and the app have been created and deleted many times. I’ve been looking at the latest instance of the app.

I had tried creating and deleting the app multiple times to see if the error would go away. Turns out the error was with esbuild.

Phoenix 1.6 uses esbuild wrapped in elixir package to build out the assets. I created this task in mix.exs to deploy assets.

  defp aliases do
    [
      setup: ["deps.get", "ecto.setup"],
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
      "assets.deploy": [
        "cmd --cd assets npm run deploy",
        "esbuild default --minify",
        "phx.digest"
      ]
    ]
  end

and in my Dockerfile put

# build assets
RUN mix assets.deploy

instead of the default


# build assets
RUN npm run --prefix ./assets deploy
RUN mix phx.digest

That might have caused Docker to step into elixir and since we don’t have the secrets in builder, make the build crash.

Reverting to the original version fixed the crash.

2 Likes

Thank you for this! This resolved a failing build. However, when esbuild isn’t run in the Dockerfile, app.js doesn’t get built. On line 36, I have COPY assets assets, so idk what’s missing.

Edit: After refreshing a few times, app.js is working. :raised_hands:

1 Like

This was due to an issue on esbuild, it is fixed in the latest release. Update your dependencies and mix assets.deploy should work.

1 Like