You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cookiecutter-Django替换Caddy为Nginx后静态文件无法加载求助

Fixing Static Files Loading with Nginx in Cookiecutter-Django Production Setup

Let's get your static files working properly with Nginx. The core issue here is that your Nginx container needs reliable access to the static files generated by Django's collectstatic command, which runs inside the Django container. Your previous attempts with volumes_from or copying the project might have hit permission issues or sync problems—here's the clean, maintainable fix:

Step 1: Use a Shared Volume for Static Files

Instead of trying to share the entire Django container's filesystem, create a dedicated Docker volume to store static files. This keeps things isolated and avoids permission conflicts.

Update your production.yml Docker Compose config:

# Add this at the bottom of the file to define the shared volume
volumes:
  static_files: {}

# Update the django service to mount this volume to STATIC_ROOT
django:
  # ... keep your existing config (build, env_file, etc.)
  volumes:
    - static_files:/app/staticfiles  # Matches Django's STATIC_ROOT (default in Cookiecutter-Django)

# Update the nginx service to mount the same volume
nginx:
  build:
    context: .
    dockerfile: ./compose/production/nginx/Dockerfile
  image: abs_production_nginx
  depends_on:
    - django
  ports:
    - "0.0.0.0:80:80"
  env_file:
    - ./.envs/.production/.nginx
  volumes:
    - static_files:/app/staticfiles  # This path needs to match the alias in your Nginx config

Step 2: Tweak Your Nginx Configuration

Make sure your Nginx config points to the correct path where the shared volume is mounted, and add proper caching headers for static files (good practice for production):

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    keepalive_timeout 65;

    upstream app {
        server django:5000;
    }

    server {
        listen 80;
        charset utf-8;

        # Serve static files directly from the shared volume
        location /static {
            alias /app/staticfiles;
            expires 30d;  # Cache static files for 30 days
            add_header Cache-Control "public, immutable";  # Tell browsers to cache aggressively
        }

        # If you need to serve media files (user uploads), add this too
        # Make sure to create a shared media volume similar to static_files if needed
        location /media {
            alias /app/media;
            expires 7d;
            add_header Cache-Control "public";
        }

        location / {
            try_files $uri @proxy_to_app;
        }

        location @proxy_to_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://app;
        }
    }
}

Step 3: Verify Permissions and Collectstatic

  • Cookiecutter-Django runs the Django container with a non-root user (usually django), but the shared volume will be writable by this user since it's mounted directly.
  • Ensure your Django container runs collectstatic on startup—Cookiecutter-Django's default production entrypoint should already handle this, but double-check your compose/production/django/entrypoint script to confirm it includes python manage.py collectstatic --noinput.

Why Your Previous Attempts Didn't Work

  • volumes_from: - django: This shares all volumes from the Django container, but the Nginx user (nginx) might not have read permissions on the files owned by the Django container's user (django), leading to 403 errors.
  • Copying the project to Nginx: This is redundant because collectstatic generates files after the Django container starts, so the copied files would be outdated or missing entirely.

内容的提问来源于stack exchange,提问作者Arti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:15:20