我有一个 docker compose,其中包含一个 React 应用程序和其他 django 容器。它们位于同一网络中,因此当我尝试使用服务名称从 React 容器向其中一个 django 服务发出curl 请求时,它可以工作,但在 Web 应用程序中它不起作用,它说:
POST http://backend-account:8000/api/auth/login/net::ERR_NAME_NOT_RESOLVED
这是我的 docker compose:
version: "3.9"
services:
db-account:
restart: always
container_name: ctr-db-account-service
image: mysql:8
environment:
- MYSQL_DATABASE=dtp_db
- MYSQL_USER=admin
- MYSQL_PASSWORD=ictf
- MYSQL_HOST=db
- MYSQL_PORT=3306
- MYSQL_ROOT_HOST=%
- MYSQL_ROOT_PASSWORD=root
volumes:
- account-data:/var/lib/mysql
networks:
- dtp-network
db-stream:
restart: always
container_name: ctr-db-stream-service
image: mysql:8
environment:
- MYSQL_DATABASE=dtp_db
- MYSQL_USER=admin
- MYSQL_PASSWORD=ictf
- MYSQL_HOST=db
- MYSQL_PORT=3306
- MYSQL_ROOT_HOST=%
- MYSQL_ROOT_PASSWORD=root
volumes:
- stream-data:/var/lib/mysql
networks:
- dtp-network
backend-account:
restart: always
container_name: ctr-account-service
command:
# bash -c "python check_db.py --service-name db --ip db --port 3306 &&
bash -c "sleep 20 &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
env_file:
- ./dtp-account-management-app/account_management/.env
build:
context: ./dtp-account-management-app/account_management/
dockerfile: Dockerfile
expose:
- 8000
ports:
- "8080:8000"
depends_on:
- db-account
links:
- db-account
networks:
- dtp-network
backend-stream:
restart: always
container_name: ctr-stream-service
command:
# bash -c "python check_db.py --service-name db --ip db --port 3306 &&
bash -c "sleep 20 &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:7000"
env_file:
- ./dtp-stream-management-app/stream_management/.env
build:
context: ./dtp-stream-management-app/stream_management/
dockerfile: Dockerfile
expose:
- 7000
ports:
- "7000:7000"
depends_on:
- db-stream
links:
- db-stream
networks:
- dtp-network
frontend:
restart: always
command: npm start
container_name: ctr-frontend-service
build:
context: ./dtp-frontend-app/
dockerfile: Dockerfile
ports:
- "3000:3000"
stdin_open: true
depends_on:
- backend-account
- backend-stream
links:
- backend-stream
- backend-account
networks:
- dtp-network
networks:
dtp-network:
driver: bridge
volumes:
account-data:
driver: local
stream-data:
driver: local
此外,当错误发生时,我在终端中什么也没有得到,更像是没有通信,但尝试在 react 容器中运行curl请求,我得到了这个响应:
/react # curl -i -X GET --url http://backend-account:8000/api/auth/login/
HTTP/1.1 200 OK
Date: Mon, 13 Sep 2021 11:25:06 GMT
Server: WSGIServer/0.2 CPython/3.9.6
Content-Type: application/json
Vary: Accept, Origin
Allow: POST, OPTIONS
X-Frame-Options: DENY
Content-Length: 40
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
最佳答案
您的网络应用程序(react)最终在用户的浏览器中运行,而不是在容器中运行。此时,它们不在同一个 docker 网络中,并且使用服务名称将无法像在容器内使用curl 时那样工作。
因此,您需要在服务器上公开您的服务,以便用户在家里使用自己的浏览器可以发出网络请求。
然后您需要在前端代码中使用您设置的服务器IP地址或域名来访问Django后端。
由于您已经发布了后端端口 8080:8000
和 7000:7000
,因此如果防火墙允许,您可以在服务器 IP 上访问该服务。
例如,在前端代码中使用其中之一。
http://<your-server-ip>:8080
# or
http://<your-server-ip>:7000
也就是说,我建议购买一个域名并设置指向您的服务器的 DNS 记录。然后您还可以提供适当的 SSL 证书,对流量进行加密。
顺便说一句,如果您只想在服务之间与 docker 进行内部通信,那么您不需要像以前那样发布端口。这可能会也可能不会导致安全问题。例如,您的数据库没有发布端口,后端仍然可以连接。但正如我所说,这更多的是一个随机的侧面事实,而不是实际答案的一部分。要解决您的问题,您需要执行我上面描述的操作。
关于reactjs - 使用服务名称在 docker-compose React 容器中调用 API 到 django 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69161875/