Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Runtime" configuration variables are baked in at compile time when using standalone as target #36551

Closed
1 task done
SoftMemes opened this issue Apr 28, 2022 · 8 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template. Output (export/standalone) Related to the the output option in `next.config.js`.

Comments

@SoftMemes
Copy link

Verify canary release

  • I verified that the issue exists in Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 20.6.0: Wed Jan 12 22:22:42 PST 2022; root:xnu-7195.141.19~2/RELEASE_X86_64
Binaries:
  Node: 16.13.2
  npm: 8.1.2
  Yarn: 3.2.0
  pnpm: N/A
Relevant packages:
  next: 12.1.6-canary.13
  react: 18.0.0
  react-dom: 18.0.0

What browser are you using? (if relevant)

N/A

How are you deploying your application? (if relevant)

N/A

Describe the Bug

I'm leveraging the standalone target (outputStandalone: true) in order to create a self contained build suitable for use in Docker. While I do get an output application, this does not appear to play nice with runtime configuration.

I understand that normally in Next, access to process.env is resolved at build time, but it is possible to inject runtime configuration by accessing process.env (or through other means) in next.config.js.

When using the standalone build however, the config form next.config.js appears to be baked into the generated server.js file, meaning any environment variables set at runtime (such as through the Docker configuration) are ignored.

Expected Behavior

Config is read by evaluating next.config.js (or the original content of it) at runtime when initializing the next standalone server.

To Reproduce

  • Populate publicRuntimeConfig or serverRuntimeConfig in next.config.js from environment variables via process.env
  • Build the site with "standalone" enabled
  • Set environment variables at runtime
  • Observe that the runtime values are not being used
@SoftMemes SoftMemes added the bug Issue was opened via the bug report template. label Apr 28, 2022
@balazsorban44 balazsorban44 added the Output (export/standalone) Related to the the output option in `next.config.js`. label Apr 29, 2022
@balazsorban44
Copy link
Member

An explanation to this has been given here: #33910 (comment)

You could also simply use process.env.MY_VARIABLE and set them in your environment or add them through a .env file. Anything that is not prepended with NEXT_PUBLIC_ will be server-side only and won't be exposed to the client.

@SoftMemes
Copy link
Author

Thank you for the reply, the thread that you referenced is very relevant indeed.

There's some confusion still on my side which may simply be an issue with the documentation. According to https://nextjs.org/docs/basic-features/environment-variables

 In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time.

I've taken this to mean that all process.env variables are baked in at build time.

Additionally, while the process.env at runtime works for the server side configuration, it does not allow for runtime modification of client side config parameters, which was the original reason for my using this pattern. This model is also suggested in the documentation on runtime configuration: https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration

@balazsorban44
Copy link
Member

balazsorban44 commented May 2, 2022

I agree, the docs could be more clear about that. 👍 I think it was overlooked, only client-side values are actually replaced: #20869 (comment)

process.env needs to be evaluated build time though (hence you cannot destructure) to prevent leaking secrets. So Next.js could strip the keys not being used.

Runtime configuration on client-side comes with the penalty of not being able to statically optimize the page (described here), so it would be good to know your use case.

Are you trying to serve content based on the user request/other dynamic parameters?

@SoftMemes
Copy link
Author

Thank you for the reply. My use case is to be able to build a docker image once, then run it across our different environments (development, staging, production). For the clientside, the bits that differ are only some URLs such as the domain used for API calls, some environment specific details passed to Sentry for error reporting, to Google Analytics, etc.

I appreciate that the most performant way of doing this would be to build an image per environment, though I'd like to avoid it if possible as no other parts of the system works in this way, e.g. backend services are all built once, then simply fired up in an environment and tweaked via environment variables.

When I've done this with "traditional" react projects, I've injected a single dynamic config file loaded once on startup of the SPA. I suppose it would be possible to do this also with Next and wrap each client page in a component that reads (and if needed caches) the config with a regular REST call, and have a single dynamic API endpoint depend on environment variables on the server.

@balazsorban44
Copy link
Member

This request sounds like what @leerob concluded here as well: #35820 (comment)

@SoftMemes
Copy link
Author

Agreed, this looks like the same type of use case.

@merlindru
Copy link

merlindru commented May 10, 2022

There's some confusion still on my side which may simply be an issue with the documentation. According to https://nextjs.org/docs/basic-features/environment-variables

 In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time.

I've taken this to mean that all process.env variables are baked in at build time.

Just ran into this as well! Thank you for making this clear 👍 @balazsorban44

kodiakhq bot pushed a commit that referenced this issue May 22, 2022
Based on #36551 (comment) making the docs more clear which also aligns with the wording of Environment Variables in Middlerware: https://nextjs.org/docs/api-reference/next/server#how-do-i-access-environment-variables

See also: #20869 (comment)

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. Output (export/standalone) Related to the the output option in `next.config.js`.
Projects
None yet
Development

No branches or pull requests

3 participants