#reactjs #docker #docker-compose #microservices #devops
Вопрос:
У меня есть докер-композиция, содержащая приложение react и другой контейнер django. Они находятся в одной сети, поэтому, когда я пытаюсь сделать запрос curl из контейнера react на один из сервисов django, используя имя службы, которое он работает, но в веб-приложении он не работает, и он сказал :
POST http://backend-account:8000/api/auth/login/ net::ERR_NAME_NOT_RESOLVED
это моя докерская композиция :
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 amp;amp;
bash -c "sleep 20 amp;amp;
python manage.py migrate amp;amp;
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 amp;amp;
bash -c "sleep 20 amp;amp;
python manage.py migrate amp;amp;
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
Кроме того, когда произошла ошибка, я ничего не получаю в терминале, скорее всего, нет связи, но, пытаясь выполнить запрос curl в контейнере react, я получил этот ответ:
/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
Ответ №1:
Ваше веб-приложение (react) в конечном итоге запускается в браузере пользователя, а не в контейнере. В этот момент они не находятся в одной сети докеров, и использование имени службы не будет работать так, как при использовании curl из контейнера.
Поэтому вам нужно предоставить доступ к вашей службе на вашем сервере, чтобы пользователи с ее собственной машины дома, используя свой браузер, могли сделать сетевой запрос.
Затем вам нужно использовать IP-адрес сервера или доменное имя, которое вы настроили, в своем интерфейсном коде, чтобы перейти на серверную часть Django.
Поскольку вы уже опубликовали порты своих бэкэндов, 8080:8000
и 7000:7000
вы можете использовать эту службу на своем IP-адресе сервера , если позволяет брандмауэр.
Например, используйте один из них в своем интерфейсном коде.
http://<your-server-ip>:8080
# or
http://<your-server-ip>:7000
Тем не менее, я бы посоветовал приобрести домен и установить DNS-запись, указывающую на ваш сервер. Тогда вы также могли бы предоставить надлежащий SSL-сертификат, шифрующий трафик.
Кстати, если вы хотели только внутренней связи между службами с docker, то вам не нужно публиковать порты, как вы это делали. Это может привести или не привести к проблемам безопасности. Например, в вашей базе данных нет опубликованных портов, и серверная часть все еще может подключаться. Но, как я уже сказал, это скорее случайный побочный факт, чем часть реального ответа. Чтобы решить вашу проблему, вам нужно сделать то, что я описал выше.