Heroku Configuation problem -- assets

I have one more problem now trying to configure a (heroku unmbrella) app as the error below shows. I use the app mostly to serve json, but there are a few barebones html pages served which use assets in static, as indicated below. However, Heroku seems to want such assets in ./assets along with various other files such as a package.json.

I have been followng https://hexdocs.pm/phoenix/heroku.html. It is possible that I set up this project with --no-brunch --no-html, as it was originally serving only json. The app works fine locally css and js files in priv/static as described below. I’m not using brunch and don’t know what it is.

$ tree -L 2 apps/koko_web/priv
apps/koko_web/priv
├── gettext
│ ├── en
│ └── errors.pot
└── static
├── css
└── js


As the error message shows, Heroku is looking for an assets folder.

remote: -----> Building dependencies
remote:        Installing and caching node modules
remote: /app/tmp/buildpacks/abc...0059be/lib/build.sh: 
line 105: cd: /tmp/build_5a13/./assets: No such file or directory
remote:  !     Push rejected, failed to compile Phoenix app.

What to do?

Notes added

(1) I tried deleting this buildpack: https://github.com/gjaldon/heroku-buildpack-phoenix-static.git – Still got the ./assets: No such file or directory error.

(2) Also tried creating a dummy ./assets folder … no dice, needs a package.json and other things. Couldn’t guess the structure needed.

Can you link/copy the assets of your web-app to the umbrella root?

If you do not have such a thing, try the following contents for your package.json:

{
  "name": "koko_assets",
  "description": "Minimal package JSON",
  "version": "0.0.1"
}

This should be a minimal one, that does not have any dependencies ore build-info in it. It’s just there to be found…

Progress of sorts. I now have assets at the root of the umbrella project, and that folder contains the mininal package.json file. However, I get the error below when I push to Heroku.

However, heroku’s build process seems not to know.

remote: -----> Building dependencies
remote:        Installing and caching node modules
remote: npm WARN package.json koko_assets@0.0.1 No repository field.
remote: npm WARN package.json koko_assets@0.0.1 No README data
remote: npm WARN package.json koko_assets@0.0.1 No license field.
remote:        npm WARN koko_assets@0.0.1 No repository field.
remote:        npm WARN koko_assets@0.0.1 No license field.
remote:        npm WARN package.json koko_assets@0.0.1 No repository field.
remote:        npm WARN package.json koko_assets@0.0.1 No README data
remote:        npm WARN package.json koko_assets@0.0.1 No license field.
remote:        Restoring cached assets
remote: sending incremental file list
remote: rsync: change_dir#3 "/tmp/build_8e429770499ee289b9d54a2e416cece9//priv" failed: No such file or directory (2
remote: rsync error: errors selecting input/output files, dirs (code 3) at main.c(712) [Receiver=3.1.1]
remote:  !     Push rejected, failed to compile Phoenix app.

Note There are references to directories priv :slight_smile:

$ ls */**/priv
apps/koko/priv:
repo

apps/koko_web/priv:
gettext	static

It seems as if you are missing a priv at the umbrella-root

1 Like

Put a priv at root and now get farther, with this error:

emote: sent 63 bytes  received 19 bytes  164.00 bytes/sec
remote: total size is 0  speedup is 0.00
remote:        Running custom compile
remote:        Hello, this the compile file ...
remote:        /tmp/build_8f0f770a95d7c1cb95771f79d6970026/compile: line 3: brunch: command not found
remote:  !     Push rejected, failed to compile Phoenix app.

I added the file compile with contents as below after getting errors on brunch. I inserted ther first line to make sure that the brunch: command not found` message referred to what I thought it did.

echo "Hello, this the compile file ..."

brunch build --production

cd $phoenix_dir

mix "${phoenix_ex}.digest"

if mix help "${phoenix_ex}.digest.clean" 1>/dev/null 2>&1; then
  mix "${phoenix_ex}.digest.clean"
fi

So – still at an impasse, though a different one – let’s call it progress! :slight_smile:

Notes added.

(1) I interpret the above as the buildpack wanting to run the brunch command on the compile file but not being able to find the command since it is not installed. If this is so, the question is then what kind of configuration is needed to install brunch. I’ve looked around, but most of the info is for setting up new projects.

(2) Of course, if I could do without brunch, that would be great. I don’t need it in development and would like to keep as simple a setup as possible.

There are 2 ways to solve this. Either add brunch to the packages.json or create a simple file:

#/!usr/bin/env bash

echo "Brunch faker"

This has to be saved at assets/node_modules/brunch/bin/brunch, also it has to be executable (chmod +x assets/node_modules/brunch/bin/brunch).

And a third way is to file an issue at heroku or the third party that maintains the build script to actually to support umbrellas (they are searching some stuff at the root which should be in a sub-app in umbrellas) and to support --no-html apps (they do not need those assets and brunch related stuff)

1 Like

I tried the fake brunch solution, but couldn’t get it to work for some reason.
In the end I forked the repo for the buildpack for static assets –

  https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

and modified the compile file to look like your faker file. Here is
the hacked buildpack:

  https://github.com/jxxcarlson/heroku-buildpack-phoenix-static

Using it, I was able to build the app on heroku.

Thanks so much for your help.

The README of that buildpack states:

Purpose

This buildpack is meant to be used with the Heroku Buildpack for Elixir. When deploying Phoenix apps to Heroku, static assets will need to be compiled. This buildpack sees to it that static assets are compiled and that a corresponding asset manifest is generated.

Since you do not have static assets at all, the easiest solution might probably have been to not add that buildpack to your project.

Yes, if you don’t have assets at all, don’t add this buildpack.

On a side note: you should not create assets folder in the umbrella root, but instead you should configure the buildpack correctly by editing it’s phoenix_static_buildpack.config.

In one app that I run, a 1.3 phoenix app with umbrella structure, I have apps/web/ for the web app, my config loosk like this:

clean_cache=false
compile="compile"
node_version=6.11.0
npm_version=3.10.10
phoenix_relative_path=apps/web
remove_node=false
assets_path=assets/
phoenix_ex=phx
1 Like

Progress …using your directions, I’ve managed to deploy the app. However, I get the error listed below:

[error] Could not find static manifest at 
"/app/_build/prod/lib/koko_web/priv/static/cache_manifest.json". 
Run "mix phoenix.digest"  after building your static files or 
remove the configuration from "config/prod.exs".

I did try removing the line below from koko_web/config/prod.exs but to no avail

 cache_static_manifest: "priv/static/cache_manifest.json"

,

Yes – finally got it to deploy and to run. Thank you so much!

Huge progress

I still have two issues, if you have time.

One is minor: the error

[error] Could not find static manifest at 
"/app/_build/prod/lib/koko_web/priv/static/cache_manifest.json". 
Run "mix phoenix.digest"  after building your static files or 
remove the configuration from "config/prod.exs".

It is annoying, but does not seem to cause any harm.

The other is a websocket config problem. At the moment, I just replaced

Phoenix.Socket.init "ws://localhost:4000/socket/websocket"

with

Phoenix.Socket.init "wss://mysterious-forest-36511.herokuapp.com/socket/websocket"

However, this gives the error

 12:54:12.902 [error] Could not check origin for Phoenix.Socket transport.

This happens when you are attempting a socket connection to
a different host than the one configured in your config/
files. For example, in development the host is configured
to "localhost" but you may be trying to access it from
"127.0.0.1". To fix this issue, you may either:

  1. update [url: [host: ...]] to your actual host in the
    config file for your current environment (recommended)

      endpoint or when configuring the transport in your

  2. pass the :check_origin option when configuring your
     UserSocket module, explicitly outlining which origins
     are allowed:

        check_origin: ["https://example.com", "//another.com:888", "//other.com"]

In koko_web/config/prod.exs I have the line

url: [scheme: "https", host: "mysterious-forest-36511.herokuapp.com", port: 443],

Would I add another line? Perhaps

url: [scheme: "wss", host: "mysterious-forest-36511.herokuapp.com", port: ???],

About 2nd issue, the config you have currently looks fine on a first glance.

Do you have Heroku environment variable of MIX_ENV set to “prod”? Maybe not, and it’s picking up dev.exs instead of prod.exs?

I tried setting MIX_ENV set to “prod” – that had no effect as far as I could see.

I then added the line check_origin: false to transport :websocket ... in koko_web/channels/user_socket.ex. That killed the old error message but revealed a .new one:

2017-08-01T14:41:55.758855+00:00 app[web.1]: Request: GET /socket/websocket
2017-08-01T14:41:55.758856+00:00 app[web.1]: ** (exit) an exception was raised:
2017-08-01T14:41:55.758856+00:00 app[web.1]:     ** (UndefinedFunctionError) function Koko.Web.UserSocket.connect/2 is undefined or private
2017-08-01T14:41:55.758858+00:00 app[web.1]:         (koko_web) Koko.Web.UserSocket.connect(%{}, %Phoenix.Socket{assigns: %{}, channel: nil, channel_pid: nil, endpoint: Koko.Web.Endpoint, handler: Koko.Web.UserSocket, id: nil, join_ref: nil, joined: false, private: %{}, pubsub_server: Koko.Web.PubSub, ref: nil, serializer: Phoenix.Transports.WebSocketSerializer, topic: nil, transport: Phoenix.Transports.WebSocket, transport_name: :websocket, transport_pid: #PID<0.566.0>})
2017-08-01T14:41:55.758858+00:00 app[web.1]:         (phoenix) lib/phoenix/socket/transport.ex:168: Phoenix.Socket.Transport.connect_vsn/6
2017-08-01T14:41:55.758859+00:00 app[web.1]:         (phoenix) lib/phoenix/transports/websocket.ex:88: Phoenix.Transports.WebSocket.init/2
2017-08-01T14:41:55.758860+00:00 app[web.1]:         (phoenix) lib/phoenix/endpoint/cowboy_websocket.ex:12: Phoenix.Endpoint.CowboyWebSocket.init/3

Also, I am getting the compiler warning (locally):

undefined behavior function connect/2 (for behavior Phoenix.Socket)	1:1

I don’t know what to do here, since i haven’t t[ouched Phoenix.Socket.connect

And locally it connects, rigth?

Can you show what’s your UserSocket like?

Yes, locally, with a slightly different configuration, it connects.

Here is my user_socket.ex file:

defmodule Koko.Web.UserSocket do
  use Phoenix.Socket

  ## Channels
  channel "room:*", Koko.Web.RoomChannel

  ## Transports

  # LOCAL CONFIG: transport :longpoll, Phoenix.Transports.LongPoll
  transport :websocket, Phoenix.Transports.WebSocket,
    timeout: 45_000,
    check_origin: false

  # check_origin: ["https://localhost:3000"]

 # ADDED JUST NOW -- I am going to test this.
  def connect(_params, socket) do
   # {:ok, assign(socket, :user_id, params["user_id"])}
   {:ok, assign(socket, :foo, ["bar"])}
  end

  
  # Returning `nil` makes this socket anonymous.
  def id(_socket), do: nil
end

Working now – I had to define my own connect/2 function.

I really appreciate your help.

What is your interest in Elixir/Phoenix?

I used to do a lot of Rails stuff with my web development company for our clients. We think now Elixir/Phoenix is pretty much better in majority of cases, and we’re shifting towards providing mostly Elixir services, rather than Ruby services.

Somewhat similar experience here, except that I am just developing one app for reasons connected with my profession (it is to create and distribute online lecture notes with technical content – math / physics, etc).

The first version was a Rails app. I learned a lot, but it was slow, needed a lot of memory, and became very difficult to maintain and add features to. After a lot of experimentation, I went to a system with a Phoenix back end and an Elm front end. Hope to have a beta release in September or October.

1 Like

Yep, that’s usual with Rails.

We’re doing production Elm apps already too :). Nice combo.