Hi all, I'm having some trouble getting Ory Kratos...
# ory-selfhosting
b
Hi all, I'm having some trouble getting Ory Kratos + NextJS to function well with two distinct URLs with Ory Elements. NEXT_PUBLIC_ORY_SDK_URL points to my public URL for Ory, and ORY_SDK_URL points to the service URL for Ory Kratos within my k8s cluster. It seems that the ORY_SDK_URL value is being ignored, and the NEXT_PUBLIC value is being used both client side and server side I think the issue is that this orySdkUrl function in the nextjs package only checks for the NEXT_PUBLIC env var, unlike the similarly-named orySdkUrl in the elements-react package, which checks for ORY_SDK_URL . Is there way to get this same "use server side variable, if available, otherwise use the NEXT_PUBLIC variable" behavior in the nextjs package? Thanks in advance for any assistance!
Side note: is this a bug in the react package? It's checking if the env var ORY_SDK_URL is set, and, if so, sets the base URL to value of a different env var _ORY_SDK_URL (note the leading underscore)
OK, think I worked this out! I wasn't able to get it working with 2 distinct URLs. Tested patches to the getSdkUrl function linked above to have it use the
ORY_SDK_URL
in the NextJs context. This worked to get the initial login page to render, but caused issues with any links that were included in the SSR'd login page as the URLs for these links would point to the in-cluster URL for kratos. The fix was to instead use nextjs rewrites, like this:
Copy code
env: {
    NEXT_PUBLIC_ORY_SDK_URL: '/api/kratos',
    ORY_SDK_URL: '<http://localhost:3000/api/kratos>', // use absolute URL server-side, which will be stable across deployments
  },
  async rewrites() {
    return [
      {
        source: '/api/kratos/:path*',
        destination: '<http://kratos-public.default.svc.cluster.local:4433/:path*>',
      },
    ];
  },
b
Are you using the next.js middleware?
b
I was not, but I just tried it out, and it helped! Thank you! I was able to remove this rewrite logic entirely with the middleware in place. The only piece of my previous workaround that seemed to still be necessary was to patch the SDK url in the ory config that is passed to the middleware:
Copy code
export function getOryElementsConfig()  {
  const kratosUrl = process.env.ORY_SDK_URL || process.env.NEXT_PUBLIC_ORY_SDK_URL || '';
  const oryElementsConfig = enhanceOryConfig(baseConfig, kratosUrl);
  return {
    ...oryElementsConfig,
    sdk: {
      ...oryElementsConfig.sdk,
      options: {
        credentials: "include" as RequestCredentials
      }
    }
  }
}
Is it expected for this to be required?
n
I'm facing the same problem and I can't solve it. can you post a docker example for nextjs ? @bland-eye-99092
b
hey @narrow-park-87615 I did get this up and running! Not sure if this is the "ory certified" approach, but it's live and functional for my team. If any ory folks happen to read this and can weigh in on whether there's a cleaner approach to achieving this, that would be much appreciated 🙂 here's the recipe that worked for us: .env file:
Copy code
NEXT_PUBLIC_API_URL=<http://localhost:8080>
NEXT_PUBLIC_ORY_SDK_URL=<http://localhost:3000/.ory/kratos>
ORY_SDK_URL=<http://app-kratos-public.app.svc.cluster.local:4433> # we use k8s, but this would point to whatever URL your node service can resolve
Config helper fn:
Copy code
export function getOryElementsConfig()  {
  const kratosUrl = process.env.NEXT_PUBLIC_ORY_SDK_URL || '';
  const oryElementsConfig = enhanceOryConfig(baseConfig, kratosUrl);
  return {
    ...oryElementsConfig,
    sdk: {
      ...oryElementsConfig.sdk,
      options: {
        credentials: "include" as RequestCredentials
      }
    }
  }
}
ory middleware.ts - copied exactly from the example repo, except we use the config fn above instead of the default config:
Copy code
import { createOryMiddleware } from "@ory/nextjs/middleware"
import { getOryElementsConfig } from '@/lib/auth'
import {OryConfig} from "@ory/nextjs";

// This function can be marked `async` if using `await` inside
export const middleware = createOryMiddleware(getOryElementsConfig() as OryConfig)

// See "Matching Paths" below to learn more
export const config = {}
next config - the
rewrite
is the critical bit here - I was unsuccesful at getting Ory to call the backend URL consistently via any combination of env vars, so giving a single URL that can be hit from the FE and rewritten by the node server to point to the backend URL got it working.
Copy code
import type { NextConfig } from "next";

// Check if we're in a `npm run dev`
// Note: local deployments to k8s are considered 'production' in this context
const isDev = process.env.NODE_ENV === 'development';
const oryKratosRewriteDestination = isDev ?
    `${process.env.ORY_SDK_URL}/:path*` :
    '<http://app-kratos-public.app.svc.cluster.local:4433/:path*>'

// Parse the API URL from environment or use default
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "<http://localhost:8080>";
const apiDomain = apiUrl.replace(/^https?:\/\//, "");

const nextConfig: NextConfig = {
  images: {
    domains: ["<http://images.unsplash.com|images.unsplash.com>", apiDomain, "localhost"],
  },
  devIndicators: false,
  // Enable standalone output for Docker deployment
  output: 'standalone',
  async rewrites() {
    return [
      {
        source: '/.ory/kratos/:path*',
        destination: oryKratosRewriteDestination,
      },
    ];
  },
};

export default nextConfig;
a
@blue-salesclerk-13657 I am using the example below for Next.js to be able to use Ory Kratos as Authentication. Currently I have the following error occur which from my understanding something is wrong in the code or/and perhaps the package does not exist. Any help on this would be appreciated. `error`:
Copy code
Cannot find module '@ory/nextjs/middleware' or its corresponding type declarations.ts(2307)
Repo: https://github.com/ory/docs/tree/master/code-examples/protect-page-login/nextjs
b
@ancient-magazine-81061 here are the package versions I'm using - maybe you need to pin to one of these -next versions? Iirc these were pre-release when I tried this back in April.
Copy code
"@ory/client": "^1.20.6",
"@ory/client-fetch": "^1.15.0-next.0",
"@ory/elements": "^0.5.3",
"@ory/elements-react": "^1.0.0-next.44",
"@ory/nextjs": "^1.0.0-next.5",
a
@blue-salesclerk-13657 Understood. I noticed the npm packages would install in another folder since I was running
npm install
while not having the
nextjs-app-router
folder as the root folder. I appreciate you helping out regardless.
Did you set your Next.js port to be 4455?.