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
Alas my moment of joy only lasted until I browsed my way to stage2.speicher.ltd
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 )
And sure enough everything was layed out with CSS as should be
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
I assume that the problem is that your website is missing the expected style, correct?
At a first look it seems that your CSS bundle, https://stage2.speicher.ltd/css/app-ada34c09c604a70f521cfb3887f52835.css, does not contain all the rules that one would expect looking at your HTML. For example, there are no rules for the HTML classes max-w-screen-xl, mx-auto, and many of those framework classes that you use.
In other words your assets are correctly compiled and served, but they miss some expected content. Itās hard to guess why without looking at your code, but first of all I would look into your assets to make sure that all the necessary CSS is included.
the question is more like: if I do a (local) mix release everything is in place and all CSS rules are honored - but without touching anything - when I do (the same) mix release, only now in a container (which is what technically is happening in a dokku deploy) the css is less than half the size!!
-rw-r--r-- 1 walther staff 28898 19 Jun 10:25 app-e8d95eb985318b44f69a005c82e5464e.css
-rw-r--r-- 1 walther staff 6168 19 Jun 10:25 app-e8d95eb985318b44f69a005c82e5464e.css.gz
vs the docker
-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
Iām going hunting in a dokku forum - this has obviously nothing to do with neither Elixir, nor Phoenix, but has to be a dokku thing of sorts!
If I do a local docker-compose up I bring my container alive on my own machine - with the ātrueā filesize of the bundled css, hence it has to be dokku that somehow fiddles with whatever part of the package
But I will report back onec I get this sorted out!
āyou hit me right in the pantalone, partenerā as Hrundi V Bakshi a.k.a Peter Sellers would have said
Iām in no way what so ever fluent in Webpack & Friends - operating on a strict āmonkey ordersā command by command.
I remember seeing PurgeCSS when I was meddling with Tailwind in order to get it glued into the project in the first place - but either I didnāt make it to the āsteamy finaleā or I dodged it, sorry cannot recall.
But the entire repo is at https://github.com/wdiechmann/fish.git - and Iād appreciate it a lot if anyone would spend a moment trying to help me push through this
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
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:
Have a proper config (url, server: true for phoenix to start and such)
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
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
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.
On the topic of multistage - oh Iād like that but Dokku complains about missing intermediates because it does a (too) wonderful job of cleaning up the build stage intermediates - and I havenāt solved how to keep them long enough to utilize multistage
@wdiechmann Ah, I donāt know anything about Dokku but if itās really the case that it doesnāt support multistage builds Iād consider that a serious red flag. Itās still a single Dockerfile and single docker build so there shouldnāt be any issues. Multistage is one of the most important docker features to me.
@praveenperera nice clean Dockerfile. Iād probably create a single base for both the deps-getter and release-builder steps since they both do the same apk installs. You shouldnāt need the mkdir commands. WORKDIR already creates the directory if it doesnāt exist and most others should be created automatically as well I believe. And Iād probably combine multiple COPY and multiple RUN statements wherever possible. Itās easier to read now though and doesnāt make too much of a difference anyway since they arenāt in the final image.