Docker/Symfony/Reactjs/Keycloak:如何使用分离的 docker-compose 文件从一个容器向另一个容器发出 HTTP 请求?
Posted
技术标签:
【中文标题】Docker/Symfony/Reactjs/Keycloak:如何使用分离的 docker-compose 文件从一个容器向另一个容器发出 HTTP 请求?【英文标题】:Docker/Symfony/Reactjs/Keycloak : How to make an HTTP request from a container to another with separated docker-compose files? 【发布时间】:2021-09-21 04:22:23 【问题描述】:我有 3 个服务:我在 Symfony 中的后端(Backoffice 和 Api)、我在 Reactjs 中的前端应用程序以及用于 SSO 身份验证的 Keycloak 服务。
我想为我的后台和前端应用使用 Keycloak 身份验证。
我有 3 个单独的 docker-compose 文件:
我的后端 docker-compose 文件:
version: "3.3"
services:
web:
container_name: web_app
build:
context: ./.docker/web
ports:
- 8000:80
volumes:
- .:/var/www/backend
working_dir: /var/www/backend
depends_on:
- mysql
mysql:
container_name: mysql_app
image: mysql:5.7
command: mysqld --sql_mode=NO_ENGINE_SUBSTITUTION --character-set-server=utf8 --collation-server=utf8_general_ci --skip-character-set-client-handshake
restart: on-failure
ports:
- 3307:3306
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
phpmyadmin:
container_name: phpmyadmin_app
image: phpmyadmin/phpmyadmin
ports:
- 8001:80
environment:
PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: root
depends_on:
- mysql
volumes:
mysql_data:
driver: local
networks:
default:
external:
name: app-network
我的前端 docker-compose 文件:
version: "3.3"
services:
nodejs:
container_name: nodejs_app
image: "node:10"
ports:
- 3001:3000
user: "node"
environment:
- NODE_ENV=development
volumes:
- .:/usr/src/frontend
working_dir: /usr/src/frontend
command: >
sh -c "npm install && npm start"
networks:
default:
external:
name: app-network
我的 Keycloak docker-compose 文件:
version: "3.3"
services:
keycloak_mysql:
image: mysql:5.7
volumes:
- keycloak_data:/var/lib/mysql
ports:
- 3308:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: keycloak
keycloak:
image: quay.io/keycloak/keycloak:latest
environment:
DB_VENDOR: MYSQL
DB_ADDR: keycloak_mysql
DB_DATABASE: keycloak
DB_USER: root
DB_PASSWORD: root
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
ports:
- 8080:8080
depends_on:
- keycloak_mysql
volumes:
keycloak_data:
driver: local
networks:
default:
external:
name: app-network
我的后端 .env 文件:
OAUTH_KEYCLOAK_SERVER_URL=http://localhost:8080/auth
OAUTH_KEYCLOAK_CLIENT_ID=app
OAUTH_KEYCLOAK_CLIENT_SECRET=
OAUTH_KEYCLOAK_REALMS=app
然后使用以下命令创建一个网络:docker network create app-network
首先,当我尝试在后台进行身份验证时,我被重定向到 Keycloak 登录页面。 然后,在输入我的凭据后,我被重定向回我的后台,并出现以下错误:
cURL error 7: Failed to connect to localhost port 8080: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://localhost:8080/auth/realms/app/protocol/openid-connect/token
我对 docker 和网络不是很熟悉。
我该如何解决这个问题?
更新 1:
现在我已经在我的网络中添加了一个子网:docker network create --subnet 172.23.0.0/24 app-network
并向我的容器添加静态 IP:
services:
# Backend docker-compose file
web:
networks:
default:
ipv4_address: 172.23.0.11
...
...
mysql:
networks:
default:
ipv4_address: 172.23.0.15
...
...
phpmyadmin:
networks:
default:
ipv4_address: 172.23.0.14
# Frontend docker-compose file
nodejs:
networks:
default:
ipv4_address: 172.23.0.12
# Keycloak docker-compose file
keycloak_mysql:
networks:
default:
ipv4_address: 172.23.0.16
...
...
keycloak:
networks:
default:
ipv4_address: 172.23.0.13
下面的命令:docker network inspect app-network
给了我:
[
"Name": "app-network",
"Id": "31984c890cfbf8206dacf18dd3e831c45cb133ab5391b45edf609cd2232eaffa",
"Created": "2021-07-14T12:19:07.6486215Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM":
"Driver": "default",
"Options": ,
"Config": [
"Subnet": "172.23.0.0/24"
]
,
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom":
"Network": ""
,
"ConfigOnly": false,
"Containers":
"14ab20cf0c5517d9ec9b9d136d65bc07e847d154364ab831a7825c913943a768":
"Name": "phpmyadmin",
"EndpointID": "81d31a65c37e121dbb4948e933e8edf37213612e9b3f6eb4ac66e4a0443a0117",
"MacAddress": "02:42:ac:17:00:0e",
"IPv4Address": "172.23.0.14/24",
"IPv6Address": ""
,
"1cec44b30b8f942803d1bc3525ba5875d73f7253fbac021c67bf76ebf4488f7c":
"Name": "web",
"EndpointID": "9a58e55dd679585af744af01b69d21eb94995a54ead0d24a5fe64e306c599452",
"MacAddress": "02:42:ac:17:00:0b",
"IPv4Address": "172.23.0.11/24",
"IPv6Address": ""
,
"21f54bb4a453e701f1628b4c5e122d3a1e32411608603d193bd5787e2ff1ac38":
"Name": "nodejs",
"EndpointID": "3272a80565ea0ff627c947635c04f5ad8fa47d1822db62e3e0d5f9052270d062",
"MacAddress": "02:42:ac:17:00:0c",
"IPv4Address": "172.23.0.12/24",
"IPv6Address": ""
,
"7d0a8dec8ff6baac31e208c5ccea6fca6954d088a87b884ddd96c95d1c6a2930":
"Name": "keycloak_mysql_1",
"EndpointID": "2517e766e4af674185c4d8612c5e169e6e12ab4658497dfe95cd08ba3d3f6153",
"MacAddress": "02:42:ac:17:00:10",
"IPv4Address": "172.23.0.16/24",
"IPv6Address": ""
,
"822abcc2e5b7e2231f08534050618bc4842405a0f7a287274b9240c291ce87e3":
"Name": "mysql",
"EndpointID": "5b3f47483495e48d0026c84dffe86d4cecd529b9f87ca0d40902280cca01be86",
"MacAddress": "02:42:ac:17:00:0f",
"IPv4Address": "172.23.0.15/24",
"IPv6Address": ""
,
"998210a92b66d1342c9df35b30e341f7631c62604f6b7d0d0d3ac128d2c78420":
"Name": "keycloak_1",
"EndpointID": "3e7e346a159593e4863abd7bc20d2b7f398a6fd2763981b2584ecc02d325c92e",
"MacAddress": "02:42:ac:17:00:0d",
"IPv4Address": "172.23.0.13/24",
"IPv6Address": ""
,
"Options": ,
"Labels":
]
我可以通过以下方式访问我的web
容器中的keycloak
容器:
curl http://keycloak:8080
或 curl http://172.23.0.13:8080
所以我已将我的后端 .env 文件更新为:OAUTH_KEYCLOAK_SERVER_URL=http://keycloak:8080/auth
但是当重定向发生时,我的浏览器无法识别http://keycloak:8080
url。
在我的浏览器上,我只能访问:
My backend: http://localhost:8000
My frontend: http://localhost:3001
My keycloak: http://localhost:8080
是否也可以通过 Ips 从主机访问我的容器?
解决方案:
我编辑了我的/etc/hosts
并添加了:
127.0.0.1 keycloak
127.0.0.1 web
127.0.0.1 nodejs
现在一切正常
【问题讨论】:
你试过没有在每个 docker-compose.yml 文件的全局网络语句中使用 'default' 关键字吗? 我有同样的错误。 【参考方案1】:默认情况下,docker-compose
创建的容器都有自己的网络命名空间 - 即他们自己的(虚拟)网络接口和他们自己的 IP 地址 - 因此尝试从应用容器连接到 http://localhost:8080/
将无法连接到Keycloak 容器,但应用程序容器本身。
要连接到 Keycloak 容器,您需要使用映射 / 被转发到 Keycloak 容器的主机名/IP。由于所有容器都连接到app-network
,因此您可以使用容器名称:
OAUTH_KEYCLOAK_SERVER_URL=http://keycloak:8080/auth
请参阅docker-compose
networking docs 了解更多信息。 (简短的说明:您无需在主机上公开 mysql
容器的端口,以便应用容器能够连接)
如果使用相同的基本 url 来重定向您的浏览器,请确保使用可以从运行浏览器的主机解析的主机/IP,例如然后将相应端口转发到正确容器的主机本身的主机名。
【讨论】:
感谢您的回答。我已经更新了我的帖子。【参考方案2】:从您的后端的角度来看(或从这个上下文中的所有其他容器)localhost
是容器本身。因此,如果您想在主机上使用端口转发,则必须使用网桥 IP 地址。
应该类似于172.17.0.1
。
因此您的配置将显示为:OAUTH_KEYCLOAK_SERVER_URL=http://172.17.0.1:8080/auth
【讨论】:
感谢您的回答。我已经更新了我的帖子。以上是关于Docker/Symfony/Reactjs/Keycloak:如何使用分离的 docker-compose 文件从一个容器向另一个容器发出 HTTP 请求?的主要内容,如果未能解决你的问题,请参考以下文章