Debugging staticfiles in production

Hey everyone,

Loving this community. I am a hobby engineer still learning the ropes, but getting more comfortable with Django and the web as I read a little more and tinker a little more.

I’ve having a ROUGH time trying to figure out why my production site can’t find my staticfiles. I outlined the issue on Stackoverflow. Surely there’s something simple I just can’t see.

To debug, I’ve been just repeatedly changing a setting, committing the change, and pushing it to heroku. It seems slow and clunky and messy, but I don’t know how else to debug locally because it works locally!

Any tips on debugging? Or any tips on what the heck is happening?

How are you running your server in production? If you’re using runserver (which I hope you’re not), check out the runserver documentation.

Otherwise, most of the time that I’ve had this problem, it’s caused by a mismatch between where my webserver (usually nginx) thinks the static files are and where they’re actually located.

[Edit] Sorry, missed the reference to heroku the first time. Looking more closely at your SO post, I see in installed apps you have ‘whitenoise.runserver_nostatic’, which is explicitly telling whitenoise not to serve static files. (Documented here: Using WhiteNoise in development)

I’ve never used either heroku or WhiteNoise, but it seems to me that removing that line is possibly one step toward a solution.

Ken

Thanks for the response and time, @KenWhitesell.

To clarify: I’m deploying in a Docker container on Heroku and WhiteNoise to serve static files.

My understanding is that ‘whitenoise.runserver_nostatic’ is to

disable Django’s static file handling and allow WhiteNoise to take over [link]

rather than telling WhiteNoise not to serve static files.

Here’s what I’m seeing

Two types of CSS files linked in my <head> tag:

  • <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css">
  • <link rel="stylesheet" href="/static/css/base.css">

Results:

  • The CDN file from the outside server is working.
  • My own /static/css/base.css is not working even though that file is located in my /project-folder/static/css/base.css location.
  • None of the admin styles are working.

image

When I push to heroku

I DO see this message:

remote: 145 static files copied to '/code/staticfiles'.

I would imagine you’re correct in that the webserver thinks the files are somewhere different.

Thanks for the correction on whitenoise. You’re quite correct, I had misread that paragraph the first time through.

Sorry I can’t help you, I’ve never used heroku, so I don’t know how to tell it to find the static files in /code/staticfiles.

Appreciate your time regardless, Ken! Thank you so much. I’ll keep digging.

Bumping this because it’s been over two weeks and I still can’t figure it out. I’ve been talking to Heroku support, but so far no luck.

Has anyone ever experienced this? Here is what is most peculiar to me at this point…

1) Can’t get error with DEBUG on

  • 200 OK response when DEBUG = 1 on Heroku
  • 500 error when DEBUG = 0 on Heroku

2) collectstatic says it’s working but isn’t putting files into STATIC_ROOT

I’ll just list steps to explain what I have experienced.

  1. git push heroku master
  2. Logs say, “147 static files copied to '/code/staticfiles', 443 post-processed.
  3. heroku run ls staticfiles/
  4. See nothing in this folder
  5. Double-check settings.py to find that STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
  6. heroku run python manage.py collectstatic --noinput
  7. heroku run ls staticfiles/
  8. Still see nothing in this folder.

guessing at the syntax, how about heroku run ls /code/staticfiles? That appears to be the directory being used. (I don’t know what the current directory would be on a heroku run ls staticfiles/ - perhaps trying a heroku run pwd or heroku run ls?)

Thanks for the attention again, @KenWhitesell.

heroku run pwd ==> /code

Here’s what I get from heroku run ls

Dockerfile  Pipfile.lock  challenges  docker-compose.yml  manage.py    pages            static       templates
Pipfile     README.md     db.sqlite3  heroku.yml          mybulmatags  records_project  staticfiles  users

And for completeness, I receive no output from heroku run ls /code/staticfiles

Making another guess - if you have the name of one specific file (hopefully unique or somewhat unusual), you could try:

heroku run find / -name whatever_file_you_want_to_find 

So for example, if you had a file named “home.html”, the command would be:

heroku run find / -name home.html

It will show you all the directories in which that file appears, assuming the find command is available.

(Sorry, I’m just taking potshots in the dark to try and help figure out what’s happening.)

Ken, you’re a beautiful human. I appreciate all your help. I was actually looking for a command like that but didn’t know one!

There’s this one javascript file I use that makes my menu work on mobile, so I searched for that.

heroku run find / -name base.js

It returned:

find: ‘/tmp/env.d’: Permission denied
find: ‘/proc/tty/driver’: Permission denied
find: ‘/proc/1/task/1/fd’: Permission denied
find: ‘/proc/1/task/1/fdinfo’: Permission denied
find: ‘/proc/1/task/1/ns’: Permission denied
find: ‘/proc/1/fd’: Permission denied
find: ‘/proc/1/map_files’: Permission denied
find: ‘/proc/1/fdinfo’: Permission denied
find: ‘/proc/1/ns’: Permission denied
/code/static/js/base.js

So I’m seeing the original file, but not the one collected for serving.

Ok, so that appears to confirm that the collectstatic actually isn’t copying files.

Could you manually do the manage.py collectstatic followed by the find to see if it works that way?

Of course.

Input: heroku run python manage.py collectstatic --noinput

Output: 147 static files copied to '/code/staticfiles'.

Input: heroku run find / -name base.js

Output:

find: ‘/proc/tty/driver’: Permission denied
find: ‘/proc/1/task/1/fd’: Permission denied
find: ‘/proc/1/task/1/fdinfo’: Permission denied
find: ‘/proc/1/task/1/ns’: Permission denied
find: ‘/proc/1/fd’: Permission denied
find: ‘/proc/1/map_files’: Permission denied
find: ‘/proc/1/fdinfo’: Permission denied
find: ‘/proc/1/ns’: Permission denied
find: ‘/tmp/env.d’: Permission denied
/code/static/js/base.js

Well, you’ve got me at this point, sorry. I hope someone with more (i.e. any) heroku experience can jump in and help you out.

Haha, thanks for the effort again, Ken!

I’ll throw out one more idea:

./manage.py collectstatic -v 3 --noinput

It’s possible that there’s an error message not being displayed for some reason.

Nice idea! I only get a bunch of lines that say Copying '/relative/path/to/file.js' but nothing indicating an error.

Update for you, @KenWhitesell:

I talked with Matthew Freire from justdjango.com and he suggested just moving the files to an S3 bucket. It wasn’t a totally smooth transition, but it eventually solved my problems.

He hypothesized that Heroku wouldn’t let me adjust the files with heroku run commands or with manage.py collectstatic commands. Can’t confirm if that’s true, though.

Let me just say: deployment is a hard problem.

I’m glad you found an answer! I do have another source to check out that I have bookmarked as a resource: https://github.com/jlgimeno/wagtail-heroku-deployment. I got this from a Wagtail CMS tutorial and have had success with it in the past.

Maybe something in there will help.

-Jorge

Thanks for the update. That would make me curious to know whether or not doing the collectstatic before deployment to heroku would work in this case. (In other words, pushing your code out there with your static files already in code/staticfiles. I’m sure it’s a moot issue at this point. I’ll probably need to make the effort to learn something about heroku in the not-too-distant future.)