nextjs-auth0をdocker上でも使いたい

nextjsでも簡単にauth0を使いたい！
と思ってサンプルに従うと、Dockerビルドってかproduction buildするとエラーで落ちちゃいます。

configのサンプル
auth0/nextjs-auth0: Next.js SDK for signing in with Auth0 (Experimental) - https://github.com/auth0/nextjs-auth0#runtime-configuration

```javascript
import { initAuth0 } from '@auth0/nextjs-auth0';
import config from './config';

export default initAuth0({
  domain: process.env.AUTHO_DOMAIN,
  clientId: process.env.AUTHO_DOMAIN,
  clientSecret: process.env.APP_SECRRET,
  scope: 'openid profile',
```

エラー内容こんな感じ。process.env.XXXが見れないから落ちてるのかな。

```
Automatically optimizing pages...
> Build error occurred
Error: A valid Auth0 Domain must be provided
    at Object.createInstance [as default] (/usr/src/app/node_modules/@auth0/nextjs-auth0/dist/instance.node.js:10:15)
    at initAuth0 (/usr/src/app/node_modules/@auth0/nextjs-auth0/dist/index.js:8:46)
    at Object.xMDF (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:781:127)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at Module.1TCz (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:147:13)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at Object.0 (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:99:18)
    at __webpack_require__ (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:23:31)
    at /usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:91:18
    at Object.<anonymous> (/usr/src/app/.next/server/static/GDDYxjIWKG2mlWWc4bTrE/pages/_app.js:94:10)
error Command failed with exit code 1
```

## ボツ案
issue投げて聞いてみたら、 `.env` を仮データで追加し実行時に再ビルドすると大丈夫らしい。試したらできた。

Can't build on docker. · Issue #86 · auth0/nextjs-auth0 - https://github.com/auth0/nextjs-auth0/issues/86

```Dockerfile:Dockerfile
FROM node:14 as builder

WORKDIR /app

COPY .env.template .env
COPY package.json yarn.lock ./
RUN yarn install

COPY . .
RUN yarn build

# ------------------
FROM node:14-alpine as release

WORKDIR /app

COPY --from=builder /app/package.json /app/yarn.lock ./
RUN yarn install
COPY --from=builder /app/.next ./.next
COPY . .

EXPOSE 3000
CMD ["yarn", "start:build"]

```

```json:package.json
  "scripts": {
    "start": "next start",
    "start:build": "yarn build && yarn start",
    "build": "next build",
```


確かにできるんだけど、CI時にビルド２回ぐらい回しちゃうことになって、めっちゃ時間かかる・・・

## 改善案

initAuth0のオブジェクトを直接export defaultすると、環境変数がバインドされちゃうので、関数にしてあとからprocess.envを評価すればいいじゃんって案

Document best practices for using nextjs-auth0 with a nextjs production build. · Issue #154 · auth0/nextjs-auth0 - https://github.com/auth0/nextjs-auth0/issues/154


環境変数はgetConfig()経由で受け取り、バインドすると想定通り動いてくれた。やったね！

```javascript:src/lib/auth0.js
import getConfig from 'next/config';
import { initAuth0 } from '@auth0/nextjs-auth0';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

let auth0 = null;

const proc = () => {
  if (!auth0) {
    auth0 = initAuth0({
      clientId: publicRuntimeConfig.auth0.clientId,
      domain: publicRuntimeConfig.auth0.domain,
      scope: 'openid email profile',
      postLogoutRedirectUri: publicRuntimeConfig.baseUrl,
      redirectUri: `${publicRuntimeConfig.baseUrl}/api/auth/signed-in`,
      clientSecret: serverRuntimeConfig?.auth0?.secret ?? '',
      session: {
        cookieSecret: serverRuntimeConfig?.appSecret ?? '',
        // Set to 8 hours
        cookieLifetime: 60 * 60 * 8,
        storeIdToken: false,
        storeAccessToken: false,
        storeRefreshToken: false,
      },
      oidcClient: {
        // Optionally configure the timeout in milliseconds for HTTP requests to Auth0.
        httpTimeout: 2500,
        // Optionally configure the clock tolerance in milliseconds, if the time on your server is running behind.
        clockTolerance: 10000,
      },
    });
  }

  return auth0;
};

export default proc;
```

```javascript:next.config.js
const nextConfig = {
  serverRuntimeConfig: {
    appSecret: process.env.APP_SECRET,
    auth0: {
      secret: process.env.AUTH0_CLIENT_SECRET,
    },
  },
  publicRuntimeConfig: {
    baseUrl: process.env.NEXT_PUBLIC_BASE_URL,
    auth0: {
      clientId: process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID,
      domain: process.env.NEXT_PUBLIC_AUTH0_DOMAIN,
    },
  },
};

module.exports = nextConfig;
```

```diff:page/auth/api/sign-in.js
diff --git a/pages/api/auth/sign-in.js b/pages/api/auth/sign-in.js
index 7b109a7..d271932 100644
--- a/pages/api/auth/sign-in.js
+++ b/pages/api/auth/sign-in.js
@@ -1,6 +1,8 @@
-import auth0 from '../../../src/lib/auth0';
+import Auth0 from '../../../src/lib/auth0';
 import { checkHeaders } from '../../../src/lib/middleware/auth';
 
+const auth0 = Auth0();
+
 const login = checkHeaders(async (req, res) => {
   try {
     await auth0.handleLogin(req, res);

```