beerlington

beerlington

Heroku app recompiles after restarts using Elixir 1.15

I upgraded to Elixir 1.15 and am having issues deploying on Heroku now. Whenever the app restarts, the whole application recompiles. On our large application, this recompile takes longer than 30 seconds, which causes the app to crash.

I’m able to reproduce this on a bare bones Phoenix app. The line where it says “Compiling 15 files” should not be happening during a restart.

2023-07-06T14:42:59.587968+00:00 heroku[web.1]: Restarting
2023-07-06T14:42:59.650735+00:00 heroku[web.1]: State changed from up to starting
2023-07-06T14:43:00.295043+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2023-07-06T14:43:00.322078+00:00 app[web.1]: 14:43:00.321 [notice] SIGTERM received - shutting down
2023-07-06T14:43:00.322086+00:00 app[web.1]: 
2023-07-06T14:43:01.502645+00:00 heroku[web.1]: Process exited with status 0
2023-07-06T14:43:03.720077+00:00 heroku[web.1]: Starting process with command `mix phx.server`
2023-07-06T14:43:05.363804+00:00 app[web.1]: Compiling 15 files (.ex)

Where should I report this issue? I don’t know if it’s something specific to Elixir or if the Heroku buildpack we’re using needs to be updated to support Elixir 1.15. GitHub - HashNuke/heroku-buildpack-elixir: Heroku Buildpack for Elixir with nitro boost

Marked As Solved

johantell

johantell

Yes, running the migrations through mix will force recompilation. There is a way around it though, i think its described quite well under the phoenix release docs. In short its a helper function that is called via the release through the eval command

Also Liked

AlfredBaudisch

AlfredBaudisch

For those coming here with a setup similar to mine:

  • Elixir 1.15
  • OTP 26
  • Heroku
  • Phoenix 1.7
  • And Umbrella app (4 apps)

The solution to make it work with Heroku, as explained previously, is to migrate to use Releases, but then, Node and npm weren’t being run so statics assets were not being compiled (i.e. apps/xxx/assets).

In the end I made it work in Heroku by adding a Procfile manually, keeping the Elixir and Phoenix static assets buildpacks, adding an additional “elixir mix release” buildpack and setting Phoenix Endpoint as a server.

Configuration step by step:

Phoenix Endpoint

I had a lot of trouble making Phoenix start in Heroku when building the mix release. In the end, this is what I needed to put inside config/runtime.exs. The secret lies in adding server: true, otherwise the Elixir release won’t start Phoenix as a server and Heroku will timeout on startup.

if config_env() == :prod do
  config :fb_web, Farmbackup.Endpoint,
    http: [
      port: {:system, "PORT"},
      compress: true,
      timeout: 60_000,
      protocol_options: [
        idle_timeout: 60_000
      ]
    ],
    url: [scheme: "https", host: System.fetch_env!("FARMBACKUP_HOST"), port: 443],
    debug_errors: false,
    cache_static_manifest: "priv/static/cache_manifest.json",
    secret_key_base: System.fetch_env!("SECRET_KEY_BASE"),
    server: true
end

mix.exs release

In the main mix.exs file add all your umbrella apps in the releases config key:

  def project do
    [
      apps_path: "apps",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      aliases: aliases(),
      releases: [
        fb_task: [
          applications: [
            fb_web: :permanent,
            fb_db: :permanent,
            fb_invoice: :permanent,
            fb_salary: :permanent
          ],
          version: DateTime.utc_now() |> DateTime.to_iso8601()
        ]
      ]
    ]
  end

Heroku Buildpacks

You are going to need these 3 buildpacks installed in order:

https://github.com/HashNuke/heroku-buildpack-elixir.git
https://github.com/gigalixir/gigalixir-buildpack-phoenix-static
https://github.com/chrismcg/heroku-buildpack-elixir-mix-release

Buildpack config

elixir_buildpack.config

erlang_version=26.1.2
elixir_version=1.15.7
always_rebuild=false
runtime_path=/app

phoenix_static_buildpack.config

clean_cache=true
phoenix_relative_path=apps/fb_web (i.e. app in the umbrella which has `/assets`)
assets_path=apps/fb_web/assets
node_version=v14.15.5
npm_version=6.14.11

Procfile

YOU need to manually create a Heroku Procfile for Umbrellas.

In our case it is:

web: _build/prod/rel/fb_task/bin/fb_task start
iamyojimbo

iamyojimbo

I have posted an update here: Additional recompile occurring on Heroku with Elixir 1.15 causing boot issues · Issue #12771 · elixir-lang/elixir · GitHub

Read there for more detail. The root cause is that elixir 1.15 introduced cwd in the cache key after compilation. Heroku compiles code in a tmp build dir, but is run from /app.

Fix it by using your exact same Procfile as before, but passing in --no-compile, as detailed here: Changing absolute path of mix project causes full recompilation · Issue #13241 · elixir-lang/elixir · GitHub

So change your procfile to:

release: mix do ecto.migrate --no-compile, any_other_example_mix_command
web: MIX_ENV=prod mix phx.server --no-compile

You do not need to use releases.

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement