Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Phoenix 1.4.x to 1.5.0 upgrade instructions

Phoenix 1.5 requires Elixir >= 1.7. Be sure your existing version is up to date by running elixir -v on the command line.

Install the new phx.new project generator

$ mix archive.uninstall phx_new
$ mix archive.install hex phx_new 1.5.0

Bump your deps

Update your Phoenix and Phoenix PubSub deps to their latest versions.

Note: The outdated Phoenix.Endpoint.CowboyAdapter for Cowboy 1 is deprecated. Please make sure {:plug_cowboy, "~> 2.1"} is specified in your deps.

  defp deps do
    [
      {:phoenix, "~> 1.5.0"},
      {:phoenix_pubsub, "~> 2.0"},
      {:plug_cowboy, "~> 2.1"},
      ...
    ]
  end

PubSub 2.0 Changes

Phoenix.PubSub 2.0 provides a simpler, more extensible, and more performant Phoenix.PubSub API. For users of Phoenix.PubSub, the API is the same, but the pubsub server being started by the endpoint has been deprecated in favor of starting the PubSub server yourself. This prevents race conditions on startup and decouples the PubSub system from the endpoint.

First, replace your endpoint's :pubsub config with a new :pubsub_server key in config/config.exs:

config :my_app, MyApp.Endpoint,
  url: [host: "localhost"],
  ...,
- pubsub: [name: MyApp.PubSub, adapter: Phoenix.PubSub.PG2],
+ pubsub_server: MyApp.PubSub,

Next, update your lib/my_app/application.ex supervision tree to start its own PubSub:

children = [
+ # Start the PubSub system
+ {Phoenix.PubSub, name: MyApp.PubSub},
  # Start the Endpoint (http/https)
  MyApp.Endpoint,
]

Update your layouts

Rendering the child template from layouts is deprecated. Replace:

<%= render(@view_module, @view_template, assigns) %>

With the new @inner_content assign:

<%= @inner_content %>

Update your Tests

Using Phoenix.ConnTest is deprecated, replace usage:

use Phoenix.ConnTest

with:

import Plug.Conn
import Phoenix.ConnTest

Note: for most applications, this will be located in a single place in test/support/conn_case.ex

Add the new Phoenix LiveDashboard (optional)

The new LiveDashboard project provides real-time performance monitoring and debugging tools for Phoenix developers. Follow the steps in the project readme to include it in your existing applications https://github.com/phoenixframework/phoenix_live_dashboard

@vanderhoop

This comment has been minimized.

Copy link

@vanderhoop vanderhoop commented Apr 16, 2020

So frickin' pumped for Phoenix.LiveDashboard. Optional, shmoptional!

@AaronCowan

This comment has been minimized.

Copy link

@AaronCowan AaronCowan commented Apr 16, 2020

If anyone else was too excited when upgrading remember it is <%= @inner_content %> NOT <%= render @inner_content %>. Hopefully I'll save someone a small headache. So excited for this!

@nickjj

This comment has been minimized.

Copy link

@nickjj nickjj commented Apr 17, 2020

When I use <%= @inner_content %> in my app.html.eex layout it throws assign @inner_content not available in eex template when trying to render any page.

Does anyone else get this?

@joshchernoff

This comment has been minimized.

Copy link

@joshchernoff joshchernoff commented Apr 20, 2020

When I use <%= @inner_content %> in my app.html.eex layout it throws assign @inner_content not available in eex template when trying to render any page.

Does anyone else get this?

Just upgraded and I have <%= @inner_content %> in my app.html.eex with no problem 🤷‍♂️

@mythicalprogrammer

This comment has been minimized.

Copy link

@mythicalprogrammer mythicalprogrammer commented Apr 23, 2020

 {:plug_cowboy, "~> 2.1"},

This yelled at me with mix deps.update --all:

Dependencies have diverged:
* plug_cowboy (Hex package)
  the dependency plug_cowboy 2.1.2

  > In mix.exs:
    {:plug_cowboy, "~> 2.1", [env: :prod, repo: "hexpm", hex: "plug_cowboy"]}

  does not match the requirement specified

  > In deps/phoenix/mix.exs:
    {:plug_cowboy, "~> 1.0 or ~> 2.2", [env: :prod, hex: "plug_cowboy", repo: "hexpm", optional: true]}

  Ensure they match or specify one of the above in your deps and set "override: true"
** (Mix) Can't continue due to errors on dependencies

I had to do:

 {:plug_cowboy, "~> 2.2"},
@jonleighton

This comment has been minimized.

Copy link

@jonleighton jonleighton commented Apr 24, 2020

I ran into the following error when running mix phx.server:

** (Mix) Could not start application myapp: Myapp.Application.start(:normal, []) returned an error: shutdown: failed to start child: MyappWeb.Endpoint
    ** (EXIT) an exception was raised:
        ** (UndefinedFunctionError) function Phoenix.Socket.__child_spec__/2 is undefined or private
            (phoenix 1.5.1) Phoenix.Socket.__child_spec__(Phoenix.LiveReloader.Socket, [endpoint: MyappWeb.Endpoint])
            (elixir 1.10.1) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
            (phoenix 1.5.1) lib/phoenix/endpoint/supervisor.ex:105: Phoenix.Endpoint.Supervisor.init/1
            (stdlib 3.11.2) supervisor.erl:295: :supervisor.init/1
            (stdlib 3.11.2) gen_server.erl:374: :gen_server.init_it/2
            (stdlib 3.11.2) gen_server.erl:342: :gen_server.init_it/6
            (stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

The workaround discussed here solved it for me: https://elixirforum.com/t/mix-phx-server-failing-after-upgrading-to-phoenix-1-5-0-rc-0/30842/6

@Qqwy

This comment has been minimized.

Copy link

@Qqwy Qqwy commented Apr 24, 2020

What has happened to the old default CSS styles (that e.g. show a spinner when the component is loading/restarting)?

@oliver-kriska

This comment has been minimized.

Copy link

@oliver-kriska oliver-kriska commented Apr 25, 2020

@Qqwy I think you mean this upgrade of LiveView

@vanderhoop

This comment has been minimized.

Copy link

@vanderhoop vanderhoop commented Apr 26, 2020

Hey @chrismccord, just a heads up that the deprecation of use Phoenix.ChannelTest (preferring import Phoenix.ChannelTest) can also be surfaced in the "Update your tests" section, as this is likely to come up for folks doing channel work.

@angelikatyborska

This comment has been minimized.

Copy link

@angelikatyborska angelikatyborska commented Apr 27, 2020

Rendering the child template from layouts is deprecated. Replace:

<%= render(@view_module, @view_template, assigns) %>

What about other usages of @view_module and @view_template? For example, I have an app with a layout that allows you to put extra content in the head by something like this:

<%= render_existing @view_module, "head_content." <> @view_template, assigns %>

It still works after updating to 1.5, but I am still wondering if it will stop working anytime soon?

@joshchernoff

This comment has been minimized.

Copy link

@joshchernoff joshchernoff commented Apr 27, 2020

FYI if you run into issues because you used render_existing to dynamically render js tags and the view_module points to the LayoutView and the view_template points to :root then you can use this workaround to address it.

# lib/my_app_web/views/layout_view.ex

defmodule MyAppWeb.LayoutView do
  use MyAppWeb, :view

  def render_existing_nested(
        %{
          :phoenix_template => phoenix_template,
          :phoenix_view => phoenix_view
        },
        tag,
        assigns
      ) do
    render_existing(phoenix_view, tag <> phoenix_template, assigns)
  end
end

Then I use <%= render_existing_nested @conn.private, "script.", assigns %> in my root layout

I'm sure this could be done better but I think it conveys the idea of how to workaround the issue of the root layout.

@navinpeiris

This comment has been minimized.

Copy link

@navinpeiris navinpeiris commented Apr 28, 2020

Also checkout PhoenixDiff https://www.phoenixdiff.org/?source=1.4.16&target=1.5.1 for other changes in generated code

@josevalim

This comment has been minimized.

Copy link

@josevalim josevalim commented Apr 30, 2020

For the @view_module and @view_template, use view_module(@conn) and view_template(@conn) instead. Note you will need to import view_template: 1 in your my_app_web.ex file under def view.

@octosteve

This comment has been minimized.

Copy link

@octosteve octosteve commented May 1, 2020

If anyone else was too excited when upgrading remember it is <%= @inner_content %> NOT <%= render @inner_content %>. Hopefully I'll save someone a small headache. So excited for this!

THANK YOU

@spapas

This comment has been minimized.

Copy link

@spapas spapas commented May 2, 2020

For anybody having the same problem as me with render_existing, josevalim's reply fixed it for me. I was using a render_existing on my global layout template to run some javascript for particular like this:

<%= render_existing @view_module, "extra_scripts.html", assigns %>

this stopped working in Phoenix 1.5. Changing the above to

<%= render_existing view_module(@conn), "extra_scripts.html", assigns %>

fixed it.

Thank you!

@rschooley

This comment has been minimized.

Copy link

@rschooley rschooley commented May 6, 2020

Looking at fresh 1.4.17 and 1.5.1 projects I see 1.5 has a Telemetry Supervisor in Application.ex:

  def start(_type, _args) do
    children = [
      # Start the Telemetry supervisor
      MyApp.Telemetry,

Should this be part of the upgrade process?

edit: oh I see a whole telemetry.ex file in 1.5 which is used by LiveDashboard specifically so I suppose not.

I will leave this in case someone else runs into the same question.

@thiagomajesk

This comment has been minimized.

Copy link

@thiagomajesk thiagomajesk commented May 11, 2020

I was stuck running the new mix setup task from the templates with the error: ERR! Could not install from "" as it does not contain a package.json file.. I discovered there's a problem with npm install --prefix assets on Windows and it's not working as expected. Instead, you'll have to manually cd into the asset directory and install the dependencies.

This seems to be documented here: phoenixframework/phoenix_live_view#449.

@QuinnWilton

This comment has been minimized.

Copy link

@QuinnWilton QuinnWilton commented May 11, 2020

If you run into the following error after upgrading:

    ** (EXIT) an exception was raised:
        ** (UndefinedFunctionError) function Phoenix.Socket.__child_spec__/2 is undefined or private

You may be able to fix it with this command: mix deps.clean phoenix_live_reload && mix deps.update phoenix_live_reload

@izzues

This comment has been minimized.

Copy link

@izzues izzues commented May 21, 2020

@navinpeiris that's exactly what I was looking for, thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.