Связывание контейнеров Django и nginx при развертывании

Когда я использую docker-compose для создания образов и запуска контейнеров, все работает нормально, и я могу получить доступ к своему приложению в браузере через localhost.

Затем я переименовываю/отмечаю образы и загружаю их на dockerhub.

Я написал второй docker-compose.yml, который извлекает эти два образа из dockerhub, создает сеть и запускает их. Оба образа загружаются правильно, но когда я направляю браузер на localhost, то получаю только окно "Welcome to Ngninx - further configuration required".

Я использовал 'docker network inspect' для сравнения двух сетей, и все кажется одинаковым, за исключением очень незначительных изменений ip-адресов.

CHESS_NN_WEBAPP
│   docker-compose.yml
│   docker-compose_deploy.yml
│   Dockerfile
│   requirements.txt
│
├───config
│   └───nginx
│       └───conf.d
│               local.conf
│
├───django_wrapper
│   │   db.sqlite3
│   │   manage.py
│   │
│   ├───django_wrapper
│   │       asgi.py
│   │       settings.py
│   │       urls.py
│   │       wsgi.py
│   │
│   └───webapp
│       │   admin.py
│       │   apps.py
│       │   chess_tools.py
│       │   urls.py
│       │   views.py
│       │
│       ├───templates
│               index.html
│ 
└───other stuff

Докерфайл для контейнера приложений django/gunicorn:

# start from official image
FROM python:3.10-slim

# arbitrary location choice: you can change the directory
RUN mkdir -p /opt/services/djangoapp/src
WORKDIR /opt/services/djangoapp/src

# install dependencies
COPY requirements.txt /opt/services/djangoapp/src/
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install opencv-python-headless

# copy project code
COPY . /opt/services/djangoapp/src
# start django server
RUN cd django_wrapper && python manage.py 

# expose port 80
EXPOSE 80

# define default command to run when starting the container
CMD ["gunicorn", "--chdir", "django_wrapper", "--bind", ":80", 
        "django_wrapper.wsgi:application", "--timeout", "0"]

docker-compose.yml, который собирает изображения:

version: '3'

services:
  djangoapp:
    build: .
    volumes:
      - .:/opt/services/djangoapp/src
    networks:
      - nginx_network

  nginx:
    image: pagespeed/nginx-pagespeed:latest
    ports:
      - 80:80
    volumes:
      - ./config/nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - djangoapp
    networks:
      - nginx_network

networks:
  nginx_network:
    driver: bridge

Nginx conf.d:

# first we declare our upstream server, which is our Gunicorn application
upstream chess_nn {
    server djangoapp:80;
}

# now we declare our main server
server {

    listen 80;
    server_name localhost;

    location / {
        # everything is passed to Gunicorn
        proxy_pass http://chess_nn;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

}

Пока все работает как надо (т.е. у меня есть доступ через localhost), поэтому два получившихся образа помечаем как 'colurw/chess_nn:webapp' и 'colurw/chess_nn:nginx' и отправляем в Docker Hub.

Мой файл docker-compose.yml для извлечения и запуска этих образов выглядит так:

version: '3'

services:
  djangoapp:
    image: colurw/chess_nn:webapp
    networks:
      - nginx_network

  nginx:
    image: colurw/chess_nn:nginx
    ports:
      - 80:80
    depends_on:
      - djangoapp
    networks:
      - nginx_network

networks:
  nginx_network:
    driver: bridge

Запуск docker-compose с этим файлом приводит к тому, что оба контейнера работают... Я вижу экран nginx в браузере, а в журнале gunicorn написано "Listening at: http://0.0.0.0:80", но я также вижу из журнала, что запрос браузера не проходит так далеко, поскольку нормальный ответ (который включает загрузку chess_tools.py при первом обращении к localhost) не происходит.

Вот результаты "docker network investigate" для сети нерабочих контейнеров:

[
    {
        "Name": "chess_nn_webapp_nginx_network",
        "Id": "40ece5962610e64d605b579ee27bf71b3e665767bc67af3d0767a1e58a27adff",
        "Created": "2024-02-01T15:57:41.422912742Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2b89f8fbe62acc31d08420cb97fb7fc264743b2efb3715856d78e3b13ffe5265": {
                "Name": "chess_nn_webapp-djangoapp-1",
                "EndpointID": "20abea988881a827caa1671e3ffb38cc35983b52961fde9674781c1bdc56a1d1",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "b3669a895bd52023c949505b7174f4e1d0a6570dbfa955af22f0fc5f5789afc3": {
                "Name": "chess_nn_webapp-nginx-1",
                "EndpointID": "2e156010866564e4261befda0d6980b7aea2c12bc0077a6ea5e4bb4c854f80e0",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "nginx_network",
            "com.docker.compose.project": "chess_nn_webapp",
            "com.docker.compose.version": "2.23.3"
        }
    }
]

Спасибо, что дошли так далеко! Пожалуйста, если у вас есть предположения о том, в чем проблема, я буду очень благодарен.

Для контейнера Nginx в вашей локальной среде вы внедряете локальный файл конфигурации Nginx во время выполнения

    volumes:
      - ./config/nginx/conf.d:/etc/nginx/conf.d

но в удаленном развертывании эта конфигурация отсутствует.

Ваше удаленное развертывание уже написано так, чтобы ожидать пользовательский образ для прокси Nginx, поэтому самым простым изменением может быть включение конфигурационного файла в образ. Это может быть очень простой Dockerfile

# Dockerfile.nginx
FROM pagespeed/nginx-pagespeed:latest
COPY config/nginx/conf.d/ /etc/nginx/conf.d/

и вашему файлу Compose нужно сказать, чтобы он создавал образ, а не монтировал том

  nginx:
    image: colurw/chess_nn:nginx
    build:
      context: .
      dockerfile: Dockerfile.nginx
    ports:
      - 80:80
    # volumes:   <-- delete
    #   - ./config/nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - djangoapp
    networks:   # consider deleting as well
      - nginx_network

В локальной среде я бы аналогичным образом рассмотрел возможность удаления volumes: для контейнера djangoapp. Это приведет к замене всего кода образа содержимым хост-системы, что означает, что локально вы фактически не запускаете развертываемый образ. Также безопасно удалить все блоки networks: из всего файла, поскольку Compose создаст сеть с именем default и автоматически присоединит к ней все контейнеры.

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