wdiechmann

wdiechmann

Deployed Phoenix app does not honor css instructions

Finally, I did get everything right and managed to deploy my app (to be) in a dokku setup on one of my own servers - with bells and whistles, letsencrypt, and what not :smile:

Alas my moment of joy only lasted until I browsed my way to stage2.speicher.ltd :cry:

I hurried to verify that all ‘gets’ had status=200 - which they have (bar a couple of pics but that’s beside the point)

Then I did a local mix release (in fact I did this )

#!/bin/sh

mix do deps.get, deps.compile
npm install --prefix assets && \
  npm rebuild node-sass --prefix assets && \
  npm --prefix ./assets ci --progress=false --no-audit --loglevel=error

npm run --prefix ./assets deploy
mix phx.digest

NODE_ENV=prod \
  MIX_ENV=prod \
  APP_PORT=5000 \
  POOL_SIZE=10 \
  COOL_TEXT='tjuhej' \
  SECRET_KEY_BASE=xxx \
  DBUSER='xxx' \
  DBPWRD='xxx' \
  DBNAME='xxx' \
  DBHOST="xxx" \
  URLHOST='localhost' \
mix do compile, release

NODE_ENV=prod \
  MIX_ENV=prod \
  APP_PORT=5000 \
  POOL_SIZE=10 \
  COOL_TEXT='tjuhej' \
  SECRET_KEY_BASE=xxx \
  DBUSER='xxx' \
  DBPWRD='xxx' \
  DBNAME='xxx' \
  DBHOST="xxx" \
  URLHOST='localhost' \
_build/prod/rel/fish/bin/fish start

And sure enough everything was layed out with CSS as should be :face_with_thermometer:

Then I did docker exec -it 59dde6cc7690 /bin/bash on the host and looked at the css and js files in the build folder with ls -la priv/static/css && ls -la priv/static/js which provided me with

total 40
drwxr-xr-x    1 nobody   nobody        4096 Jun 19 08:17 .
drwxr-xr-x    1 nobody   nobody        4096 Jun 19 08:17 ..
-rw-r--r--    1 nobody   nobody       10309 Jun 19 08:17 app-ada34c09c604a70f521cfb3887f52835.css
-rw-r--r--    1 nobody   nobody        2775 Jun 19 08:17 app-ada34c09c604a70f521cfb3887f52835.css.gz
-rw-r--r--    1 nobody   nobody       10309 Jun 19 08:17 app.css
-rw-r--r--    1 nobody   nobody        2775 Jun 19 08:17 app.css.gz
total 240
drwxr-xr-x    1 nobody   nobody        4096 Jun 19 08:17 .
drwxr-xr-x    1 nobody   nobody        4096 Jun 19 08:17 ..
-rw-r--r--    1 nobody   nobody       85163 Jun 19 08:17 app-724019b72e83ce3178e2f240205ce182.js
-rw-r--r--    1 nobody   nobody       23286 Jun 19 08:17 app-724019b72e83ce3178e2f240205ce182.js.gz
-rw-r--r--    1 nobody   nobody       85163 Jun 19 08:17 app.js
-rw-r--r--    1 nobody   nobody          98 Jun 19 08:17 app.js.LICENSE-bcda1cd32249233358d1702647c75e56.txt
-rw-r--r--    1 nobody   nobody         108 Jun 19 08:17 app.js.LICENSE-bcda1cd32249233358d1702647c75e56.txt.gz
-rw-r--r--    1 nobody   nobody          98 Jun 19 08:17 app.js.LICENSE.txt
-rw-r--r--    1 nobody   nobody         108 Jun 19 08:17 app.js.LICENSE.txt.gz
-rw-r--r--    1 nobody   nobody       23286 Jun 19 08:17 app.js.gz

So, I thought - cache! Then I did browse stage2.speicher.ltd from a ‘new’ device but sadly the result is the same!

Have you got any clue what-so-ever then please share - I’m completely baffled here :slightly_frowning_face:

Most Liked

praveenperera

praveenperera

The way PurgeCSS works is the following:

  1. Does a regex search through the paths it was given and collects all the class names it found in the files
  2. Strips all definitions in your CSS files that was not found in step 1.

PurgeCSS can break your builds in a few ways:

  1. The regex definition you use does not capture all class names
  2. You did not point it to all the files containing references to the CSS classes
  3. You run PurgeCSS when the HTML/LiveView/View files aren’t present.

Looking at your Dockerfile: fish/Dockerfile at 91ab23a3e6ea8605a572c0b1f7c64bee3139adb4 · wdiechmann/fish · GitHub

I’m pretty sure what happened was 3.

At line 38 you run npm deploy. Which runs PurgeCSS.
https://github.com/wdiechmann/fish/blob/91ab23a3e6ea8605a572c0b1f7c64bee3139adb4/Dockerfile#L38

However, you only add the HTML files actually referencing the CSS classes into your Dockerimage at line 42
https://github.com/wdiechmann/fish/blob/91ab23a3e6ea8605a572c0b1f7c64bee3139adb4/Dockerfile#L38

Meaning when PurgeCSS ran it didn’t see any CSS classes being used anywhere. So it just went ahead and empties your entire CSS file.

Edit

I’ve uploaded the Dockerfile I use for my template repo that works with Phoenix + TailwindCSS + PurgeCSS

henrik

henrik

This sounds a bit like an over-aggressive PurgeCSS (https://tailwindcss.com/docs/controlling-file-size/#setting-up-purgecss-manually).

If you’re using PurgeCSS, maybe try removing it and see if it improves things?

otijhuis

otijhuis

Just to let you know, I’m responsible for the latest Dockerfile that’s in the phoenix releases documentation. So you can blame me if it doesn’t work :wink:

I just tried it again to see if anything broke but it works fine for me.

For it to work you need the following though:

  1. Have a proper config (url, server: true for phoenix to start and such)
  2. To test it in docker on a mac/windows machine you might have to disable the :inet6 transport option because it seems only docker on linux supports ipv6
  3. rename my_app to your app name in the Dockerfile

I looked at your Dockerfile and here are some tips:

  • Don’t use COPY . .. Always be as specific as possible. Docker makes heavy use of caching layers. For example, let’s say you edit a README.md file in the root of your project. That file doesn’t have anything to do with the build itself. But because you used COPY . ., which includes README.md, you’ve invalidated the cache. That means every step after the COPY . . will be executed again even if you didn’t change anything else. If your .dockerignore isn’t configured properly you can have some really hard to trace problems. You might copy things that are compiled for your mac into the linux container for instance. Yes, I’ve seen that happen :slight_smile:
  • If you have multiple RUN statements after each other, combine them into 1 run statement. Each RUN statement causes the creation of a new layer. For example, RUN chown -R nobody:nobody /app basically creates a copy of all the files in the app directory, just with new permissions. The originals aren’t changed and are still in the previous layer. Your image file just grew a lot in size, even though it’s “just” a permission change.
  • Try to separate the run/copy statements for elixir files and the assets. Because the COPY . . is at the top, all the npm commands are executed again, even when you only change elixir files.
  • Use multistage Dockerfiles. Right now you have only 1 FROM. This means that ALL build dependencies, node_modules, source and such end up in your final image even though you don’t need them to run your application. Your final image is 576Mb. When using the Dockerfile in the release docs for a new phoenix project (without db) you end up with an image around 22Mb in size. A huge difference. With multistage files you can separate the image/files you need for your build from the minimal image you need to just run the application.

This is basically why the Dockerfile in the release docs is the way it is. It’s all about optimising for caching (everything for the build itself) and size (the final image that runs in production).

You can optimise even further using buildkit for instance but that makes the Dockerfile a bit more complex so I didn’t include that in the docs.

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54250 245
New

We're in Beta

About us Mission Statement