Docker-compose с NGINX не обслуживает Django на localhost

Я пытаюсь обслужить простое приложение Django через NGINX с помощью Docker Compose. Я не совсем понимаю, откуда берется проблема, но сборка прошла успешно. Есть идеи, почему приложение не работает правильно?

Это установка:

├── app
│   ├── templates
│   ├── webapp
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── entrypoint.sh
│   ├── entrypoint.prod.sh
│   └── requirements.txt
├── nginx
│   ├── Dockerfile
│   └── nginx.conf
├── .env
├── docker-compose.ci.yml
├── docker-compose.prod.yml
└── docker-compose.yml

app/webapp/settings.py:

.env

DEBUG=0
SECRET_KEY=<foo>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=webapp_django_prod
SQL_USER=webapp_django
SQL_PASSWORD=<password>
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres
YOUTUBE_DATA_API_KEY=<foo>

app/Dockerfile

# pull official base image
FROM python:3.9.6-alpine

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install psycopg2
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r /usr/src/app/requirements.txt

# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh

# copy project
COPY . /usr/src/app/

# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]

app/entrypoint.sh

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

python manage.py flush --no-input
python manage.py migrate
python manage.py collectstatic --no-input --clear

exec "$@"

app/Dockerfile.prod

# pull official base image
FROM python:3.9.6-alpine

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install psycopg2
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r /usr/src/app/requirements.txt

# copy entrypoint-prod.sh
COPY ./entrypoint.prod.sh /usr/src/app/entrypoint.prod.sh

# copy project
COPY . /usr/src/app/

# run entrypoint.prod.sh
ENTRYPOINT ["/usr/src/app/entrypoint.prod.sh"]

app/entrypoint.prod.sh

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

exec "$@"

nginx/Dockerfile

FROM nginx:1.21-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

nginx/nginx.conf

upstream webapp {
    server web:8000;
}

server {

    listen 80;

    location / {
        proxy_pass http://webapp;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /staticfiles/ {
        alias /usr/src/app/staticfiles/;
    }

    location /mediafiles/ {
        alias /usr/src/app/mediafiles/;
    }

}

docker-compose.yml

version: '3.8'

services:
  web:
    build: ./app
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ./app/:/usr/src/app/
    ports:
      - 8000:8000
    environment:
      - DEBUG=1
      - SECRET_KEY=<foo>
      - SQL_ENGINE=django.db.backends.postgresql
      - SQL_DATABASE=webapp_django_prod
      - SQL_USER=webapp_django
      - SQL_PASSWORD=<foo>
      - SQL_HOST=db
      - SQL_PORT=5432
      - DATABASE=postgres
    depends_on:
      - db
  db:
    image: postgres:13-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=webapp_django
      - POSTGRES_PASSWORD=<foo>
      - POSTGRES_DB=webapp_django_prod

volumes:
  postgres_data:

docker-compose.ci.yml

version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
      cache_from:
        - "${WEB_IMAGE}"
    image: "${WEB_IMAGE}"
    command: gunicorn webapp.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    expose:
      - 8000
    env_file: .env
  nginx:
    build:
      context: ./nginx
      cache_from:
        - "${NGINX_IMAGE}"
    image: "${NGINX_IMAGE}"
    volumes:
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    ports:
      - 80:80
    depends_on:
      - web

volumes:
  static_volume:
  media_volume:

docker-compose.prod.yml

version: '3.8'

services:
  web:
    image: "${WEB_IMAGE}"
    command: gunicorn webapp.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    ports:
      - 8000:8000
    env_file: .env
  nginx:
    image: "${NGINX_IMAGE}"
    volumes:
      - static_volume:/usr/src/app/staticfiles
      - media_volume:/usr/src/app/mediafiles
    ports:
      - 80:80
    depends_on:
      - web

volumes:
  static_volume:
  media_volume:

Поскольку я не могу комментировать до сих пор. Самый простой способ определить проблему - просмотреть журналы.

Вы можете проверить контейнеры Docker, запустив это на каждом экземпляре:

docker logs --follow your-container-name

Или вы можете добавить это в ваш файл docker-compose, если контейнер docker будет убит, вы можете получить доступ к нему с помощью journalctl:

mycontainer:
    image: myimage
    logging:
        driver: journald
        options:
            tag: mytag

И затем получить доступ к нему, используя:

journalctl -u docker CONTAINER_NAME=mycontainer_name
journalctl -u docker CONTAINER_TAG=mytag

Ответ частично взят из: https://stackoverflow.com/a/43663253/16891224

Вернуться на верх