Unable to deploy Phoenix app without assets

Hi all,

I am trying to deploy pretty basic Phoenix 1.6.6 app that was created with --no-html --no-assets --no-gettext --no-live, but it’s failing on assets with this message:

 => ERROR [builder 11/17] COPY assets assets                                                                              0.0s
------
 > [builder 11/17] COPY assets assets:
------
Error error building: failed to compute cache key: "/assets" not found: not found

I tried to “fix” it by creating an empty /assets folder, but now it’s complaining about this:

 => ERROR [builder 12/17] RUN mix assets.deploy                                                                           1.5s
------
 > [builder 12/17] RUN mix assets.deploy:
#21 0.987 Generated payday app
#21 1.473 ** (Mix) The task "assets.deploy" could not be found
------
Error error building: executor failed running [/bin/sh -c mix assets.deploy]: exit code: 1

Any ideas how to solve this? (other than re-generating the app)
I feel that it’s a bug in the flyctl launch command.

Thanks a lot. :slight_smile:

What happens when you build it locally? (i.e. run the mix assets.deploy command on your local machine)

Of course this, since I used the --no-assets flag.

** (Mix) The task "assets.deploy" could not be found

I temporarily commented out that step in the Dockerfile and it’s working. I am not sure if that’s the way to do it, I am completely new to fly.io, but I would assume that the flyctl launch task will detect there’s no /assets folder and skip that step automatically.

Fly is not really that “automatic” (although I suspect it can be with the user of buildpacks).

flyctl launch will simply build the Dockerfile and host it. It won’t perform any introspection on the app to determine how it should be built like say Heroku will. So, what you’ve done with removing the step from the Dockerfile seems correct. You have no assets so simply don’t try to build them.

For what it’s worth, I also host a Phoenix app on Fly where Phoenix doesn’t manage the assets (Webpack does). My Dockerfile looks like:

FROM elixir:1.13.1 as builder

EXPOSE 4000

ENV APP_HOME=/usr/src/app \
  HEX_HOME=/opt/hex \
  HEX_HTTP_CONCURRENCY=2 \
  HEX_HTTP_TIMEOUT=30 \
  LANG=C.UTF-8 \
  MIX_HOME=/opt/mix \
  MIX_ENV=prod \
  REFRESHED_AT=2021-11-15

WORKDIR $APP_HOME

# install supporting tools
RUN mix local.hex --force
RUN mix local.rebar --force

# copy dependencies
COPY ./config config
COPY ./mix.exs ./mix.lock ./.formatter.exs ./

RUN mix do deps.get deps.compile, compile

COPY ./lib lib
COPY ./priv priv
COPY ./test test

COPY --from=frontend /usr/src/app/dist/* /usr/src/app/priv/static/assets/frontend/

RUN mix release production

#
# Deploy
#
FROM debian:bullseye as production

ENV APP_HOME=/usr/src/app \
    MIX_ENV=prod \
    LANG=C.UTF-8

EXPOSE 4000

WORKDIR $APP_HOME

# Install libs
RUN apt-get update && \
    apt-get install -yq \
    libssl-dev \
    imagemagick \
    --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

COPY --from=builder $APP_HOME/_build/prod/rel/production $APP_HOME

CMD bin/production start

One word of advice, it’s worth including the assets functionality of Phoenix even if you’re not using it because:

  1. Many third party libs rely on it, i.e. if you want to enable Live Dashboard or some kind of automatically generated admin for you app, it’s helpful to have it.

  2. It’s used in unexpected places. I.e. error pages rely on the assets.

I disabled the assets in my app then wound up just bringing them mostly back again to support those two use cases. Might be something to think about :slightly_smiling_face:

3 Likes

Thanks a lot. That’s a lot of useful information. :slight_smile:

@sam gave a great answer.

We use Phoenix’s release generator to generate the Dockerfile. It would make sense for it to detect assets and other optional setups, though.

Right now, editing your Dockerfile is exactly what you should do.

1 Like