If considering implementing this in a production environment, it is advisable not to do so :). In my perspective, having the phoenix app responsible for the node.js app may not be the best choice. However, if you wish to run both together during development using a single mix phx.server
command, then you can proceed by following the steps below.
To start, create a GenServer
that will launch the nuxt app and integrate it into the application supervision tree. Specify the path for the package.json
file of your nuxt app as the assets_path
. Note that this assets_path
does not necessarily have to be within your phoenix app itself.
defmodule NuxtServer do
use GenServer, restart: :permanent
require Logger
def start_link(assets_path, opts \\ []) do
GenServer.start(__MODULE__, [assets_path], opts)
end
def init([assets_path]) do
# The package.json under the assets folder should have a "nuxt" script defined in the scripts section
port = Port.open({:spawn, "npm run nuxt"}, [{:cd, assets_path}])
ref = Port.monitor(port)
{:ok, %{port: port, ref: ref, assets_path: assets_path}}
end
def handle_info({:DOWN, _, :port, _, _}, %{assets_path: assets_path, ref: ref, port: port}) do
Logger.error("Nuxt server is down, restarting ...")
Port.close(port)
Port.demonitor(ref)
{:ok, state} = init([assets_path])
{:noreply, state}
end
def handle_info({_prot, {:data, msg}}, s) do
Logger.debug(msg)
{:noreply, s}
end
def handle_info(msg, state), do: super(msg, state)
end
After setting up the GenServer
, you can then proceed with instructions on how to add a reverse proxy in phoenix, such as utilizing this library if you need to access everything through the phoenix http port.