Nginx

使用 docker+nginx+django/angularjs 提供靜態文件時出現 404

  • September 1, 2015

我正在遵循儲存庫中給出的配置。我決定將我的 docker 配置和實際程式碼保存在單獨的儲存庫中 - 我將使用 Dockerfile 複製程式碼儲存庫。我正在使用 docker-machine(在本地,使用 Virtualbox 驅動程序)和 docker-compose 設置。

程式碼倉庫的目錄結構大致如下——:

|-- bower.json
|-- CONTRIBUTORS
|-- defsec
|   |-- defsec
|   |   |-- aws_settings.py
|   |   |-- heroku_settings.py
|   |   |-- __init__.py
|   |   |-- settings.py
|   |   |-- urls.py
|   |   |-- views.py
|   |   `-- wsgi.py
|   |-- manage.py
|   |-- quiz_restful
|   |   |-- __init__.py
|   |   |-- permissions.py
|   |   |-- serializers.py
|   |   |-- services.py
|   |   |-- tests.py
|   |   `-- views.py
|   `-- users
|       |-- __init__.py
|       |-- models.py
|       |-- permissions.py
|       |-- serializers.py
|       `-- views.py
|-- extras
|-- gulpfile.js
|-- package.json
|-- Procfile
|-- README.md
|-- requirements.txt
|-- scripts
|   `-- postInstall.sh
|-- static
|   |-- javascripts
|   |   |-- app.js
|   |   |-- controllers
|   |   |   `-- controllers.js
|   |   |-- directives
|   |   |   `-- directives.js
|   |   `-- services
|   |       `-- services.js
|   |-- partials
|   |   |-- eval.html
|   |   |-- exam.html
|   |   |-- exam-partials
|   |   |   |-- exam-view.html
|   |   |   `-- sidebar.html
|   |   |-- login.html
|   |   `-- register.html
|   `-- stylesheets
|       `-- styles.css
|-- templates
|   |-- index.html
|   |-- javascripts.html
|   |-- navbar.html
|   `-- stylesheets.html

docker-compose.yml文件與我上面列出的儲存庫的文件幾乎相同,只是我安裝django在卷上的細微差別.:/root- 沒有它[8] System error: no file or directory會引發錯誤。這可能是因為/usr/src/app在複製之前不存在(供參考,是原始文件)。Dockerfile(用於django服務)具有以下內容 - :

FROM ubuntu:14.04

ENV DJANGO_CONFIGURATION Docker

# First, we need to get git, and clone our repository
# Additionally, get everything else here too, such as nodejs and npm

RUN apt-get update
RUN apt-get install -y ca-certificates git-core ssh nodejs npm python-pip libpq-dev python-dev
RUN ln -s /usr/bin/nodejs /usr/bin/node

ENV HOME /root

# Add custom ssh keypair - usually Bitbucket deployment keys
ADD ssh/ /root/.ssh/

# Fix permissions
RUN chmod 600 /root/.ssh/*

# Avoid first connection host confirmation
RUN ssh-keyscan bitbucket.org > /root/.ssh/known_hosts

# Clone the repo
WORKDIR /usr/src/app
RUN git clone git@bitbucket.org:username/defsec-exam-app.git

# Install requirements
WORKDIR /usr/src/app/defsec-exam-app
RUN pip install -r requirements.txt
RUN npm install -g bower
RUN bower --allow-root install

# Remember to perform migrations on your own, and also create DB when needed.
# S3 Storage
...

# DB Settings
...

WORKDIR /usr/src/app/defsec-exam-app/defsec
CMD ["gunicorn", "defsec.wsgi", "-w", "2", "-b", "0.0.0.0:8000", "--log-level", "-"]

最後,nginx.conf提供靜態文件的方法如下:

worker_processes 1;

events {

   worker_connections 1024;

}

http {

   server {
       listen 80;
       server_name example.org;

       access_log /dev/stdout;
       error_log /dev/stdout info;

       location /static/ {
           alias /usr/src/app/defsec-exam-app/static;
       }

       location /static/javascripts/ {
         default_type text/javascript;
         alias /usr/src/app/defsec-exam-app/static/javascripts/;
       }

       location /static/stylesheets/ {
         default_type text/css;
         alias /usr/src/app/defsec-exam-app/static/stylesheets/;
       }

   location /static/bower_components/ {
     alias /usr/src/app/defsec-exam-app/static/bower_components/;
   }

       location / {
           proxy_pass http://django:8000;
           proxy_set_header   Host $host;
           proxy_set_header   X-Real-IP $remote_addr;
           proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header   X-Forwarded-Host $server_name;
       }
   }
}

但是,我根本無法讓 nginx 為靜態文件提供服務——所有這些文件都返回 404。我想知道容器服務nginxdjango容器服務之間的連結(定義見docker-compose.yml)是否不正確,但似乎不是這樣。我還檢查了容器中的/etc/hosts文件nginx,因為連結會創建主機文件條目。

172.17.0.136    151ca02e891a
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.134    defsecdocker_django_1 eb900ed9600c
172.17.0.135    defsecdocker_nginx_1 eec99206076a
172.17.0.134    django eb900ed9600c defsecdocker_django_1
172.17.0.134    django_1 eb900ed9600c defsecdocker_django_1
172.17.0.135    nginx eec99206076a defsecdocker_nginx_1
172.17.0.135    nginx_1 eec99206076a defsecdocker_nginx_1
172.17.0.116    defsecdocker_postgres_1
172.17.0.134    defsecdocker_django_1
172.17.0.135    defsecdocker_nginx_1.bridge
172.17.0.136    defsecdocker_nginx_run_10.bridge
172.17.0.135    defsecdocker_nginx_1
172.17.0.136    defsecdocker_nginx_run_10
172.17.0.116    defsecdocker_postgres_1.bridge
172.17.0.134    defsecdocker_django_1.bridge

我不確定這是否正確,因為只有 3 個容器,但 hosts 文件中有很多條目,其中一些是重複的。這是可重現的行為 - 每次使用 docker-compose 建構和執行容器時,我都會得到這個確切的文件。nginx用於確認 404的 docker-compose 日誌。

任何指針將不勝感激。

看來 docker-compose 配置不正確。nginx 拋出這些 404 的原因是因為它無法訪問/usr/src/app/defsec-exam-app/static.

這是正確的 docker-compose 配置-:

# Nginx
nginx:
   build: ./nginx
   volumes_from:
       - django
   links:
       - django
   ports:
       - "80:80"

# This defines a service for the Django app
# Will include the Angular frontend
django:
   build: .
   volumes:
       - .:/root
       - /usr/src/app
   expose:
       - "8000"
   links:
       - postgres

# This defines a service for the Postgres database
postgres:
   image: postgres:latest

volumes_from從 django 服務獲取卷。我已經暴露usr/src/app為一卷。這似乎可以解決問題。我願意接受建議,如果有的話!

此外,這是新的 nginx 配置 -:

worker_processes 1;

events {

   worker_connections 1024;

}

http {

   server {
       listen 80;
       server_name example.org;

       access_log /dev/stdout;
       error_log /dev/stdout info;

       location /static/ {
           alias /usr/src/app/defsec-exam-app/static;
       }

       location /static/javascripts/ {
         default_type text/javascript;
         alias /usr/src/app/defsec-exam-app/static/javascripts/;
       }

       location /static/stylesheets/ {
         default_type text/css;
         alias /usr/src/app/defsec-exam-app/static/stylesheets/;
       }

   location /static/bower_components/ {
     types {
       text/css css;
       text/javascript js;
     }
     alias /usr/src/app/defsec-exam-app/static/bower_components/;
   }

   location /static/partials/ {
     types {
       text/html html;
     }
     alias /usr/src/app/defsec-exam-app/static/partials/;
   }

   location /static/admin/ {
         alias /usr/src/app/defsec-exam-app/static/admin/;
   }

   location /static/admin/css {
     default_type text/css;
     alias /usr/src/app/defsec-exam-app/static/admin/css;
   }

   location /static/admin/js {
     default_type text/javascript;
     alias /usr/src/app/defsec-exam-app/static/admin/js;
   }

   location /static/admin/img {
     types {
       image/png png;
       image/jpeg jpg;
     }
     alias /usr/src/app/defsec-exam-app/static/admin/img;
   }

       location / {
           proxy_pass http://django:8000;
           proxy_set_header   Host $host;
           proxy_set_header   X-Real-IP $remote_addr;
           proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header   X-Forwarded-Host $server_name;
       }
   }
}

注意:我必須將 django admin css/js/img 單獨添加到 docker/deployment 儲存庫中,以便 django admin 正常工作。(django Dockerfile 中的一個簡單的 ADD 命令就可以了)

引用自:https://serverfault.com/questions/717845