【问题标题】:Django and nginx and gunicorn and docker compose - configuring URLsDjango 和 nginx 以及 gunicorn 和 docker compose - 配置 URL
【发布时间】:2019-01-08 11:57:03
【问题描述】:

我正在用 Django 2、Docker Compose 和 Nginx 构建一个练习应用程序。启动图像是成功的,但是,任何非 Django/Python 文件不会加载。

例如,/static/bootstrap-3.2/dist/css/bootstrap.css(或 /static 中的任何文件)不会加载。我在 SO 上看到了一些其他相关的问题,但出于某种原因,我认为我的配置仍然缺少一些东西。有控制台日志和终端行指示静态或其他目录资源的 404 错误。

感谢任何帮助,谢谢!

工作目录树

|- gunicorn/
|- nginx\
|-- nginx.conf
|-- ...
|- django/
|-- __init__.py
|-- templates/
|-- static/
|-- manage.py
|-- settings.py
|-- forms.py
|-- views.py
|-- urls.py
|-- wsgi.py 
|- docker-compose.yml
|- Dockerfile
|- requirements.txt

Dockerfile

FROM python
ENV PYTHONUNBUFFERED 1

ADD . /ljingo
WORKDIR /ljingo

RUN pip install -r requirements.txt
RUN python -m nltk.downloader punkt
RUN python -m nltk.downloader wordnet
RUN python -m nltk.downloader averaged_perceptron_tagger

requirements.txt

Django==2.0
django-crispy-forms
psycopg2
gunicorn
nltk==3.3

nginx/nginx.conf

server {
    root /;

    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    access_log /logs/access.log;

    error_log /logs/error.log;

    location /media  {
        alias /django/media;
    }

    location /static {
        alias /django/static;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://django:8000;
    }
}

docker-compose.yml

version: '2'
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - .:/ljingo
      - ./nginx:/etc/nginx/conf.d
      - ./static:/static
    depends_on:
      - django

  django:
    build: .
    image: ljingo
    command: python3 manage.py collectstatic
    command: python3 manage.py migrate
    # command: python3 manage.py runserver 0.0.0.0:80
    command: gunicorn ljingo.wsgi -c ./gunicorn/gunicorn.py -b 0.0.0.0:8000
    # depends_on:
    #   - db
    volumes:
      - .:/ljingo
    ports:
      - "8000:8000"

终端 STDOUT 输出

mac:django-gunicorn bmalone$ docker-compose up
django-gunicorn_django_1 is up-to-date
Starting django-gunicorn_nginx_1 ... done
Attaching to django-gunicorn_django_1, django-gunicorn_nginx_1
django_1  | [2018-08-01 00:23:22 +0000] [1] [INFO] Starting gunicorn 19.9.0
django_1  | [2018-08-01 00:23:22 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
django_1  | [2018-08-01 00:23:22 +0000] [1] [INFO] Using worker: sync
django_1  | [2018-08-01 00:23:22 +0000] [9] [INFO] Booting worker with pid: 9
django_1  | [2018-08-01 00:23:23 +0000] [10] [INFO] Booting worker with pid: 10
django_1  | [2018-08-01 00:23:23 +0000] [11] [INFO] Booting worker with pid: 11
django_1  | [2018-08-01 00:23:23 +0000] [12] [INFO] Booting worker with pid: 12
django_1  | [2018-08-01 00:23:23 +0000] [13] [INFO] Booting worker with pid: 13
django_1  | Not Found: /static/custom.css
django_1  | Not Found: /static/bootstrap-3.2/dist/css/bootstrap.css
django-gunicorn_nginx_1 exited with code 0

【问题讨论】:

  • 我认为在您的静态断言目录/static/ 中找不到.css 文件。也许尝试将COPY custom.css /static/custom.css 添加到您的 dockerfile 中?

标签: django nginx static docker-compose nltk


【解决方案1】:

您的docker-compose.yml 文件不能有多个command 条目。您需要将对manage.pygunicorn 的调用合并到一个命令中。

command: python3 manage.py collectstatic && python3 manage.py migrate && gunicorn ljingo.wsgi -c ./gunicorn/gunicorn.py -b 0.0.0.0:8000

由于这有点长且难以阅读,我建议创建一个简单的 bash 脚本来运行每个命令,并从 docker-compose.yml 配置中调用:

start_django.sh

#!/usr/bin/env bash

set -ex

python3 manage.py collectstatic
python3 manage.py migrate
gunicorn ljingo.wsgi -c ./gunicorn/gunicorn.py -b 0.0.0.0:8000

docker-compose.yml

django:
  # ...all of the other config goes here, but a single command entry...
  command: ./start_django.sh

确保在创建 start_django.sh 后,在容器内授予它可执行权限。这可以通过您的Dockerfile 来完成:

Dockerfile

ADD . /ljingo
RUN chmod +x /lingo/start_django.sh
WORKDIR /ljingo

【讨论】:

  • 太棒了!再加上我的 nginx.conf 文件中的一次更改——“location /static/”到“location ^/static/”——我可以成功地在 nginx 上部署静态文件以及我的 Django 应用程序。谢谢@damon!
  • 另一个注意事项 - chmod 命令在我的 Python 环境中没有为我运行,但 Docker 中的 COPY 命令显然与本地权限匹配,因此在本地更改 +x 权限后,脚本执行正常。
  • @RoboBear – Re: Permissions » 最好不要依赖本地环境的权限。你确定你的 Dockerfile 在COPY . /ljingo 之后有RUN chmod ... 行吗?很高兴我能帮忙:)