You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker Compose部署Keycloak、Next.js与Spring Boot时的网络配置及令牌验证问题求助

Docker Compose部署Keycloak、Next.js与Spring Boot时的网络配置及令牌验证问题求助

我太懂你现在的头疼了——搭这三个服务时一会儿后端报issuer不匹配,一会儿前端跳错地址,折腾LLM也没搞定,完全摸不着头绪。咱们先把核心问题拆解清楚,再一步步把配置改对:

核心问题根源

  1. Issuer不匹配:Keycloak给前端发的JWT里,issuer是http://localhost:8081/realms/polarix,但你后端用http://keycloak:8081/realms/polarix验证,两者不一致导致令牌验证失败。
  2. 内外网地址冲突:前端在浏览器里跑,必须用localhost:8081访问Keycloak;但后端在Docker网络内,应该用服务名keycloak:8081访问Keycloak。你之前的Keycloak配置把KC_HOSTNAME设为localhost,导致它生成的所有地址都是localhost,后端验证时就会issuer不匹配。
  3. 前端构建与运行地址混乱:你用host网络构建前端,但运行时用桥接网络,可能导致前端请求地址硬编码错误。

修改后的完整Docker Compose配置

networks:
  polarix-network:
    driver: bridge

services:
  dependency-builder:
    image: oven/bun:1-alpine
    working_dir: /app
    volumes:
      - .:/app
    command: bun install
    networks:
      - polarix-network

  postgres:
    image: postgres:13
    container_name: postgres
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres-init:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"
    networks:
      - polarix-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U keycloak"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  keycloak:
    image: quay.io/keycloak/keycloak:26.4.2
    container_name: keycloak
    command:
      - start-dev
      - --import-realm
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: password
      KC_HTTP_ENABLED: "true"
      KC_HTTP_PORT: 8081
      # Docker内网用服务名,对外暴露用localhost
      KC_HOSTNAME: keycloak
      KC_HOSTNAME_URL: http://localhost:8081
      KC_HOSTNAME_STRICT: "true"
      # 后端内部请求用服务名
      KC_HOSTNAME_STRICT_BACKCHANNEL: "true"
      KC_HOSTNAME_BACKCHANNEL: http://keycloak:8081
    volumes:
      - ./data/import:/opt/keycloak/data/import
    ports:
      - "8081:8081"
    networks:
      - polarix-network
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/localhost/8081'"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 60s

  backend:
    build: ./backend
    container_name: backend
    environment:
      DB_URL: jdbc:postgresql://postgres:5432/polarix_db
      DB_USER: keycloak
      DB_PASSWORD: password
      # Issuer必须和JWT里的iss完全一致
      KEYCLOAK_ISSUER_URI: http://localhost:8081/realms/polarix
      # 后端内网访问Keycloak拿JWKS用服务名
      KEYCLOAK_JWKS_URI: http://keycloak:8081/realms/polarix/protocol/openid-connect/certs
      KEYCLOAK_SERVER_URL: http://keycloak:8081
    ports:
      - "8080:8080"
    networks:
      - polarix-network
    depends_on:
      postgres:
        condition: service_healthy
      keycloak:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/v3/api-docs"]
      interval: 15s
      timeout: 5s
      retries: 5

  frontend:
    build:
      context: .
      dockerfile: frontend/Dockerfile
      args:
        API_URL: http://localhost:8080
    container_name: frontend
    environment:
      # Next.js静态构建时用环境变量传递地址
      - NEXT_PUBLIC_API_URL=http://localhost:8080
      - NEXT_PUBLIC_KEYCLOAK_URL=http://localhost:8081
    ports:
      - "5173:5173"
    networks:
      - polarix-network
    depends_on:
      backend:
        condition: service_healthy

volumes:
  postgres_data:

关键修改点解释

1. Keycloak配置(核心修复)

  • KC_HOSTNAME: keycloak:Docker内网的服务名,让后端能直接通过这个地址访问Keycloak,无需绕到主机。
  • KC_HOSTNAME_URL: http://localhost:8081:告诉Keycloak对外(浏览器、前端)暴露的地址,确保生成的授权链接、JWT的issuer都是前端能访问的localhost。
  • KC_HOSTNAME_STRICT_BACKCHANNEL: "true":强制后端的内部请求(比如验证令牌、获取JWKS)用keycloak:8081,避免地址混乱。

2. 后端配置修复

  • KEYCLOAK_ISSUER_URI必须和JWT里的iss字段完全一致(也就是http://localhost:8081/realms/polarix),这样令牌验证时issuer匹配。
  • KEYCLOAK_JWKS_URI用Docker内网服务名,让后端高效访问Keycloak的证书接口。

3. 前端配置修复

  • NEXT_PUBLIC_*前缀的环境变量传递地址,Next.js会自动注入到前端代码中,避免构建时硬编码错误。
  • 去掉了构建时的network: host,没必要且容易引发网络问题,直接用默认构建网络即可。

额外注意事项

  1. 删掉旧容器和卷:启动前先执行docker-compose down -v,清除旧的缓存配置。
  2. Keycloak客户端配置:在Keycloak后台把前端地址http://localhost:5173加到Valid Redirect URIsWeb Origins里,避免CORS或回调错误。
  3. Spring Boot后端补充配置:确保你的application.yml里的JWT验证配置和docker-compose一致:
    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: ${KEYCLOAK_ISSUER_URI}
              jwk-set-uri: ${KEYCLOAK_JWKS_URI}
    
  4. 去掉/etc/hosts的多余配置:你之前加的127.0.0.1 完全没必要,反而可能触发浏览器的安全限制导致crypto函数错误。

验证步骤

  1. 启动所有服务:docker-compose up --build
  2. 访问Keycloak后台:http://localhost:8081/admin,确认能正常登录。
  3. 访问前端:http://localhost:5173,点击登录验证是否跳转到Keycloak页面,登录后能否正常调用后端API。
  4. 查看后端日志:确认没有issuer不匹配的错误,令牌验证通过。

这样应该就能解决你遇到的所有网络和令牌验证问题了,如果还有小问题,比如CORS或前端跳转错误,直接检查Keycloak的客户端配置和前端的环境变量就行~

火山引擎 最新活动