Trouble deploying LiveView/Flowbite app to Fly.io

I have a Phoenix/LiveView app that uses Flowbite. Locally, everything renders as expected. However, when I deploy the app to Fly.io, all tailwind styling is absent. I followed the instructions at https://flowbite.com/docs/getting-started/phoenix/#install-flowbite to get Flowbite integrated with my app.

One last thing, when I pull up my app at https://irvine-my-app.fly.dev/ and look in the dev console, I see what is probably indicative of the problem:

app.css:1     Failed to load resource: the server responded with a status of 404 ()

Any ideas on what my problem might be would be much appreciated. Thanks

It seems that the route to the app.css is broken because it is returning a 404 and in your website nothing is loading its style.

Could you share the code snippet where you load the app.css? Check it, because maybe it works nice in your local because you set some path that works there but no with the directory structure in Fly.io.

I would inspect your layout, but now I am not in the computer so I can’t check it.

Edit:

Checked, inspecting your website I see:

<link phx-track-static="" rel="stylesheet" href="/assets/app.css">

But https://irvine-my-app.fly.dev/assets/app.css is not there.

Could you confirm if you are getting some error when you deploy it?

See local console out below, but I’m not sure that the logs are complete. I suppose that there might be a way to get logs from Fly.io website, but I haven’t figured that out yet.

I suspect the the problem is due to inaccurate instructions given at the Flowbite website as referenced in my original post. I can see that the instructions are from before the release of Phx 1.7x. All that I did to create the app was:

  1. Created the app with “mix phx.new my_app”.
  2. Launched the app at Fly.io. The app came up fine with no styling problems.
  3. Followed the Flowbite instructions for Phoenix integration. (Instruction referenced in my original post).
  4. Redeployed the app again to Fly.io. This time all styling was absent.

And nothing else. I strongly suspect that anyone doing the same would reproduce the problem.

% fly deploy
Update available 0.1.4 -> 0.1.8.
Run "fly version upgrade" to upgrade.
==> Verifying app config
Validating /Users/charlesirvine/src/my_app/fly.toml
Platform: machines
âś“ Configuration is valid
--> Verified app config
==> Building image
Remote builder fly-builder-shy-fire-2325 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
[+] Building 0.0s (0/1)                                                                                                                                                                                                                                                                                                                           
[+] Building 9.3s (28/28) FINISHED                                                                                                                                                                                                                                                                                                                
 => [internal] load remote build context                                                                                                                                                                                                                                                                                                     0.0s
 => copy /context /                                                                                                                                                                                                                                                                                                                          0.2s
 => [internal] load metadata for docker.io/hexpm/elixir:1.14.2-erlang-25.2-debian-bullseye-20221004-slim                                                                                                                                                                                                                                     0.3s
 => [internal] load metadata for docker.io/library/debian:bullseye-20221004-slim                                                                                                                                                                                                                                                             0.3s
 => [builder  1/17] FROM docker.io/hexpm/elixir:1.14.2-erlang-25.2-debian-bullseye-20221004-slim@sha256:ce3e96acf4c13abe335d9f1ae2099037f8593f07e2bdf2387307c5c6bb9472cb                                                                                                                                                                     0.0s
 => [stage-1 1/6] FROM docker.io/library/debian:bullseye-20221004-slim@sha256:b46fc4e6813f6cbd9f3f6322c72ab974cc0e75a72ca02730a8861e98999875c7                                                                                                                                                                                               0.0s
 => CACHED [builder  2/17] RUN apt-get update -y && apt-get install -y build-essential git     && apt-get clean && rm -f /var/lib/apt/lists/*_*                                                                                                                                                                                              0.0s
 => CACHED [builder  3/17] WORKDIR /app                                                                                                                                                                                                                                                                                                      0.0s
 => CACHED [builder  4/17] RUN mix local.hex --force &&     mix local.rebar --force                                                                                                                                                                                                                                                          0.0s
 => CACHED [builder  5/17] COPY mix.exs mix.lock ./                                                                                                                                                                                                                                                                                          0.0s
 => CACHED [builder  6/17] RUN mix deps.get --only prod                                                                                                                                                                                                                                                                                      0.0s
 => CACHED [builder  7/17] RUN mkdir config                                                                                                                                                                                                                                                                                                  0.0s
 => CACHED [builder  8/17] COPY config/config.exs config/prod.exs config/                                                                                                                                                                                                                                                                    0.0s
 => CACHED [builder  9/17] RUN mix deps.compile                                                                                                                                                                                                                                                                                              0.0s
 => CACHED [builder 10/17] COPY priv priv                                                                                                                                                                                                                                                                                                    0.0s
 => CACHED [builder 11/17] COPY lib lib                                                                                                                                                                                                                                                                                                      0.0s
 => [builder 12/17] COPY assets assets                                                                                                                                                                                                                                                                                                       0.1s
 => [builder 13/17] RUN mix assets.deploy                                                                                                                                                                                                                                                                                                    5.4s
 => [builder 14/17] RUN mix compile                                                                                                                                                                                                                                                                                                          0.9s
 => [builder 15/17] COPY config/runtime.exs config/                                                                                                                                                                                                                                                                                          0.0s 
 => [builder 16/17] COPY rel rel                                                                                                                                                                                                                                                                                                             0.0s 
 => [builder 17/17] RUN mix release                                                                                                                                                                                                                                                                                                          1.7s 
 => CACHED [stage-1 2/6] RUN apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales   && apt-get clean && rm -f /var/lib/apt/lists/*_*                                                                                                                                                                               0.0s 
 => CACHED [stage-1 3/6] RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen                                                                                                                                                                                                                                                    0.0s 
 => CACHED [stage-1 4/6] WORKDIR /app                                                                                                                                                                                                                                                                                                        0.0s
 => CACHED [stage-1 5/6] RUN chown nobody /app                                                                                                                                                                                                                                                                                               0.0s
 => [stage-1 6/6] COPY --from=builder --chown=nobody:root /app/_build/prod/rel/my_app ./                                                                                                                                                                                                                                                     0.2s 
 => exporting to image                                                                                                                                                                                                                                                                                                                       0.2s 
 => => exporting layers                                                                                                                                                                                                                                                                                                                      0.2s
 => => writing image sha256:4bd0b908c72590d391840b23c17eeaae8b597567541ffb0b996712b99344fe09                                                                                                                                                                                                                                                 0.0s
 => => naming to registry.fly.io/irvine-my-app:deployment-01H126VH0YCFJXVRB6XK71DYMT                                                                                                                                                                                                                                                         0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/irvine-my-app]
1c27cd583a47: Pushed 
42a5c091208b: Layer already exists 
362def4856e3: Layer already exists 
9aeb36868f46: Layer already exists 
a4f93aad2b0e: Layer already exists 
fe7b1e9bf792: Layer already exists 
deployment-01H126VH0YCFJXVRB6XK71DYMT: digest: sha256:29a4e688df6830f0783c54bc89aefd4d4e60d2074becd7d1be725eb9a750712b size: 1576
--> Pushing image done
image: registry.fly.io/irvine-my-app:deployment-01H126VH0YCFJXVRB6XK71DYMT
image size: 124 MB

Watch your app at https://fly.io/apps/irvine-my-app/monitoring

Running irvine-my-app release_command: /app/bin/migrate
  release_command 91857004a42383 completed successfully
Updating existing machines in 'irvine-my-app' with rolling strategy
  [1/2] Machine e784e775f2e283 [app] update finished: success
  [2/2] Machine 3d8d9115ae0689 [app] update finished: success
  Finished deploying

Visit your newly deployed app at https://irvine-my-app.fly.dev/

Here are the specific Flowbite integration instructions, which seem to work for local deployment but not for Fly.io deployment:

  1. Cd to the assets dir and install the Flowbite package using NPM:
npm install flowbite
  1. Require the Flowbite plugin inside tailwind.config.js:
module.exports = {

    plugins: [
        require('flowbite/plugin')
    ]

}
  1. Set up the template paths for the Flowbite JS file:
module.exports = {

    content: [
        './node_modules/flowbite/**/*.js'
    ]

}
  1. Finally, import the Flowbite JS package inside the default ./assets/js/app.js file.
// ...

import "flowbite/dist/flowbite.phoenix.js";

// other Phoenix packages

what does the assets directory look like after you install flowbite? It’s possible that npm is doing something in the installation that overwrites the whole directory. If you edit the /assets/app.css file in the developer toolbox in a chromium based browser the styling gets applied correctly but the file is blank to start with.

The problem was that the node_modules directory wasn’t deployed via the generated docker file, since it was explicitly ignored in the generated .dockerignore file. Once the problem was corrected, assets were correctly deployed and everything was styled correctly.

2 Likes