Django+Docker Compose+WhiteNoise部署Railways时生产环境无法加载新JS文件(本地正常)
Hey there! Let’s dig into this 404 issue with your new JS files on Railways. I’ve gone through your configuration and have some targeted steps to debug and fix this:
1. First, Verify collectstatic Actually Runs & Collects New Files on Railways
Your start-django.sh runs collectstatic on container startup, but we need to confirm it’s working as expected in Railways’ environment:
- Check your Railways deployment logs for lines like
Copying 'static/js/your-new-file.js'from theCollect Static Filesstep. If you don’t see your new JS files listed here, that’s the root cause. - SSH into your Railways container (via the Railways dashboard’s "Console" tab) and run these commands to inspect the files:
# Check if your source static files exist ls static/js/ # Check if collectstatic copied them to STATIC_ROOT ls staticfiles/js/
If the new JS files are missing from staticfiles, double-check that your STATICFILES_DIRS is pointing to the correct directory (confirm BASE_DIR resolves to the right path in Railways with echo $BASE_DIR in the console).
2. Confirm Production Configs Are Actually Loading
Make sure your ENV_STATE environment variable is set to production in Railways:
- Go to your Railways service’s "Variables" tab and verify
ENV_STATE=productionis present. - In the container console, run this to check if your static files storage backend is correctly set to WhiteNoise:
poetry run python manage.py shell -c "from django.conf import settings; print(settings.STORAGES['staticfiles'])"
You should see 'BACKEND': 'whitenoise.storage.CompressedStaticFilesStorage' in the output.
3. Fix the Order of INSTALLED_APPS
Your INSTALLED_APPS has whitenoise.runserver_nostatic at the end, but it should come before django.contrib.staticfiles to properly disable Django’s built-in static file server in development (while not breaking production, it’s a best practice that avoids unexpected behavior):
INSTALLED_APPS = [ 'app.apps.AppConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'whitenoise.runserver_nostatic', # Move this here 'django.contrib.staticfiles', 'django.contrib.humanize', 'captcha', 'storages', ]
4. Move collectstatic to the Docker Build Stage (Instead of Startup)
Running collectstatic on container startup in Railways can lead to issues with ephemeral storage or delayed startup. Instead, run it during your Docker image build to bake static files into the image:
Add this line to your Dockerfile (after installing dependencies and copying your code):
RUN poetry run python manage.py collectstatic --no-input
Then remove the collectstatic line from start-django.sh (or keep it as a fallback, but build-time execution is more reliable for production).
5. Check WhiteNoise Middleware & Cache Behavior
- Your
MIDDLEWAREorder forWhiteNoiseMiddlewareis correct (right afterSecurityMiddleware), so that’s good. - If you’re 100% sure the files exist in
staticfilesbut still get 404s, force a cache bust by runningcollectstaticwith the--clearflag (add this to your build or startup script temporarily):poetry run python manage.py collectstatic --no-input --clear
This deletes the old staticfiles directory before collecting new files, ensuring no stale files are left behind.
6. Rule Out Path/Permission Issues
- In Railways, confirm the user running your container has read access to the
staticfilesdirectory. Runls -l staticfiles/in the console to check permissions. - Verify that
STATIC_ROOTis correctly set toBASE_DIR / "staticfiles"(printsettings.STATIC_ROOTin the shell to confirm the full path).
Let me know which step leads you to the fix! It’s almost always either collectstatic not running correctly, configs not loading, or path/permission issues in the production environment.
内容来源于stack exchange

