Deploying to Gigalixir not working

Deploying to prod on gigalixir shows: {"errors":{"detail":"Not Found"}}
No node for static files. It’s all API based.

When it’s delivered to dev it works.

$ - mix phx.server

[info] Running BujiWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:4000 (http)
[info] Access BujiWeb.Endpoint at http://localhost:4000

When it’s delivered to prod it doesn’t work

$ - MIX_ENV=prod mix phx.server
23:02:10.298 [info] Running BujiWeb.Endpoint with cowboy 2.9.0 at :::4000 (http)
23:02:10.310 [info] Access BujiWeb.Endpoint at http://${APP_NAME}.gigalixirapp.com:443

Any idea on why cowboy doesn’t show IP on prod? It crashes.

config/prod.exs

use Mix.Config

config :buji, BujiWeb.Endpoint,
  server: true,
  http: [port: {:system, "PORT"}], # Needed for Phoenix 1.2 and 1.4. Doesn't hurt for 1.3.
  url: [host: "${APP_NAME}.gigalixirapp.com", port: 443],
  secret_key_base: "${SECRET_KEY_BASE}",
  version: Mix.Project.config[:version] #To bust cache during hot updgrades

config :buji, Buji.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: "${DATABASE_URL}",
  database: "",
  ssl: true,
  pool_size: 2

# For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information
# when generating URLs.
#
# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix phx.digest` task,
# which you should run after static files are built and
# before starting your production server.

# Do not print debug messages in production
config :logger, level: :info

Any idea on why cowboy doesn’t show IP on prod?

It does show it, but it’s using ipv6 where zeros are ommited, :::4000, means it binds on all interfaces. I haven’t used gigalixir, but if I were you I’d double-check if ${APP_NAME}.gigalixirapp.com is interpreted correctly by gigalixir, since it seems like it’s not, otherwise it would’ve been replaced with env vars at

23:02:10.310 [info] Access BujiWeb.Endpoint at http://${APP_NAME}.gigalixirapp.com:443

By default neither phoenix nor elixir config support env var templates like this.

Where did you run above cmd?

Could you post all gigalixir log here, there must be more information about the error.

This is what the doc says, but it seems outdated. Will try a different way.
https://gigalixir.readthedocs.io/en/latest/modify-app/distillery.html

The above command is ran locally to test prod environment. Prod log is below. Most recent.

 Attempting to start 'lumbering-harmful-lcont' on host 'b'lumbering-harmful-lcont-55f9c5b8bf-jwtvd''
 Attempting health checks on port 4000
 web.1  | started with pid 39
 Your app is failing health checks, which means it isn't listening on port 4000 yet.
 Readiness probe failed: dial tcp 10.56.21.187:4000: connect: connection refused
 web.1  | 15:29:11.957 [info] Running BujiWeb.Endpoint with cowboy 2.9.0 at :::4000 (http)
 web.1  | 15:29:11.957 [info] Access BujiWeb.Endpoint at http://lumbering-harmful-lcont.gigalixirapp.com:443
 Stopping container lumbering-harmful-lcont

config/prod.exs

use Mix.Config

config :buji, BujiWeb.Endpoint,
  server: true,
  http: [port: {:system, "PORT"}], # Needed for Phoenix 1.2 and 1.4. Doesn't hurt for 1.3.
  url: [host: "${APP_NAME}.gigalixirapp.com", port: 443],
  secret_key_base: "${SECRET_KEY_BASE}",
  version: Mix.Project.config[:version] #To bust cache during hot updgrades

config :buji, Buji.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: "${DATABASE_URL}",
  database: "",
  ssl: true,
  pool_size: 2

# For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information
# when generating URLs.
#
# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix phx.digest` task,
# which you should run after static files are built and
# before starting your production server.

# Do not print debug messages in production
config :logger, level: :info

# ## SSL Support
#
# To get SSL working, you will need to add the `https` key
# to the previous section and set your `:url` port to 443:
#
#     config :buji, BujiWeb.Endpoint,
#       ...
#       url: [host: "example.com", port: 443],
#       https: [
#         port: 443,
#        cipher_suite: :strong,
#         keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
#         certfile: System.get_env("SOME_APP_SSL_CERT_PATH"),
#         transport_options: [socket_opts: [:inet6]]
#       ]
#
# The `cipher_suite` is set to `:strong` to support only the
# latest and more secure SSL ciphers. This means old browsers
# and clients may not be supported. You can set it to
# `:compatible` for wider support.
#
# `:keyfile` and `:certfile` expect an absolute path to the key
# and cert in disk or a relative path inside priv, for example
# "priv/ssl/server.key". For all supported SSL configuration
# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
#
# We also recommend setting `force_ssl` in your endpoint, ensuring
# no data is ever sent via http, always redirecting to https:
#
#     config :buji, BujiWeb.Endpoint,
#       force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.

# Finally import the config/prod.secret.exs which loads secrets
# and configuration from environment variables.
import_config "prod.secret.exs"
                                                                                                                                            66,1          Bot



This is what works for me:

config :testivator, TestivatorWeb.Endpoint,
  http: [port: {:system, "PORT"}],
  load_from_system_env: true,
  cache_static_manifest: "priv/static/cache_manifest.json",
  check_origin: ["//testivator.com"],
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  live_view: [signing_salt: System.get_env("AUTHENTICATOR_SEED")]

I also have releases.exs

config :testivator, TestivatorWeb.Endpoint, server: true

So, I rewrote everything to release.exs.
Same problem

2021-09-17T03:17:37+00:00 lumbering-harmful-lcont[gigalixir]: Readiness probe failed: dial tcp 10.56.19.207:4000: connect: connection refused
2021-09-17T03:17:40.790886+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-5d5f49c65f-5szsh']: web.1  | 03:17:40.788 [info] Running BujiWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:4000 (http)
2021-09-17T03:17:40.790927+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-5d5f49c65f-5szsh']: web.1  | 03:17:40.789 [info] Access BujiWeb.Endpoint at http://lumbering-harmful-lcont.gigalixirapp.com:443
2021-09-17T03:17:40+00:00 lumbering-harmful-lcont[gigalixir]: Your app is failing health checks, which means it isn't listening on port 4000 yet.
2021-09-17T03:17:40+00:00 lumbering-harmful-lcont[gigalixir]: Readiness probe failed: dial tcp 10.56.19.207:4000: connect: connection refused
2021-09-17T03:17:43+00:00 lumbering-harmful-lcont[gigalixir]: Stopping container lumbering-harmful-lcont
2021-09-17T03:18:13.935005+00:00 lumbering-harmful-lcont[gigalixir-run]: Shutting down 'lumbering-harmful-lcont' on host 'b'lumbering-harmful-lcont-68c94b6c86-8spsg''
2021-09-17T03:18:16+00:00 lumbering-harmful-lcont[gigalixir]: Readiness probe failed: dial tcp 10.56.19.205:4000: i/o timeout

config/release.exs

# In this file, we load production configuration and secrets
# from environment variables. You can also hardcode secrets,
# although such is generally not recommended and you have to
# remember to add this file to your .gitignore.
import Config

database_url =
  System.get_env("DATABASE_URL") ||
    raise """
    environment variable DATABASE_URL is missing.
    For example: ecto://USER:PASS@HOST/DATABASE
    """

config :buji, Buji.Repo,
  adapter: Ecto.Adatpers.Postgres,
  ssl: true,
  database: "",
  url: database_url,
  pool_size: String.to_integer("2")

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
    """

config :buji, BujiWeb.Endpoint,
  server: true,
  http: [port: {:system, "PORT"}], # Needed for Phoenix 1.2 and 1.4. Doesn't hurt for 1.3.
  url: [host: System.get_env("APP_NAME") <> ".gigalixirapp.com", port: 443]

Locally, tried it too. Got this

buji$ _build/prod/rel/buji/bin/buji start
23:24:34.721 [info] Running BujiWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:4000 (http)
23:24:34.721 [info] Access BujiWeb.Endpoint at http://buji.gigalixirapp.com:443
23:24:44.568 request_id=FqV-GLTAejuGpPoAAAAE [info] GET /
23:24:44.569 request_id=FqV-GLTAejuGpPoAAAAE [info] Sent 404 in 587µs

To give context, I don’t have webpack. Purely using elixir for API. The root url shows this in local dev

If I use local dev to connect to the API it works. But in prod it doesn’t. Anything else I should try I’ve exhausted 3 of the options to deploy(release, mix, distillery). It must be something I’ve done because it’s only API based. I tried the getting started with webpack and it works.

Here’s an update, since I ran the command below to only have API’s.
mix phx.new ~/Workspace/hello_world --no-html --no-webpack

I thought deleting the Plug.Static would change things in /lib/APP_NAME/APP_NAME_WEB/endpoint.ex. The section below was deleted since I don’t need it.

 # Serve at "/" the static files from "priv/static" directory.
  #
  # You should set gzip to true if you are running phx.digest
  # when deploying your static files in production.
  plug Plug.Static,
    at: "/",
    from: :buji,
    gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt)

Gigalixir has now the following error log:

2021-09-19T00:17:58.664965+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | {"init terminating in do_boot",{#{'__exception__'=>true,'__struct__'=>'Elixir.TokenMissingError',description=><<"syntax error: expression is incomplete">>,file=><<"/app/releases/0.1.0/releases.exs">>,line=>34},[{'Elixir.Code',eval_string_with_error_handling,3,[{file,"lib/code.ex"},{line,340}]},{'Elixir.Config','__eval__!',2,[{file,"lib/config.ex"},{line,219}]},{'Elixir.Config.Reader','read!',2,[{file,"lib/config/reader.ex"},{line,57}]},{'Elixir.Config.Reader',load,2,[{file,"lib/config/reader.ex"},{line,37}]},{'Elixir.Config.Provider','-run_providers/2-fun-0-',2,[{file,"lib/config/provider.ex"},{line,334}]},{'Elixir.Enum','-reduce/3-lists^foldl/2-0-',3,[{file,"lib/enum.ex"},{line,2111}]},{'Elixir.Config.Provider',boot_providers,4,[{file,"lib/config/provider.ex"},{line,203}]}]}}
2021-09-19T00:17:58.665376+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | init terminating in do_boot ({,[{Elixir.Code,eval_string_with_error_handling,3,[{_},{_}]},{Elixir.Config,__eval__!,2,[{_},{_}]},{Elixir.Config.Reader,read!,2,[{_},{_}]},{Elixir.Config.Reader,load,2,[{
2021-09-19T00:17:58.668595+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | 
2021-09-19T00:17:58.877451+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | Crash dump is being written to: erl_crash.dump...done
2021-09-19T00:17:59.447048+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | exited with code 1
2021-09-19T00:17:59.447319+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: system | sending SIGTERM to all processes
2021-09-19T00:20:54.520695+00:00 lumbering-harmful-lcont[gigalixir-run]: Attempting to start 'lumbering-harmful-lcont' on host 'b'lumbering-harmful-lcont-6878c854c5-l48tm''
2021-09-19T00:20:54.520706+00:00 lumbering-harmful-lcont[gigalixir-run]: Attempting health checks on port 4000
2021-09-19T00:20:54.975727+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | started with pid 39
2021-09-19T00:20:56.467337+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | ERROR! Config provider Config.Reader failed with:
2021-09-19T00:20:56.468080+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | ** (TokenMissingError) releases/0.1.0/releases.exs:34: syntax error: expression is incomplete
2021-09-19T00:20:56.468164+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/code.ex:340: Code.eval_string_with_error_handling/3
2021-09-19T00:20:56.468369+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/config.ex:219: Config.__eval__!/2
2021-09-19T00:20:56.468407+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/config/reader.ex:57: Config.Reader.read!/2
2021-09-19T00:20:56.468528+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/config/reader.ex:37: Config.Reader.load/2
2021-09-19T00:20:56.468561+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/config/provider.ex:334: anonymous fn/2 in Config.Provider.run_providers/2
2021-09-19T00:20:56.468604+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
2021-09-19T00:20:56.468635+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  |     (elixir 1.10.4) lib/config/provider.ex:203: Config.Provider.boot_providers/4
2021-09-19T00:20:56.468778+00:00 lumbering-harmful-lcont[b'lumbering-harmful-lcont-6878c854c5-l48tm']: web.1  | 

So what’s around line 34 in config/releases.exs?

This instructions worked for me: Using Elixir Releases — GIGALIXIR 1.4.0 documentation