elements icon indicating copy to clipboard operation
elements copied to clipboard

bug: self host nextjs docker

Open productdevbook opened this issue 9 months ago • 8 comments

Preflight checklist

Ory Network Project

https://github.com/ory/elements/tree/main/examples/nextjs-app-router

Describe the bug

Is it possible to add settings that work with docker, it would be great if you could add this with a dockerfile and compose.

 ⨯ Error [FetchError]: Unable to call the API endpoint. Ensure that CORS is set up correctly and that you have provided a valid SDK URL to Ory Elements.
    at <unknown> (.next/server/chunks/374.js:1:570008)
    at Generator.next (<anonymous>)
    at <unknown> (.next/server/chunks/374.js:1:568927)
    at new Promise (<anonymous>)
    at W (.next/server/chunks/374.js:1:568676)
    at <unknown> (.next/server/chunks/374.js:1:568950)
    at ea (.next/server/chunks/374.js:1:727268)
    at async a (.next/server/app/auth/login/page.js:1:3102) {
  digest: '4138030352',
  [cause]: Error [FetchError]: The request failed and the interceptors did not return an alternative response
      at I.<anonymous> (.next/server/chunks/374.js:1:525625)
      at Generator.throw (<anonymous>)
      at s (.next/server/chunks/374.js:1:523630) {
    [cause]: [TypeError: fetch failed] {
      [cause]: [AggregateError: ] { code: 'ECONNREFUSED' }
    }
  }
}

Reproducing the bug

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3010:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
      - HOSTNAME=0.0.0.0
      - ORY_SDK_URL=http://kratos:4433
      - NEXT_PUBLIC_ORY_SDK_URL=http://localhost:4433
      - ORY_KRATOS_PUBLIC_URL=http://kratos:4433
      - ORY_KRATOS_ADMIN_URL=http://kratos:4434
    restart: unless-stopped
    networks:
      - intranet
    depends_on:
      kratos:
        condition: service_healthy

  kratos-migrate:
    image: oryd/kratos:v1.3.1
    environment:
      - DSN=postgres://postgres:[email protected]:5432/kratos?sslmode=disable
    volumes:
      - type: bind
        source: ./kratos
        target: /etc/config/kratos
    command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
    restart: on-failure
    networks:
      - intranet

  kratos:
    depends_on:
      - kratos-migrate
    image: oryd/kratos:v1.3.1
    ports:
      - '4433:4433' # public
      - '4434:4434' # admin
    restart: unless-stopped
    environment:
      - DSN=postgres://postgres:[email protected]:5432/kratos?sslmode=disable
      - LOG_LEVEL=trace
    command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
    volumes:
      - type: bind
        source: ./kratos
        target: /etc/config/kratos
    networks:
      - intranet
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4433/health/ready"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s
  mailcrab:
    image: marlonb/mailcrab:latest
    ports:
      - '1025:1025'
      - '1080:1080'
    networks:
      - intranet
  kratos-admin-proxy:
    image: nginx:alpine
    ports:
      - "8444:80"
    volumes:
      - ./kratos/nginx-admin.conf:/etc/nginx/conf.d/default.conf:ro
    environment:
      - ORY_ADMIN_API_TOKEN=super-secret-admin-token
    depends_on:
      - kratos
    networks:
      - intranet
networks:
  intranet:

DockerFile

# Base image
FROM node:22-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json pnpm-lock.yaml* ./
RUN \
  if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm install --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1

RUN \
  if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm build; \
  else echo "Lockfile not found." && exit 1; \
  fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy public directory for static assets
COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]

Relevant log output


Relevant configuration


Version

1.3.1

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

Docker Compose

Additional Context

No response

productdevbook avatar Jul 04 '25 09:07 productdevbook

@productdevbook

Read the error "Ensure that CORS is set up correctly and that you have provided a valid SDK URL to Ory Elements".

In your kratos.yml you would whitelist your app in allowed_origins. Ory Kratos has documentation, as well as https://github.com/ory/kratos/tree/master/contrib/quickstart/kratos for help.

kratos.yml:

serve:
  public:
    base_url: http://localhost:4433/
    cors:
      enabled: true
      allowed_origins:
        - http://localhost:3000
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
      exposed_headers:
        - Content-Type
        - Set-Cookie

NorkzYT avatar Jul 13 '25 18:07 NorkzYT

Thank you. So what is this error, after logging in, registration buttons exit buttons etc. 0.0.0.0.0 url comes.

{
    "logout_url": "http://0.0.0.0:3000/self-service/logout?token=ory_lo_vht8mui4N9oxsdl1bGjrff8TPIkhmTWwGFJ",
    "logout_token": "ory_lo_vht8muisdsd4N9ol1bGjrff8TPIkhmTWwGFJ"
}

productdevbook avatar Jul 13 '25 18:07 productdevbook

Send your full kratos.yml file.

NorkzYT avatar Jul 13 '25 18:07 NorkzYT

kubernetes configmap yml.

Check Yml

cookies:
  domain: domain.com
  same_site: Lax
courier:
  smtp:
    from_address: [email protected]
    from_name: domain.com
identity:
  default_schema_id: default
  schemas:
  - id: default
    url: file:///etc/config/identity.default.schema.json
log:
  format: json
  level: info
selfservice:
  allowed_return_urls:
  - https://auth.domain.com/
  - https://auth.domain.com/auth/callback
  - https://*.domain.com/
  default_browser_return_url: https://auth.domain.com/auth/callback
  flows:
    error:
      ui_url: https://auth.domain.com/error
    login:
      lifespan: 10m
      ui_url: https://auth.domain.com/auth/login
    logout:
      after:
        default_browser_return_url: https://auth.domain.com/auth/login
    recovery:
      enabled: true
      ui_url: https://auth.domain.com/auth/recovery
    registration:
      after:
        password:
          hooks:
          - hook: session
      lifespan: 10m
      ui_url: https://auth.domain.com/auth/registration
    settings:
      privileged_session_max_age: 15m
      ui_url: https://auth.domain.com/settings
    verification:
      after:
        default_browser_return_url: https://auth.domain.com/auth/callback
      enabled: true
      ui_url: https://auth.domain.com/auth/verification
  methods:
    code:
      enabled: true
    link:
      enabled: true
    lookup_secret:
      enabled: true
    password:
      enabled: true
    totp:
      config:
        issuer: domain.com
      enabled: true
serve:
  admin:
    port: 4434
  public:
    base_url: https://admin.domain.com/
    cors:
      enabled: true
    port: 4433
session:
  cookie:
    domain: domain.com
    same_site: Lax
  lifespan: 24h

productdevbook avatar Jul 13 '25 18:07 productdevbook

Was NEXT_PUBLIC_ORY_SDK_URL set correctly? Also you set HOSTNAME=0.0.0.0. Though your kratos.yml file is pointing to sub domain and not http://localhost at all.

NorkzYT avatar Jul 13 '25 18:07 NorkzYT

What should we need to set HOSTNAME? I couldn't find any info about this in next.js docs.

We are using next.js Dockerfile with build args to set NEXT_PUBLIC_ORY_SDK_URL at build time and we are also setting both NEXT_PUBLIC_ORY_SDK_URL and ORY_SDK_URL variables to https://kratos.domain.com at runtime too.

productdevbook avatar Jul 13 '25 18:07 productdevbook

Since we are using Next.js I would do the following and set args to be able to get the env variables build-time and inject them during runtime to be able to use them in production mode. HOSTNAME I removed to test and you could keep it and try it with localhost as the value instead.

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        NEXT_PUBLIC_ORY_SDK_URL: ${NEXT_PUBLIC_ORY_SDK_URL}
    ports:
      - "3010:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
      - NEXT_PUBLIC_ORY_SDK_URL=https://kratos-public.domain.com         # NEXT_PUBLIC_ORY_SDK_URL=http://localhost:4433
      - NEXT_PUBLIC_ORY_KRATOS_PUBLIC_URL=https://kratos-public.domain.com
      - NEXT_PUBLIC_ORY_KRATOS_ADMIN_URL=https://kratos.domain.com
    restart: unless-stopped
    networks:
      - intranet
    depends_on:
      kratos:
        condition: service_healthy

Dockerfile:

# Near the top of file:
ARG NEXT_PUBLIC_ORY_SDK_URL


ENV NEXT_PUBLIC_ORY_SDK_URL=${NEXT_PUBLIC_ORY_SDK_URL}

NorkzYT avatar Jul 13 '25 18:07 NorkzYT

I couldn't figure it out at all. I wish there was a repository where we could directly test everything that's inside.

productdevbook avatar Aug 24 '25 12:08 productdevbook