bug: self host nextjs docker
Preflight checklist
- [x] I could not find a solution in the existing issues, docs, nor discussions.
- [x] I agree to follow this project's Code of Conduct.
- [x] I have read and am following this repository's Contribution Guidelines.
- [ ] I have joined the Ory Community Slack.
- [ ] I am signed up to the Ory Security Patch Newsletter.
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
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
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"
}
Send your full kratos.yml file.
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
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.
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.
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}
I couldn't figure it out at all. I wish there was a repository where we could directly test everything that's inside.