【问题标题】:Backend and Frontend in Docker work locally but not remotelyDocker 中的后端和前端在本地工作,但不在远程工作
【发布时间】:2021-11-29 19:02:02
【问题描述】:

问题

我有三个 Docker 容器:一个后端、一个前端和一个处理请求的 nginx 容器。 当我在我的计算机(带有 docker 引擎的 Windows 笔记本电脑)上运行它时,一切正常。 我可以在容器的日志中看到调用:

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 中的虚拟机上时,前端和后端似乎不再通信。前端可以看到,但是如果和之前做同样的操作,后端是查询不到的:

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 前端可以获取这个后端:

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;
    }
  }
}

【问题讨论】:

    标签: reactjs django docker nginx


    【解决方案1】:

    看起来backendURL = 'http://localhost'; 可能是这里的罪魁祸首?例如,您的前端配置为在 http://localhost 查询您的后端,即使它部署在不同的 IP/服务器上。

    是否可以在 React 构建过程中使用环境变量或类似的东西来提供后端的实际 URL?

    【讨论】:

    • 我在 .env.prod 中定义了REACT_APP_BACKEND_URL=192.168.31.103,然后在 App.js 中定义了const backendURL = process.env.REACT_APP_BACKEND_URL || 'http://localhost';。而且我在前端日志中显示错误:Proxy error: Could not proxy request /192.168.31.103/api/versions/ from 192.168.31.103 to http://localhost:5000/*. See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED). 我不确定这个http://localhost:5000/ 来自哪里,它没有在文件中的任何地方定义。
    • 这个看起来和stackoverflow.com/a/50207462/2844093很像,你的node开发环境中可能有某种代理配置。
    • 能否将后端 URL 设置为空字符串?然后你的代码会尝试GET /api/versions;浏览器会将仅路径 URL 解释为与页面位于同一服务器上;并且请求将转到反向代理服务器。
    • 谢谢你们俩。我从package.json 中删除了代理行,这还不够,前端在查询后端时出现 404 错误。我用一个空字符串替换了backendURL,现在它可以工作了。我将package.json 中的代理行指向后端应该也可以工作,因为它是defining a fall back when the address is not resolved
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2021-07-14
    相关资源
    最近更新 更多