Как мне получить доступ к URL-адресу FastAPI из моего приложения докера?

У меня есть интерфейсное приложение, размещенное на субдомене (www.admin.example.com). У меня также есть серверное приложение, которое использует FastAPI для связи с интерфейсным приложением реагирования. Это серверное приложение развертывается с помощью Docker. Интерфейс создается с помощью команды npm run build и развертывается вручную, т. е. файлы сборки копируются в корневой каталог поддомена.

Однако у меня возникли проблемы с доступом к этому серверному приложению FastAPI, которое размещено с использованием Docker. Я пробовал использовать IP-адрес моего сервера + порт (https://server_ip_address:8000), но не получаю ответ по пути / от моего бэкэнда FastAPI. Этот URL-адрес (https://server_ip_address:8000) фактически не загружает страницу. Я получаю сообщение об ошибке: This site can’t be reached.

Но когда я захожу https://server_ip_address, я загружаю страницу, рассказывающую о nginx. Я проверил журналы докера, и приложение FastAPI не обнаружило ни ошибок, ни ответа. Мне сказали, что у докера тоже есть собственный IP-адрес, но я попробовал это, и это не сработало. Я также не могу получить доступ к URL-адресу, например https://server_ip_address:8000, из моего внешнего приложения, иначе я получаю ошибку политики CORS. Общий вопрос: как мне получить доступ к моему приложению FastAPI, прослушивающему докер?

Docker Создать файл:

services:
  db:
    build: .
    ports:
      - "8000:8000"
    expose:
      - "8000"
    secrets:
      - MONGODB_URI
      - LOGIN_SECRET_KEY

secrets:
  LOGIN_SECRET_KEY:
    file: admin_login_secret_key.txt
  MONGODB_URI:
    file: mongo_db_uri.txt

Докер-файл:

# Use an official Python runtime as a base image
FROM python:3.9

# Set the working directory in the container
WORKDIR /app

# Copy the dependencies file to the working directory
COPY requirements.txt .

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY . .

# Specify the command to run on container start
CMD ["uvicorn", "db:app", "--host", "0.0.0.0", "--port", "8000"]

Файл сервера nginx.conf (только настройки сервера)

server {
        listen 8080;
    server_name admin.example.com;

    location /backend/ {
            proxy_pass http://127.0.0.1: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-Proto $scheme;
        }
}

Я пытался получить доступ таким образом https://admin.example.com:8080/backend, но он не перенаправляется на http://127.0.0.1:8000.

В файле компоновки docker есть только служба db; у него нет веб-сервиса. Где определен веб-сервис?

John Gordon 24.06.2024 03:44

@JohnGordon Если под веб-сервисом вы имеете в виду приложение реагирования, оно не было создано с помощью Docker. Это отдельное приложение

Alexander Obidiegwu 24.06.2024 03:53

curl http://localhost:8000 работает?

Philippe 24.06.2024 11:45

@Филипп, это должно работать в производстве?

Alexander Obidiegwu 25.06.2024 20:50

Думаю, нет, это всего лишь шаг по устранению неполадок, поскольку вы не предоставили подробную информацию о конфигурации вашей сети.

Philippe 25.06.2024 21:25

@Philippe Какие подробности? Я новичок в этом, лол, так что извините, если буду медленным. У меня есть IP-адрес моего поддомена. Я не знаю, о какой еще конфигурации вы говорите

Alexander Obidiegwu 26.06.2024 00:24

Например, виден ли server_ip_address IP-адрес в Интернете или виден только в вашей локальной сети? и что вы подразумеваете под domain IP address и server IP address?

Philippe 26.06.2024 00:30

@Philippe Это IP-адрес, видимый в Интернете. Например, IP-адрес, найденный с помощью этого сайта: nslookup.io/website-to-ip-lookup. domain IP address и server IP address для меня одно и то же. Я думаю, что это одинаково для всех, лол.

Alexander Obidiegwu 26.06.2024 00:33

на вашем хосте, вероятно, также работает nginx (в дополнение к контейнеру), если вы получаете ответ от его экземпляра ... будет ли это работать, если вы удалите экземпляр Compose и просто настроите хост? Я также сомневаюсь, что ваша настройка proxy_pass верна, и вам следует установить ее через переменную env (которая может быть db в файле docker-compose)

ti7 26.06.2024 00:34

@Philippe Я внес некоторые изменения в пост для большей ясности.

Alexander Obidiegwu 26.06.2024 00:34

@ti7 Если я получу доступ к доменному имени и порту, например https://admin.example.com:8000, я получу site can't be reached error. Если я использую IP-адрес сервера вместе с портом, например https://38.281.00:8000, я получаю ту же ошибку. Но если я получу доступ только к IP-адресу, я получу страницу, показывающую, что nginx настроен правильно. Сейчас я настроил его с помощью ChatGPT, но он не работает.

Alexander Obidiegwu 26.06.2024 00:39

это нормально, это будет вводить вас в заблуждение до тех пор, пока вы позволите, а когда это может ввести в заблуждение эксперта в своей области, это будет полно - просмотрев официальную документацию, попробуйте их пример простого запуска приложения FastAPI без nginx fastapi.tiangolo.com/deployment/docker/…

ti7 26.06.2024 00:47

@Philippe Когда я делаю telnet 127.0.0.1 8000 через ssh, он поступает в мой докер-контейнер, однако выполнение 127.0.0.1 не работает через основное приложение реагирования. Я получаю отказ в соединении.

Alexander Obidiegwu 26.06.2024 01:59

@ti7 Когда я делаю telnet 127.0.0.1 8000 или curl -i http://127.0.0.1:8000 через ssh, я получаю действительный ответ от докер-контейнера, однако выполнение http://127.0.0.1:8000 через браузер не работает. Я получаю отказ в соединении.

Alexander Obidiegwu 26.06.2024 03:59

Вы проверяли файл журнала nginx?

Philippe 26.06.2024 20:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
15
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пожалуйста, проверьте следующие возможные причины:

  • Вы неправильно настроили Nginx. Если вы хотите получить доступ к своему приложению FastAPI через IP-адрес и порт 80, вам необходимо настроить обратный прокси-сервер, сопоставляющий порт 80 с портом 8000.
  • Ваша политика безопасности ограничивает порт 8000. Таким образом, вы не можете получить доступ к порту 8000 извне. Вот почему https://ip_address:8000 не работает.

Несколько советов:

  • Настройте обратный прокси-сервер для своего бэкэнда вместо того, чтобы пытаться получить к нему доступ через IP-адрес и порт. Лично я помещу встроенный файл React в корень www и прокси /api на свой внутренний сервер.

Пожалуйста, проверьте обновленный пост. Я именно так и сделал, но все равно не работает. Одна деталь, которую я упустил, заключается в том, что мой домен является субдоменом. Таким образом, другие проекты размещаются в этом домене. Повлияет ли это на доступ к порту 8000?

Alexander Obidiegwu 26.06.2024 00:24

@AlexanderObidiegwu Если ваш nginx настроен в вашем докер-контейнере, то имя_сервера на самом деле избыточно. Это полезно только тогда, когда вам приходится иметь дело с запросами из разных доменов.

OrthoPole 26.06.2024 07:36

@AlexanderObidiegwu Субдомен на самом деле представляет собой DNS-запись в домене. Например, www.subdomain.example.com на самом деле представляет собой DNS-запись с именем www.subdomain в example.com, которая содержит IP-адрес сервера.

OrthoPole 26.06.2024 07:40

@AlexanderObidiegwu Обычно служба HTTP прослушивает порт 80. Но вы, похоже, прослушиваете порт 8000. Возможно, вам придется посетить www.subdomain.example.com:8000. Есть ли у вас доступ к конфигурации nginx на вашем хост-сервере (вместо докер-контейнера)? Если вы это сделаете, вы можете добавить конфигурацию www.subdomain.example.com, которая прослушивает 80 и имеет обратный проксирование на localhost:8000.

OrthoPole 26.06.2024 07:42

Я пробовал это сделать, но ничего не получается. Обратный прокси во всех формах и формах, но он не дает никакого результата. Мое приложение FastAPI не получает запрос. Но это работает, когда я делаю curl -i http:127.0.01:8000 или telnet 127.0.0.1 8000. Также работайте с localhost:8000. Я удалил службу nginx из своего докера. Сейчас он содержит только мое приложение fastAPI.

Alexander Obidiegwu 26.06.2024 18:13

Я обновляю пост, чтобы показать, чем я сейчас занимаюсь.

Alexander Obidiegwu 26.06.2024 18:34

@AlexanderObidiegwu Из предоставленной вами информации я прихожу к следующему выводу: ваше приложение FastAPI работает успешно. Так что, возможно, проблема в вашей конфигурации Nginx. Например, вы пытались зайти через https, но в вашей конфигурации я не увидел никаких настроек https, например местоположения файла сертификата. Так что, возможно, вы можете попробовать зайти через http. Кроме того, вы можете проверить журнал доступа nginx, чтобы узнать, действительно ли nginx получил от вас запрос.

OrthoPole 27.06.2024 12:33

Спасибо! Ты был прав. Это было из-за проблем с настройкой nginx и брандмауэром. Команда, отвечающая за это, помогла мне. Спасибо. Теперь это исправлено

Alexander Obidiegwu 28.06.2024 04:42

Другие вопросы по теме