network issue in one docker compose with keycloak and tomcat container - docker-compose

Greeting,
I'm a beginner is learning web authentication, and would like to try with tomcat and keycloak in docker compose. I put them in one docker-compose.yml as follows:
version: '2'
services:
postgres:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_DATABASE: 'keycloak'
POSTGRES_USER: 'keycloak'
POSTGRES_PASSWORD: 'keycloak'
POSTGRES_ROOT_PASSWORD: 'test'
volumes:
- ./postgres:/mnt/shares/postgres
keycloak:
image: jboss/keycloak-postgres
ports:
- "800:8080"
links:
- postgres
environment:
POSTGRES_PORT_5432_TCP_ADDR: 'postgres'
POSTGRES_DATABASE: 'keycloak'
POSTGRES_USER: 'keycloak'
POSTGRES_PASSWORD: 'keycloak'
KEYCLOAK_USER: 'admin'
KEYCLOAK_PASSWORD: 'admin'
POSTGRES_ROOT_PASSWORD: 'test'
depends_on:
- postgres
volumes:
- ./keycloak:/mnt/shares/keycloak
tomcat_keycloak:
build: .
ports:
- "880:8080"
volumes:
- ./web:/mnt/shares/web
- ./scratches:/mnt/shares/scratches
This can launch fine. Next I created the realm, client, and user in the keycloak, obtained a keycloak.json for tomcat as follows:
{
"realm": "TestRealm",
"auth-server-url": "http://192.168.208.130:800/auth",
"ssl-required": "external",
"resource": "test-client",
"public-client": true,
"use-resource-role-mappings": true
}
where 192.168.208.130 is my host ip address. Then I tried a static web link in my tomcat server. I could be redirected to the keycloak login page. But after entering user name and password, I got HTTP status 403. In the keycloak events I saw the logon was successful, and a session was established. I checked the tomcat output, and then found the following:
07-Apr-2017 17:37:04.240 INFO [http-apr-8080-exec-4] org.apache.http.impl.client.DefaultHttpClient.tryConnect I/O exception (java.net.NoRouteToHostException) caught when connecting to {}->http://192.168.208.130:800: No route to host (Host unreachable)
Looks like from my tomcat container, I cannot do HTTP client connection to my keycloak server container via the URL in host ip address. I can ping the host ip from the tomcat container though.
Could you help me to find out what I'm missing in this configuration? Really appreciate.

Related

Keycloak Postgres docker connection failure

I am trying to get up the keycloak instance via using keycloak, and the compose file I used is below which I get it from
https://github.com/keycloak/keycloak-containers/blob/main/docker-compose-examples/keycloak-postgres.yml
# keycloak dependencies
postgres-keycloak:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: quay.io/keycloak/keycloak:legacy
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
# Uncomment the line below if you want to specify JDBC parameters. The parameter below is just an example, and it shouldn't be used in production without knowledge. It is highly recommended that you read the PostgreSQL JDBC driver documentation in order to use it.
#JDBC_PARAMS: "ssl=true"
ports:
- 8082:8082
depends_on:
- postgres-keycloak
volumes:
postgres_data:
driver: local
When I run the file I am getting connection errors as below :
backend_services-keycloak-1 | Caused by: javax.resource.ResourceException: IJ031084: Unable to create connection
backend_services-keycloak-1 | Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "keycloak"
backend_services-keycloak-1 | 08:53:53,533 FATAL [org.keycloak.services] (ServerService Thread Pool -- 68) Error during startup: java.lang.RuntimeException: Failed to connect to database
backend_services-keycloak-1 | Caused by: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:jboss/datasources/KeycloakDS
backend_services-keycloak-1 | 08:53:54,449 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([("subsystem" => "metrics")]): java.lang.NullPointerException
backend_services-keycloak-1 | 08:53:54,460 ERROR [org.jboss.as.server] (ServerService Thread Pool -- 45) WFLYSRV0022: Deploy of deployment "keycloak-server.war" was rolled back with no failure message
You can try this if you want, Application named test,
Database login are, keycloak:password
keycloak admin login is : root:root
this will be accessible with a web browser at localhost:8080
version: "3.8"
name: test
services:
keycloak:
image: jboss/keycloak:15.0.2
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: root
KEYCLOAK_PASSWORD: root
KEYCLOAK_HOSTNAME: keycloak
# Uncomment the line below if you want to specify JDBC parameters. The parameter below is just an example, and it shouldn't be used in production without knowledge. It is highly recommended that you read the PostgreSQL JDBC driver documentation in order to use it.
#JDBC_PARAMS: "ssl=true"
ports:
- 8080:8080
depends_on:
- postgres
networks:
- test
postgres:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
networks:
- test
volumes:
postgres_data:
driver: local
networks:
test:
driver: bridge
This docker-compose.yml will be works.
You did a wrong two places (DB_ADDR and port forwarding)
version: '3'
services:
postgres-keycloak:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: quay.io/keycloak/keycloak:legacy
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres-keycloak
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
# Uncomment the line below if you want to specify JDBC parameters. The parameter below is just an example, and it shouldn't be used in production without knowledge. It is highly recommended that you read the PostgreSQL JDBC driver documentation in order to use it.
#JDBC_PARAMS: "ssl=true"
ports:
- 8082:8080
depends_on:
- postgres-keycloak
volumes:
postgres_data:
driver: local
And open URL
http://localhost:8082/auth/
Click here then credential admin/admin (id / password)

How do I connect to host.docker.internal postgres instance?

I'm trying to connect to my local server. I have the following docker-compose.yaml and servers.json files. I think I'm making a mistake with my .pgpass. When the containers are up and running I can login to pgAdmin, and I can see the docker_postgres_group "group", but when I try to login I get the authentication error in the first screenshot below. Further below is how I've got my pgpass set up. I think this is where the problem is, but I could be wrong...
docker-compose.yaml
version: '3.8'
services:
db:
container_name: pg_container
image: postgres
restart: always
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
POSTGRES_DB: test_db
ports:
- "5432:5432"
pgadmin:
container_name: pgadmin4_container
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: root
ports:
- "5050:80"
volumes:
- ./servers.json:/pgadmin4/servers.json # preconfigured servers/connections
- ./pgpass:/pgpass # passwords for the connections in this file
servers.json
{
"Servers": {
"1": {
"Name": "docker_postgres",
"Group": "docker_postgres_group",
"Host": "host.docker.internal",
"Port": 15432,
"MaintenanceDB": "postgres",
"Username": "postgres",
"PassFile": "/pgpass",
"SSLMode": "prefer"
}
}
}
.pgpass
This is what's inside my pgpass file: host.docker.internal:15432:postgres:postgres:postgres
Here's its location:
I've tried having the .pgpass file in the pgpass folder and outside.
And - I'm using postgres as the password to try to login to pgadmin.
When spinning up containers through docker-compose, also a network is created where each service can see the other services of the docker-compose definition. They are also resolvable by there servicename. In your case you can replace host.docker.internal with db and use the internal port 5432.
EDIT: host.docker.internal resolves the internal IP address used by your host machine. If you want connect through the host IP, the you have either to change the port in servers.json from 15432 to 5432 or the port mapping from the db service:
ports:
- "15432:5432"

Authentication failed when logging in to Postgres database created via docker-compose

I have set up the following docker-compose.yml file to set up and run PostgreSQL and PgAdmin.
version: '3.1'
services:
db:
image: postgres:latest
container_name: postgres-dopp
restart: unless-stopped
environment:
POSTGRES_USER: dopp_dev
POSTGRES_PASSWORD: dopp_dev_pass
PGDATA: /data/postgres
ports:
- "5432:5432"
volumes:
- dbdata-dopp:/data/postgres
networks:
- network-dopp
pgadmin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: pgadmin4#pgadmin.org
PGADMIN_DEFAULT_PASSWORD: admin
PGADMIN_CONFIG_SERVER_MODE: 'False'
depends_on:
- db
volumes:
- dbdata-dopp:/data/pgadmin
ports:
- "5050:80"
networks:
- network-dopp
networks:
network-dopp:
driver: bridge
volumes:
dbdata-dopp:
name: dopp-db-data
driver: local
This works fine, insofar as I can navigate to PgAdmin in my host machine's browser and through that I can connect to the database using the credentials I've defined in the environment variables. However, when attempting to make a direct connection to the postgres database from my host machine (by connecting to localhost:5432, since I have configured to expose that port), I then get the following error response:
[28P01] FATAL: password authentication failed for user "dopp_dev"
I'm fairly new to the peculiarities of Postgres and docker configuration, so I'm not sure what is causing Postgres to say that password authentication fails when connecting from my host machine, while it works perfectly fine if I do it through PgAdmin, which is on the same internal docker network.
Actually, I discovered that the docker postgres service's port 5432 was being shadowed by a local postgres instance running my host machine.

What is the keycloak docker compose Yaml file format for external postgres db connection URL

I need to setup the Keycloak docker server with the External postgres Database connection URL.
Here's my current yaml file content which is working with POstgres docker container image as mentioned
version: '3'
volumes:
postgres_data:
driver: local
services:
postgres:
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
ports:
- 5433:5432
keycloak:
image:jboss/keycloak:latest
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
KEYCLOAK_LOGLEVEL: DEBUG
ROOT_LOGLEVEL: DEBUG
ports:
- 8080:8080
- 8443:8443
depends_on:
- postgres
I checked the official documentation for passing external DB connection URL.
But exactly didn't get what changes will be needed in YAML file
ref: https://hub.docker.com/r/jboss/keycloak/
I tried removing the Postgres and depends_on section from services and passed the Database connection details in Kecyloak environment section in yaml but it did not worked for me
Can anyone suggest the correct YAML file changes to use PostgresDB connection URL
Thank You.
Docker containers can see each other by their service name, so here service name postgres is actually the connection url for keycloak container.
version: '3'
volumes:
postgres_data:
driver: local
services:
postgres: # Service name
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
ports:
- 5433:5432
keycloak:
image: jboss/keycloak:latest
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres # <<< This is the address, change it to your external db ip/domain
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
KEYCLOAK_LOGLEVEL: DEBUG
ROOT_LOGLEVEL: DEBUG
ports:
- 8080:8080
- 8443:8443
depends_on:
- postgres

Keycloak in docker-compose network

I want to setup a Docker network that contains a keycloak, postgres, and webapp instances.
Is there a way to have network communications between containers but also understand oidc client redirects as well? I am having an issue where containers can talk to each other just fine if i setup OIDC with container names for the docker network, but then I run into issues with the client that cannot connect to the those same URLs outside of the docker network on the host machine.
Can anyone point me to the right docker documentation to look at for possible solutions with DNS or host to container communication?
---- EDIT ----
To clarify. The containers can talk to each other just fine under their container names, but the client (i.e., Chrome) has to use localhost to talk to everything. In my setup for my OIDC connection in the ui web application I have to use container names or localhost. How do I get my client to understand container names in order to make the right request?
version: '2'
services:
ui:
container_name: 'ui'
image: 'bdparrish/ui:0.1'
build:
context: .
dockerfile: ./ui/Dockerfile
ports:
- "8085:80"
depends_on:
- "postgres"
- "keycloak"
networks:
- auth-network
environment:
- ASPNETCORE_ENVIRONMENT=Docker
postgres:
container_name: postgres
image: 'postgres'
environment:
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
networks:
- auth-network
keycloak:
container_name: keycloak
image: jboss/keycloak
ports:
- "8080:8080"
depends_on:
- postgres
environment:
DB_VENDOR: "POSTGRES"
DB_ADDR: postgres
DB_PORT: 5432
DB_USER: keycloak
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
restart: always
networks:
- auth-network
networks:
auth-network:
driver: bridge
You don't have to modify the etc/hosts file.
There is an environment variable for keycloak named KEYCLOAK_FRONTEND_URL especial for this purpose.
Edit your docker compose file to look like this:
version: '2'
services:
ui:
container_name: 'ui'
image: 'bdparrish/ui:0.1'
build:
context: .
dockerfile: ./ui/Dockerfile
ports:
- "8085:80"
depends_on:
- "postgres"
- "keycloak"
networks:
- auth-network
environment:
- ASPNETCORE_ENVIRONMENT=Docker
postgres:
container_name: postgres
image: 'postgres'
environment:
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
networks:
- auth-network
keycloak:
container_name: keycloak
image: jboss/keycloak
ports:
- "8080:8080"
depends_on:
- postgres
environment:
DB_VENDOR: "POSTGRES"
DB_ADDR: postgres
DB_PORT: 5432
DB_USER: keycloak
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth
restart: always
networks:
- auth-network
networks:
auth-network:
driver: bridge
Then the login should be redirected to that url.
All you need to do is add an entry to your hosts file:
Windows: C:\Windows\System32\drivers\etc\hosts
Linux: /etc/hosts
Append this to the end of the file:
127.0.0.1 keycloak
Then use keycloak:8080 from your UI to talk to your keycloak server instead of localhost:8080. You can still use localhost:8580 to visit the UI in the browser.