reactjs - 无法在 MacOS 上的 Dockerized React Web 应用程序中连接到前端
问题描述
我最近受雇于一个网站开发项目,但在 MacOS 上通过 docker 部署它时遇到了麻烦。我只是无法通过 localhost:8000 连接到前端。我已经通过在虚拟机(Ubuntu)中运行 docker 暂时解决了这个问题,但是由于这种连接,有些事情无法正常工作。
有哪些方法可以解决这个问题?
这是 dockerfiles 中的配置:
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使用主机网络文档说明:
主机网络驱动程序仅适用于 Linux 主机,不支持 Docker Desktop for Mac、Docker Desktop for Windows 或 Docker EE for Windows Server。
它还基本上完全禁用了 Docker 的网络堆栈,并且几乎从不需要。
你需要在这里做三件事:
network_mode: host
从 Compose 文件中删除所有行。(这些container_name:
线条也是不必要的。)- 对于您需要从 Docker 外部访问的任何服务(可以是所有服务,这很好),添加
ports:
以发布其容器端口。 - 当这些服务中的任何一个在内部调用其他服务时,配置它们的 URL(例如,在
.env
文件中)以使用它们的 Compose 服务名称。(请参阅Docker 文档中的Compose中的网络。)(另请注意,您的前端应用程序可能实际上在浏览器中运行,即使代码是从容器提供的,并且根本不能使用这些主机名;这一点需要仍然使用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"
推荐阅读
- django - 使用 setter 验证 Django 模型字段
- firebase - 从 asp.net core api 向 firebase auth 添加用户声明
- kendo-ui-angular2 - KendoUi Angular2 Radio 和 CheckBox 样式不适用于 RTL 方向
- ios - UITextView/NSAttribute:检测单词是否以特定符号开头
- android - 如何在 android 中本地化谷歌地图,并使搜索 URL 接受不同语言的参数
- android - 如何使用 viewpager 在 Actionbar 选项卡中获取片段的位置
- android - Android Studio - 如何使用谷歌地图 api 在学校地图上随机添加标记
- python - 生成透明文本图像 OpenCV
- java - 从具有多个默认值的缓存中提取时的代码气味?
- reactjs - 如何在 blaze 中使用反应组件?