Назад | Перейти на главную страницу

404 при обслуживании статических файлов с помощью docker + nginx + django / angularjs

Я следую конфигурации, указанной на этот репозиторий. Я решил сохранить свою конфигурацию докера и фактический код в отдельных репозиториях - я бы клонировал репозиторий кода с помощью Dockerfile. Я использую докер-машину (локально, используя драйвер 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 service) имеет следующее -:

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. Мне было интересно, есть ли связь между nginx и django контейнерные услуги (как определено в 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

Я не уверен, что это правильно, поскольку в файле hosts всего 3 контейнера, но чертовски много записей, некоторые из которых являются дубликатами. Это воспроизводимое поведение - я получаю именно этот файл каждый раз, когда создаю и запускаю контейнер с помощью docker-compose. Журналы docker-compose для nginx подтвердить 404s.

Приветствуются любые указатели.

Похоже, что конфигурация 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 работал правильно. (Простая команда ADD в файле Dockerfile django делает свое дело)