next.js: outputStandalone + serverRuntimeConfig not working as expected

Run next info (available from version 12.0.8 and up)

Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 21.4.0: Tue Jan 18 13:02:08 PST 2022; root:xnu-8020.100.406.0.1~18/RELEASE_ARM64_T8101 Binaries: Node: 16.13.2 npm: 8.1.2 Yarn: 3.1.1 pnpm: N/A Relevant packages: next: 12.0.10 react: 17.0.2 react-dom: 17.0.2

What version of Next.js are you using?

12.0.10

What version of Node.js are you using?

16.13.2

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

Docker

Describe the Bug

I have noticed the outputStandalone option and decide to try it for our docker deployment. It worked great and dramatically reduced the size of the image (x12). However, I stumbled upon a small problem.

When the server.js file is generated, it automatically expands publicRuntimeConfig and serverRuntimeConfig into the conf entry of NextServer. This pretty much means that we cannot use any dynamic environment variables in docker, as all of them are only respected during build.

Expected Behavior

next.config.js should be copied to the standalone output and its configuration should be used.

It’s quite common to have a single docker image that can suit all environments with different configuration. Using the regular next build, without outputStandalone, this is also possible.

To Reproduce

Add the following to next.config.js:

    serverRuntimeConfig: {
      API_URL: process.env.API_URL
    },
    experimental: {
      outputStandalone: true
    },

run next build

inspect .next/standalone/server.js- there is no API_URL entry in serverRuntimeConfig

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 19 (10 by maintainers)

Most upvoted comments

I understand. I think there isn’t a second issue. It was my misinterpretation.

Also, to better understand why serverRuntimeConfig is being used here, why are you storing the env variable in serverRuntimeConfig instead of accessing process.env.API_URL in the code directly where needed?

Hi @ijjk!

I may have a use case for this feature: I manage multiple environments for the same Next.js project with credentials (used server-side only) that can vary between environments, for exemple backend URLs (that are proxied through /api routes) & related API secrets.

serverRuntimeConfig hydrated with process.env.MY_VARIABLES is very useful in this case as it doesn’t require the whole project to be rebuilt + packaged in Docker when deploying the project to all the environments.

Hello @ijjk, Thanks for your feedback. I did try to modify server.js, but as you said, next.config.js has some dependencies, so I couldn’t make it work. As for why using serverRuntimeConfig, I honestly don’t have an answer. I guess this was a historical config, trying to also support client-side config. I will experiment with using the env directly, thanks.

Hi, currently the config with outputStandalone is serialized and inlined in the server.js file generated to prevent relying on any dependencies in next.config.js and prevent unexpected breaking from building to deploying. If the serverRuntimeConfig values can not be set during build-time and need to be able to change with the env then you can change the inlined config in the server.js file to conf: require('./path/to/next.config.js') instead.

Also, to better understand why serverRuntimeConfig is being used here, why are you storing the env variable in serverRuntimeConfig instead of accessing process.env.API_URL in the code directly where needed?