无法连接到 MacOS 上的 Dockerized React Web 应用程序中的前端

Can't connect to frontend in Dockerized React web app on MacOS

我最近受雇于一个网站开发项目,但在 MacOS 上通过 docker 部署它时遇到问题。我就是无法通过 localhost:8000 连接到前端。 我已经在虚拟机(Ubuntu)中通过运行docker暂时解决了这个问题,但是由于这个连接有些东西不能正常工作。

有什么方法可以解决这个问题?

这是 docker 文件中的配置:

Dockerfile(前端)

# pull official base image
FROM node:12-alpine as build


# create and set working directory
WORKDIR /app
# install app dependencies
RUN mkdir frontend
COPY package.json ./frontend/
COPY package-lock.json ./frontend/
COPY frontend_healthchecker.sh ./frontend/
RUN chmod +x /app/frontend/frontend_healthchecker.sh

RUN ls
RUN cd frontend && ls
RUN cd frontend && npm install --only=prod
# RUN cd frontend && npm install --scripts-prepend-node-path=auto

# add app code
COPY . ./frontend/
RUN cd frontend && ls

# start app
RUN cd frontend && npm install && npm run build

FROM nginx:1.16.0-alpine
COPY --from=build /app/frontend/build /usr/share/nginx/html
COPY --from=build /app/frontend/nginx/default.conf /etc/nginx/conf.d/default.conf

COPY --from=build /app/frontend/frontend_healthchecker.sh /home
RUN chmod +x /home/frontend_healthchecker.sh
RUN apk add curl
RUN apk search curl
HEALTHCHECK CMD ["/bin/sh", "/home/frontend_healthchecker.sh"]

EXPOSE  8000

CMD ["nginx", "-g", "daemon off;"]

Dockerfile(后端)

FROM node:12
ENV TZ=Europe/Moscow
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

#install ffmpeg
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y ffmpeg
RUN apt-get install -y mediainfo

RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y python-pip
RUN pip --version
RUN pip install numpy
RUN pip install opencv-contrib-python
RUN pip install urllib3

WORKDIR /app

COPY . /app
COPY backend_healthchecker.sh /app
RUN chmod +x backend_healthchecker.sh

RUN ls
RUN npm install

EXPOSE 8080

WORKDIR /app/bin

HEALTHCHECK CMD ../backend_healthchecker.sh
ENTRYPOINT ["node"]

CMD ["www"]

docker-compose.yaml

version: '3.3'
services:
    kurento:
        network_mode: "host"
        build:
            context: ./kurento
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - static-content:/tmp
        container_name: p_kurento
        environment:
            - GST_DEBUG=2,Kurento*:5
    mongo:
        network_mode: "host"
        image: mongo:latest
        restart: always
        container_name: p_mongo
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - db-content:/data/db
        healthcheck:
            test: mongo localhost:27017/test | mongo show dbs
            interval: 1m
            timeout: 15m
            retries: 5
    backend:
        network_mode: "host"
        env_file:
            - ./backend/.env
        build:
            context: ./backend
        container_name: p_backend
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - static-content:/files
    frontend:
        network_mode: "host"
        env_file:
            - ./frontend/.env
        build:
            context: ./frontend
        container_name: p_frontend
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
    coturn:
        network_mode: "host"
        build:
            context: ./stun
        container_name: p_turn

    portainer:
        #network_mode: "host"
        restart: always
        image: portainer/portainer
        command: --admin-password=somepassword -H unix:///var/run/docker.sock
        ports:
            - "9000:9000"
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
        container_name: portainer

volumes:
  static-content:
  db-content:

network_mode: host 不适用于 MacOS 或 Windows 系统。 Docker Use host networking 文档注释:

The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.

它还基本上完全禁用了 Docker 的网络堆栈,而且几乎从不需要。

你需要在这里做三件事:

  1. 从 Compose 文件中删除所有 network_mode: host 行。 (container_name: 行也是不必要的。)
  2. 对于您需要从外部访问的任何服务 Docker(可以是所有服务,没关系)添加 ports: 以发布其容器端口。
  3. 当这些服务中的任何一个在内部调用其他服务时配置它们的 URL(例如,在 .env 文件中)以使用它们的 Compose 服务名称。 (请参阅 Docker 文档中的 Networking in Compose。)(另请注意,您的前端应用程序实际上可能在浏览器中运行,即使代码是从容器提供的,并且不能在all;这个具体点还是需要用localhost或者系统最终部署的主机名。)

因此,例如,前端和后端容器的设置可能如下所示:

version: '3.8'
services:
  mongo: { ... }
  backend:
    # no network_mode: host or container_name:
    # if this needs to be accessed from the browser application
    ports:
      - '8080:8080'
    # probably actually put this in .env
    environment:
      - MONGO_HOST=mongo
    # unchanged from the original
    env_file:
      - ./backend/.env
    build:
      context: ./backend
    volumes: 
      - "/etc/timezone:/etc/timezone:ro"
      - "/etc/localtime:/etc/localtime:ro"
      - static-content:/files
  frontend:
    ports:
      - '8000:8000'
    environment:
      - BACKEND_URL=http://localhost:8080 # as would be seen from the browser
    env_file:
      - ./frontend/.env
    build:
      context: ./frontend
    volumes: 
      - "/etc/timezone:/etc/timezone:ro"
      - "/etc/localtime:/etc/localtime:ro"

您可以尝试创建一个环回地址并使用它来代替默认的本地主机。

步骤:

  1. 在您的当前目录中创建一个名为 loopback-alias.plist 的文件并使用以下内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist>
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>loopback-alias</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ifconfig</string>
      <string>lo0</string>
      <string>alias</string>
      <string>10.200.10.1</string>
      <string>netmask</string>
      <string>255.255.255.0</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>

您可以更改环回地址。

  1. 将文件复制到/Library/LaunchDaemons/
  2. 重启网络
  3. 在 Docker-compose
  4. 中使用的示例代码

redis:
    image: redis
    expose: 
        - '6379'
    ports: 
        - '10.200.10.1:6379:6379'
    extra_hosts: 
        - 'localhost:10.200.10.1'

您可以查看以下link了解更多详情。 https://blog.sbaranidharan.online/index.php/2021/05/05/docker-macos-expose-container-ports-to-host-machine/