Open webdz9r opened 2 months ago
Hi,
This is documented in the .env
file with a comment: https://github.com/nickjj/docker-flask-example/blob/93af9f4fbf185098ffb1d120ee0693abcd77a38b/.env.example#L15
For production mode, you'll want to make sure all 4 of these are set:
export COMPOSE_PROFILES=postgres,redis,web,worker
export DOCKER_WEB_VOLUME=./public:/app/public
export FLASK_DEBUG=false
export NODE_ENV=production
Technically the last 2 are the default values, so by not setting them in the .env
file you get the same effect.
Once you've done that then you can docker compose build
to build your image that'll have assets precompiled and then they will be served in production directly without tailwind and esbuild running when you next docker compose up
the project. Each asset file will also be digested too with an md5 checksum which you can verify by viewing the source of the page.
Hi Nick,
thanks for the response. In production I was getting the debug toolbar until I changed config/settings.py
to use strict values
-SECRET_KEY = os.getenv("SECRET_KEY", "supersecret")
-DEBUG = bool(strtobool(os.getenv("FLASK_DEBUG", "false")))
-PROFILE = bool(strtobool(os.getenv("FLASK_PROFILE", "false")))
+SECRET_KEY = "xxxxxxx"
+
+DEBUG = False
Maybe it was a cached build problem, I'm not sure
Hmm you can always run docker compose build --no-cache
to get a fresh build without cache coming into play.
is it normal to have the JS and CSS rebuild like that in the background - I assume that means it's rebuilding something and configuration is not right
is it normal to have the JS and CSS rebuild like that in the background
In my previous comment I mentioned setting export COMPOSE_PROFILES=postgres,redis,web,worker
, did you set that? That would prevent tailwind and esbuild from running.
Once you've done that then you can docker compose build to build your image that'll have assets precompiled and then they will be served in production directly without tailwind and esbuild running when you next docker compose up the project. Each asset file will also be digested too with an md5 checksum which you can verify by viewing the source of the page.
I have the following set as I'm not using celery or postgres at the moment
export COMPOSE_PROFILES=redis,assets,web
In that case the JS and CSS won't get recompiled or run in the background. They are precompiled once at Docker image build time and then are served on each request by either gunicorn or nginx if you add that into that mix.
could you help me understand the function for this variable FLASK_SKIP_DOTENV="true" \
Seems that we always want env variables?
Yes, that stemmed from this issue: https://github.com/pallets/flask/issues/3872
Docker Compose already makes environment variables available without needing the dotenv Python package. Without setting that env var then all flask
CLI commands throw a warning saying to use doteven even if you don't need it. The current maintainer of Flask didn't want to disable that setting by default so we set that environment variable.
Hi Nick thanks again for working with me on these items.
I'm having the worst time getting my production configurations working properly and missing CSS / JS modules.
If I wanted to install Preline and tailwind typography / forms - wouldn't I just follow the install docs provided for each?
Seems the pipelines are not properly adding those packages and I'm having to include the CDN version inside my main template to get them working.
You might be thinking... "this is basic" and that's because I don't understand nodes role and asset compiling when it comes to packaging - I'm hoping for some quick tips to point me in the right direction for configuration and understanding as it relates to using flask *(this project) as a base
in the case of praline it's stating to include this in your template ''
but I'm not seeing any reference to ./node_modules/ folder generated on web container
another item - when trying to add tailwind/forms
I've added this to my Dockerfile for the asset pipeline
RUN npm install -D @tailwindcss/forms
edit my tailwind.config.js
module.exports = {
content: [
'/app/assets/js/**/*.js',
'/app/assets/css/**/*.css',
'/app/teetime/**/*.html',
'./node_modules/preline/dist/*.js'
],
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('preline/plugin')
],
darkMode: 'class'
}
when I run docker compose build
and docker compose up
web-1 | [2024-05-08 16:06:51 +0000] [1] [INFO] Starting gunicorn 21.2.0
web-1 | [2024-05-08 16:06:51 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
web-1 | [2024-05-08 16:06:51 +0000] [1] [INFO] Using worker: sync
web-1 | [2024-05-08 16:06:51 +0000] [7] [INFO] Booting worker with pid: 7
css-1 |
css-1 | Rebuilding...
css-1 | Error: Cannot find module '@tailwindcss/forms'
css-1 | Require stack:
css-1 | - /app/assets/tailwind.config.js
css-1 | at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
css-1 | at Function.resolve (node:internal/modules/helpers:136:19)
css-1 | at _resolve (/node_modules/jiti/dist/jiti.js:1:251148)
css-1 | at jiti (/node_modules/jiti/dist/jiti.js:1:253746)
css-1 | at /app/assets/tailwind.config.js:9:5
css-1 | at evalModule (/node_modules/jiti/dist/jiti.js:1:256443)
css-1 | at jiti (/node_modules/jiti/dist/jiti.js:1:254371)
css-1 | at /node_modules/tailwindcss/lib/lib/load-config.js:48:30
css-1 | at loadConfig (/node_modules/tailwindcss/lib/lib/load-config.js:50:6)
css-1 | at Object.loadConfig (/node_modules/tailwindcss/lib/cli/build/plugin.js:135:49) {
css-1 | code: 'MODULE_NOT_FOUND',
css-1 | requireStack: [ '/app/assets/tailwind.config.js' ]
css-1 | }
Hi,
You don't need to add the RUN
instruction. You can run ./run yarn:install
after adding the dependency to your package.json
file and it will take care of installing any new dependencies and also write out a new lock file. The readme file has this documented: https://github.com/nickjj/docker-flask-example?tab=readme-ov-file#updating-dependencies
does this behavior change from production vs development?
Yes, that's also mentioned in the docs and blog posts linked in the readme file.
In production assets will get digested and saved in a spot so you can reference them from a web server without needing to run the css
or js
containers.
I'm so close to getting this all sorted out...
I'm trying to install preline
yarn is doing it's thing properly but it seems that flask needs the /node_module/preline/dist/*.js files in order to work. What is the proper way to make those files available inside the application container. Seems that docker is only coping the /app/public folder
Here is what I was able to come up with (doesn't feel very gitops) in the Dockerfile for the app layer
## copy specific node_modules
# preline
COPY --from=assets --chown=python:python /node_modules/preline/dist/*.js /public/js/preline/
From there my package.json includes now work
"tailwindcss": "3.4.1",
"preline": "2.1.0",
"@tailwindcss/forms": "0.5.7",
"@tailwindcss/typography": "0.5.13"
and it's comparable with my tailwind.config.js
module.exports = {
content: [
'/app/assets/js/**/*.js',
'/app/assets/css/**/*.css',
'/app/teetime/**/*.html'
],
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('preline/plugin')
],
darkMode: 'class'
}
hopefully it helps and I welcome feedback on how to make it more turnkey / automatic
Hi, I never used that package. I'm not super well versed with esbuild but I wonder if there's anything you can do or configure to have it copy those files to a destination directory so you don't need to modify your Dockerfile.
Hi Nick,
It's me again, I'm new to ES build / Flask and fancy node based frontend stuff...
I've got an app in production and I'm seeing my logs continuesly state that it's rebuilding CSS and JS