Backend и Frontend в Docker работают локально, но не удаленно

Проблема

У меня есть три контейнера Docker: бэкенд, фронтенд и контейнер nginx, который обрабатывает запросы. Когда я запускаю их на своем компьютере (ноутбук windows с docker engine), все работает отлично. В логах контейнеров я вижу, что выполняются следующие вызовы:

reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00 +0000] "GET /static/js/bundle.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00 +0000] "GET /static/js/vendors~main.chunk.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00 +0000] "GET /static/js/main.chunk.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01 +0000] "GET /favicon.ico HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01 +0000] "GET /manifest.json HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01 +0000] "GET /logo192.png HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:02 +0000] "GET /api/versions/ HTTP/1.1" 200 55 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
backend_1        | Sending versions

Когда я устанавливаю его либо на выделенный сервер ubuntu (192.168.31.103) в сети, либо на виртуальную машину в VirtualBox на моем компьютере, кажется, что frontend и backend больше не взаимодействуют. Я могу видеть фронтенд, но если я выполняю ту же операцию, что и раньше, бэкенд не запрашивается:

192.168.31.101 - - [10/Oct/2021:21:29:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39 +0000] "GET /sockjs-node HTTP/1.1" 101 2801 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39 +0000] "GET /static/js/bundle.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39 +0000] "GET /static/js/vendors~main.chunk.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39 +0000] "GET /static/js/main.chunk.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:41 +0000] "GET /favicon.ico HTTP/1.1" 200 2114 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"

Я могу перейти непосредственно к бэкенду в браузере: http://192.168.31.103/api/versions/ и это работает нормально, возвращает json объект и nginx отображает соответствующий лог.

192.168.31.101 - - [10/Oct/2021:21:39:25 +0000] "GET /api/versions/ HTTP/1.1" 200 55 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:39:25 +0000] "GET /favicon.ico HTTP/1.1" 200 2114 "http://192.168.31.103/api/versions/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"

(обратите внимание, что 192.168.31.101 - это IP моего ноутбука в сети).

Можете ли вы заметить ошибку?

Конфигурация

У меня есть Django-REST бэкенд, который обслуживает некоторые представления, все за префиксом /api/, для примера: http:localhost/api/version. Я удалил всю CSRF защиту на данный момент.

settings.py

ALLOWED_HOSTS = [
  localhost,
  127.0.0.1,
  192.168.31.103,
]

У меня есть React frontend, который будет получать этот backend:

App.js

[...]
const backendURL = 'http://localhost';

const getBackendVersion = () => {
    setFetchingVersions(true);
    fetch(`${backendURL}/api/versions/`)
      .then( response => response.json())
      .then( d => {
        setAppVersions({
          'frontend': frontendVersion,
          'backend': d['versions']['maapi'],
        })
      })
      .catch( () => setFetchingVersions(false));
  };
[...]

Я развертываю это с помощью Docker.

docker-compose.yml

version: '3.8'

services:
  backend:
    build: ./ma-backend
    command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
    expose:
      - 8000
    env_file:
      - ./.env.prod

  frontend:
    build: ./ma-frontend
    command: npm start
    expose:
      - 3000
    depends_on:
      - backend
    env_file:
      - ./.env.prod

  reverse_proxy:
    build: ./nginx
    ports:
      - 80:80
    depends_on:
      - backend
      - frontend

nginx.conf:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
  worker_connections 1024;
}

http {
  upstream backend {
    server backend:8000;
  }

  upstream frontend {
    server frontend:3000;
  }

  server {
    listen 80;

    server_name localhost 127.0.0.1;

    location /api {
      proxy_pass              http://backend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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;
    }

    location /admin {
      proxy_pass              http://backend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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;
    }

    location / {
      proxy_pass              http://frontend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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;
    }
  }
}

Похоже, что виновником здесь может быть backendURL = 'http://localhost';? Например, ваш front-end настроен на запрос бэкенда по адресу http://localhost, хотя он развернут на другом IP/сервере.

Возможно ли использовать переменную окружения или что-то подобное в процессе сборки React для предоставления фактического URL вашего бэкенда?

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