Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code reloading stopped working consistently when updating HTML templates #36

Closed
nickjj opened this issue Feb 18, 2023 · 4 comments
Closed
Labels
help wanted Extra attention is needed

Comments

@nickjj
Copy link
Owner

nickjj commented Feb 18, 2023

Set up

  • On the latest main branch, if you edit an HTML file gunicorn isn't picking up the change.

  • Django 4.1.X with Python 3.11.X but it's also an issue with Python 3.10.X too.

  • I tried a bunch of different code editors because I've run into situations where Vim's way of saving a file made it incompatible with certain file watchers. It's an issue with all of them that I tried (nano, Vim and VSCode).

Situation

After changing watched files you should see something like this:

hellodjango-web-1       | [2023-02-18 00:22:45 +0000] [8] [INFO] Worker reloading: /app/src/config/gunicorn.py modified
hellodjango-web-1       | [2023-02-18 00:22:45 +0000] [8] [INFO] Worker exiting (pid: 8)
hellodjango-web-1       | [2023-02-18 00:22:45 +0000] [10] [INFO] Booting worker with pid: 10

The above sometimes works if you edit the src/templates/layouts/index.html or src/pages/templates/pages/home.html and always works if you edit a Python file such as any views.py file. JS and CSS also get updated on change in development which is using esbuild and tailwind instead of gunicorn.

The appropriate env vars defined in the .env file appear to be set in the container's runtime environment:

nick@kitt ~/src/github/docker-django-example (main) $ run shell
python@49922f0f9045:/app/src$ python3
Python 3.11.1 (main, Feb  4 2023, 11:23:15) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> from distutils.util import strtobool
>>> bool(strtobool(os.getenv("DEBUG", "false")))
True
>>> bool(strtobool(os.getenv("WEB_RELOAD", "false")))
True
>>>

I also confirmed this in the app by going to the src/config/settings.py file and dropping in:

print(bool(strtobool(os.getenv("DEBUG", "false"))))
print(DEBUG)

The Docker Compose logs produce True for both. That is what we want since both are set to true in the .env.

The TEMPLATES configuration is:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [os.path.join(BASE_DIR, "templates")],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

Is that not correct?

I also removed the assets container thinking maybe esbuild 0.17.X is having an effect due to both containers sharing the same Docker bind mount and I wanted to reduce variables but the same problem happens. My other Flask example app is using the same version of gunicorn and esbuild and its HTML code reloading is working.

Little help?

@nickjj nickjj added the help wanted Extra attention is needed label Feb 18, 2023
@nickjj nickjj changed the title Code reloading stopped working in an app's HTML templates, but the layout works Code reloading stopped working consistently when updating HTML templates Feb 18, 2023
@chrisjsimpson
Copy link

Hey @nickjj 👋

I'm assuming you've already played with the compose options

tty

and

std-in

For attaching stdin (similar to when forcing a tty on ssh connections)

Sorry I've not dug deep but wanted to throw those out there incase you've not turned that stone

@nickjj
Copy link
Owner Author

nickjj commented Feb 18, 2023

Hi @chrisjsimpson,

Thanks, tty: true is set and stdin_open: true has no effect (it's not in my compose file but I did try it just now).

At some point in the past all of this worked in this app. My Flask, Rails, Node and Phoenix examples all work with HTML template, code and asset changes using the same Docker settings across the board too.

One step I should take is to start checking out older versions of this code and identify the last known good state. I'll probably start by looking for commits that change the versions of gunicorn and django.

@nickjj
Copy link
Owner Author

nickjj commented Feb 18, 2023

This has been resolved in f706a63.

It was due to Django 4.1+ caching templates by default even with DEBUG = True set.

Thanks @jefftriplett for pointing me to the changelog at https://docs.djangoproject.com/en/dev/releases/4.1/#templates when I tweeted this out https://twitter.com/nickjanetakis/status/1626938661500604417.

At least now I know I'm not crazy because these templates did reload in the past.

If anyone has a better implementation than what I did in that commit please open a PR.

@nickjj nickjj closed this as completed Feb 18, 2023
@nickjj
Copy link
Owner Author

nickjj commented Feb 18, 2023

So this is fun, I was able to determine why it was so inconsistent and how it sort of worked before the patch.

Before this patch if you edited any HTML template it would not get updated. However if you edited a Python file such as the settings file after editing the HTML then the HTML would update. While testing things initially I reduced variables by hard coding DEBUG = True but that action caused a Python file update, the code itself wasn't important. That's how I arrived at inconsistent behavior. In the end this likely means Django will reload cached templates if Python files are updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants