I have 3 services : My backend (Backoffice and Api) in Symfony, My frontend app in Reactjs and a Keycloak service for SSO authentication.
I want to use Keycloak authentication for my backoffice and my frontend app.
I have 3 separated docker-compose files:
My Backend docker-compose file:
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
My Frontend docker-compose file:
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
My Keycloak docker-compose file:
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
My backend .env file :
OAUTH_KEYCLOAK_SERVER_URL=http://localhost:8080/auth
OAUTH_KEYCLOAK_CLIENT_ID=app
OAUTH_KEYCLOAK_CLIENT_SECRET=
OAUTH_KEYCLOAK_REALMS=app
And a network created with the following command : docker network create app-network
First, when I try to authenticate on my Backoffice, i’m redirected good to Keycloak login page.
Then, after typing my credentials, I’m redirected back to my backoffice with the following error:
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
I’m not very familiar with docker and networking.
How Can I solve this problem ?
UPDATE 1:
Now I’ve added a subnet to my network: docker network create --subnet 172.23.0.0/24 app-network
And added static IPs to my containers:
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
And the following command: docker network inspect app-network
gives me:
[
{
"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": {}
}
]
I can access to my keycloak
container in my web
container with doing:
curl http://keycloak:8080
or curl http://172.23.0.13:8080
So I’ve updated my backend .env file to: OAUTH_KEYCLOAK_SERVER_URL=http://keycloak:8080/auth
But my browser does not recognize http://keycloak:8080
url when the redirection occurs.
On my browser, I’m only able to access to:
My backend: http://localhost:8000
My frontend: http://localhost:3001
My keycloak: http://localhost:8080
Is it also possible to access to my containers from the host by Ips ?
SOLUTION:
I edited my /etc/hosts
and I added:
127.0.0.1 keycloak
127.0.0.1 web
127.0.0.1 nodejs
Now it’s working fine
2
Answers
From your backend point of view (or from every other container in this context)
localhost
is the container itself. so if you want to use the portforwarding on your host machine you have to use the bridge ip adress.Should be something like
172.17.0.1
.so your config would read something like:
OAUTH_KEYCLOAK_SERVER_URL=http://172.17.0.1:8080/auth
By default containers created by
docker-compose
all have their own network namespace – i.e. their own (virtual) network interface and their own IP address – and so trying to connect tohttp://localhost:8080/
from the app container will not connect to the Keycloak container but to the app container itself.To connect to the Keycloak container you need to use a hostname / IP that maps / is forwarded to the Keycloak container. Since all you containers are connected to the
app-network
you can just use the container name for this:See the
docker-compose
networking docs for more. (And short side note: you don’t need to expose the ports of yourmysql
containers on the host for the app container to be able to connect)If the same base url is used for redirecting your browser though be sure to use a host/IP that can be resolved from your host where the browser is running on, e.g. the hostname of the host itself where the respective ports are then forwarded to the right container.