command "fly deploy" I get the error "Could not resolve "highlight.js""

Hi this is the error I get …

                                                                                                                                            5.1s 

[builder 13/17] RUN mix assets.deploy:
#0 0.946
#0 0.946 15:14:10.305 [debug] Downloading tailwind from https://github.com/tailwindlabs/tailwindcss/releases/download/v3.3.2/tailwindcss-linux-x64
#0 3.598
#0 3.598 Rebuilding…
#0 4.310
#0 4.310 Done in 829ms.
#0 4.335
#0 4.335 15:14:13.696 [debug] Downloading esbuild from https://registry.npmjs.org/@esbuild/linux-x64/0.17.11
#0 5.024 ✘ [ERROR] Could not resolve “highlight.js”
#0 5.024
#0 5.024 js/app.js:17:17:
#0 5.024 17 │ import hljs from “highlight.js”
#0 5.024 ╵ ~~~~~~~~~~~~~~
#0 5.024
#0 5.024 You can mark the path “highlight.js” as external to exclude it from the bundle, which will remove this error.
#0 5.024
#0 5.038 1 error
#0 5.046 ** (Mix) mix esbuild default --minify exited with 1


Hi @GerryWong ,

Sorry to hear you’re running into issues deploying your app. Are you able to run your application locally with Docker? Would you mind sharing your Dockerfile so we can take a look? It sounds like your dependencies aren’t being installed when your image is being built.

– Annie

Hi Annie

I am new to fly.io and I am not really doing anything with Docket. I have a Phoenix Elixir project where I use “fly Launch” to configure and then “fly deploy” to push changes out as I have new releases. I have done this process successfully to one web project before this one and now just deployed an API project and this was also successful. The only difference between the project with the above error and the other two that were successful is that I execute a " npm install highlight.js --prefix assets" to add a new JS library to this project and the other two I did not have any JS code to add. And this is where the error seems to be occurring during the import of dependences.

When using fly launch and fly deploy, we check to see if there’s a Dockerfile available in the project, and if one does not exist, we generate one. It sounds like whatever Dockerfile you have in your repo doesn’t include the command to install your npm dependencies (or at least not highlight.js).

My guess is that if this isn’t a Node application, when we generated the Dockerfile for your app, our CLI didn’t know to include npm install as part of the build step in your Dockerfile.

Are you able to share the contents of your Dockerfile? It should have been generated at the root of your project.

Regards,
Annie

Here it is …

Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian

instead of Alpine to avoid DNS resolution issues in production.

Docker

Docker

This file is based on these images:

- Docker - for the build image

- Docker - for the release image

- https://pkgs.org/ - resource for finding needed packages

- Ex: hexpm/elixir:1.15.7-erlang-26.1.2-debian-bullseye-20231009-slim

ARG ELIXIR_VERSION=1.15.7

ARG OTP_VERSION=26.1.2

ARG DEBIAN_VERSION=bullseye-20231009-slim

ARG BUILDER_IMAGE=“hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}”

ARG RUNNER_IMAGE=“debian:${DEBIAN_VERSION}”

FROM ${BUILDER_IMAGE} as builder

install build dependencies

RUN apt-get update -y && apt-get install -y build-essential git \

&& apt-get clean && rm -f /var/lib/apt/lists/_

prepare build dir

WORKDIR /app

install hex + rebar

RUN mix local.hex --force && \

mix local.rebar --force

set build ENV

ENV MIX_ENV=“prod”

install mix dependencies

COPY mix.exs mix.lock ./

RUN mix deps.get --only $MIX_ENV

RUN mkdir config

copy compile-time config files before we compile dependencies

to ensure any relevant config change will trigger the dependencies

to be re-compiled.

COPY config/config.exs config/${MIX_ENV}.exs config/

RUN mix deps.compile

COPY priv priv

COPY lib lib

COPY assets assets

compile assets

RUN mix assets.deploy

Compile the release

RUN mix compile

Changes to config/runtime.exs don’t require recompiling the code

COPY config/runtime.exs config/

COPY rel rel

RUN mix release

start a new build stage so that the final image will only contain

the compiled release and other runtime necessities

FROM ${RUNNER_IMAGE}

RUN apt-get update -y && \

apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \

&& apt-get clean && rm -f /var/lib/apt/lists/_

Set the locale

RUN sed -i ‘/en_US.UTF-8/s/^# //g’ /etc/locale.gen && locale-gen

ENV LANG en_US.UTF-8

ENV LANGUAGE en_US:en

ENV LC_ALL en_US.UTF-8

WORKDIR “/app”

RUN chown nobody /app

set runner ENV

ENV MIX_ENV=“prod”

Only copy the final release from the build stage

COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/mlmweb ./

USER nobody

If using an environment that doesn’t automatically reap zombie processes, it is

advised to add an init process such as tini via apt-get install

above and adding an entrypoint. See GitHub - krallin/tini: A tiny but valid `init` for containers for details

ENTRYPOINT [“/tini”, “–”]

CMD [“/app/bin/server”]

Thanks for sharing, and it looks like my suspicion was correct. The Dockerfile you have was generated for Elixir apps, but doesn’t include any instructions for installing JS dependencies. Fly.io uses whatever instructions are in your Dockerfile to build and serve your Pheonix application, but since you aren’t installing NodeJS or running npm install in yours, you’re running into the error you shared above.

I have limited Phoenix experience, so please use this advice as a starting point, but I believe you’d want to start by installing NodeJS on this line here:

# install build dependencies
RUN apt-get update -y && apt-get install -y build-essential git nodejs \
&& apt-get clean && rm -f /var/lib/apt/lists/_

Then somewhere you’ll likely need to include a RUN npm install, or perhaps even RUN npm install highlight.js --prefix assets as you were doing manually before. I’m not sure if this needs to be done before or after RUN mix assets.deploy, please use your best judgement here, once again I’m not an Elixir expert by any stretch, so you probably know better than I do.

Hope this gives you a place to start testing some things out!

Regards,
Annie