我有一个docker组合,包含一个react应用程序和其他django容器。它们在同一个网络中所以当我尝试从react容器中使用服务名向django服务发出curl请求时它可以工作但在web应用中它不起作用,它显示:
POST http://backend-account:8000/api/auth/login/ net::ERR_NAME_NOT_RESOLVED
这是我的docker组合:
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
你的web应用(react)最终在用户的浏览器中运行,而不是在容器中。此时,它们不在同一个docker网络中,使用服务名将无法像在容器内使用curl那样工作。
所以你需要在你的服务器上公开你的服务,这样用户在家里的机器上使用他们的浏览器可以发出网络请求。
然后你需要使用你在前端代码中设置的服务器IP地址或域名来访问Django后端。
既然你已经发布了你的后端端口,8080:8000
和7000:7000
,如果你的防火墙允许,你可以在你的服务器IP上访问该服务。
例如,在你的前端代码中使用其中一个。
http://<your-server-ip>:8080
# or
http://<your-server-ip>:7000
也就是说,我建议购买一个域名,并设置一个指向你的服务器的DNS记录。然后,您还可以提供适当的SSL证书,对流量进行加密。
顺便说一句,如果你只想用docker在服务之间进行内部通信,那么你不需要像以前那样发布端口。这可能会也可能不会导致安全问题。例如,您的数据库没有发布端口,后端仍然可以连接。但正如我所说,这更像是一个随机的侧面事实,而不是实际答案的一部分。要解决你的问题,你需要做我上面所描述的。