I'm trying to deploy an Angular application with Keycloak authentication using Docker. The setup works fine on my local machine (using localhost), but when I deploy it to an Ubuntu VM, I get the following error in the browser console when accessing http://192.168.1.105:4200:
{error: 'Timeout when waiting for 3rd party check iframe message.'}
Here's my docker-compose.yml:
version: '3.8'services: angular: build: context: ./web/jtekt-client dockerfile: Dockerfile ports: - "4200:80" mysql-db: image: mysql:latest container_name: mysql-db ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: jtekt healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 jtekt-server: build: ./server/jtekt-server container_name: jtekt-server ports: - "8081:8081" environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/jtekt SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root depends_on: mysql-db: condition: service_healthy keycloak: image: quay.io/keycloak/keycloak:25.0.0 container_name: keycloak ports: - "8080:8080" environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin command: start-dev
Here's the KeycloakService in my Angular app:
import { Injectable } from '@angular/core';import Keycloak from 'keycloak-js';import { UserProfile } from '../models/user-profile';@Injectable({ providedIn: 'root',})export class KeycloakService { private _keycloak: Keycloak | undefined; private _profile: UserProfile | undefined; get keycloak() { if (!this._keycloak) { this._keycloak = new Keycloak({ url: 'http://192.168.1.105:8080', realm: 'jtekt', clientId: 'jtekt', }); } return this._keycloak; } get profile(): UserProfile | undefined { return this._profile; } constructor() {} async init() { console.log('Authentication the user...'); const authenticated = await this.keycloak?.init({ onLoad: 'login-required', }); if (authenticated) { this._profile = (await this.keycloak?.loadUserProfile()) as UserProfile; } } login() { return this.keycloak?.login(); } logout() { return this.keycloak?.logout(); } hasRole(role: string) { return this.keycloak?.hasRealmRole(role); }}
Here's my Dockerfile for the Angular app:
FROM node:alpine AS buildRUN npm install -g @angular/cliWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run build -- --configuration productionFROM nginx:alpineCOPY --from=build /app/dist/jtekt-client/browser /usr/share/nginx/htmlCOPY nginx.conf /etc/nginx/conf.d/default.confEXPOSE 80CMD ["nginx", "-g", "daemon off;"]
Here's my Nginx configuration (nginx.conf):
server { listen 80; listen [::]:80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # Security headers add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; add_header X-XSS-Protection "1; mode=block";}
What I've Tried:Ensured the VM is accessible from the host machine.Confirmed that Keycloak is running and accessible at http://192.168.1.105:8080.Updated the Keycloak configuration in my Angular service to use the VM's IP address.Checked that the docker-compose.yml is correctly configured to expose the necessary ports.Question:Why am I getting a timeout error with the message "Timeout when waiting for 3rd party check iframe message" when trying to access my Angular app on the VM? How can I resolve this issue so that the Keycloak login page is correctly displayed when accessing the Angular app at http://192.168.1.105:4200?
Any help or suggestions would be greatly appreciated!