Skip to content
Advertisement

Java.net.ConnectException: Connection refused on Docker + Keycloak

I’m new to Docker and I’m having a hard time connecting Keycloak to my local MySQL database. Does anyone have a hint of what’s going on? This is my Dockerfile:

FROM jboss/keycloak:14.0.0

ADD JDBC_PING.cli /opt/jboss/tools/cli/jgroups/discovery/
USER root

ENV DB_VENDOR MYSQL
ENV DB_ADDR host.internal.docker
ENV DB_PORT 3306
ENV DB_DATABASE keycloak
ENV DB_USER root
ENV DB_PASSWORD mydbpass
ENV PROXY_ADDRESS_FORWARDING true
ENV KEYCLOAK_USER admin
ENV KEYCLOAK_PASSWORD mykcpass
ENV PROXY_ADDRESS_FORWARDING true
ENV JGROUPS_DISCOVERY_PROTOCOL JDBC_PING
ENV JGROUPS_DISCOVERY_PROPERTIES datasource_jndi_name=java:jboss/datasources/KeycloakDS
ENV CACHE_OWNERS_COUNT 2
ENV CACHE_OWNERS_AUTH_SESSIONS_COUNT 2
ENV JAVA_OPTS -server -Xms8048m -Xmx8048m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS,com.newrelic -Djava.awt.headless=true


COPY . /project
RUN cd /project && ./mvnw clean package

FROM jboss/keycloak:14.0.0
USER root
COPY --from=0 /project/target/*.jar /opt/jboss/keycloak/standalone/deployments/app.jar
USER 1000

ENV KEYCLOAK_HTTP_PORT 80
ENV KEYCLOAK_HTTPS_PORT 443
EXPOSE 8080
EXPOSE 8443

The error log shows:

FATAL [org.keycloak.services] (ServerService Thread Pool -- 59) Error during startup: java.lang.RuntimeException: Failed to connect to database

...............
Caused by: java.net.ConnectException: Connection refused (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
        at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
        at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.base/java.net.Socket.connect(Socket.java:609)
        at com.mysql.jdbc@8.0.22//com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
        at com.mysql.jdbc@8.0.22//com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63)
        ... 64 more

Steps already taken:

  • Disabled Firewall;
  • Added bind-address: 0.0.0.0 to my my.cnf file;
  • root@% already has all privileges;
  • Tries setting DB_ADDR and DB_VENDOR in all possible configurations;
  • Server is already started and connection through Workbench runs fine.

Any help would be hugely appreciated!!

Advertisement

Answer

In a multi-stage build, each FROM line completely resets things like ENV settings, so the settings from the first stage aren’t appearing in the final image.

FROM jboss/keycloak:14.0.0 AS build
ENV DB_VENDOR MYSQL
...
FROM jboss/keycloak:14.0.0  # resets ENV settings
RUN echo $DB_VENDOR         # will be empty

In general, run-time or deploy-time settings like the database location and credentials shouldn’t be compiled into your Dockerfile. (You don’t want to rebuild the image when you deploy it somewhere different, and the credentials can be pretty easily extracted from the built image.) If you’re running this through Docker Compose, you could put these environment-specific settings in your docker-compose.yml file, or use an external environment file:

version: '3.8'
services:
  keycloak:
    build: .
    # env_file: keycloak.env  # would replace the settings below
    environment:
      DB_ADDR: host.internal.docker
      DB_USER: root
      DB_PASSWORD: password
      ET: cetera
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement