next.js - env vs serverRuntimeConfig - environment-variables

I read about serverRuntimeConfig here: https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
Now my next.config.js is:
module.exports = withCSS({
target: 'serverless',
reactStrictMode: false,
env: {
SECRET: 'SECRET'
}
});
I'm wondering, should I use serverRuntimeConfig for my secret env var instead of env ?
What are the pros / cons ?

Generally you'll want to use build-time environment variables to provide your configuration. The reason for this is that runtime configuration adds rendering / initialization overhead and is incompatible with Automatic Static Optimization.
# https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
As they said, the runtime configuration in next.config.js may cause overhead.
So I suggest using env in next.config.js, or using the .env* files in this new method (https://nextjs.org/docs/basic-features/environment-variables)
The code using your secret env vars should be in the server-side (API routes, getStaticProps, getServerSideProps), not in client-side (components...). If you reference them in client-side, they may be exposed!

Related

Gatsby .env.production variables - undefined

When building a Gatsby project I'm getting all env variables undefined in production environment.
In development everything is fine.
I have 2 similar .env.development and .env.production files.
In my gatsby-config.js I have
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});
and if I console.log(process.env.NODE_ENV) during gatsby build it gives production and the variables can be accessed and logged out.
But later in code something like
return request.post(`${process.env.GEOCODING_CF_URL}/latlng`, {...});
gives request to http://localhost:9000/ru/undefined/latlng.
What am I doing wrong and how this issue can be fixed?
UPDATE:
When I run gatsby build - process.env.NODE_ENV is production
When I run gatsby serve - process.env.NODE_ENV is undefined
If this can help in any way.
If you use environment variables in node you don't need a prefix (like in your gatsby-config.js). However, if you need to use them in a component or a page you must add GATSBY_ as a prefix, so GEOCODING_CF_URL should be GATSBY_GEOCODING_CF_URL
For me, NODE_ENV=production yarn gatsby serve did the trick.
https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/
Accessing Environment Variables in the browser.
By default, environment variables are only available in Node.js code and are not available in the browser as some variables should be kept secret and not exposed to anyone visiting the site.
To expose a variable in the browser, you must preface its name with GATSBY_. So GATSBY_API_URL will be available in browser code but API_KEY will not.
Variables are set when JavaScript is compiled so when the development server is started or you build your site.
src/pages/index.js
Copysrc/pages/index.js: copy code to clipboard
import React, { useState, useEffect } from "react"
function App() {
const [data, setData] = useState()
useEffect(async () => {
const result = await fetch(
`${process.env.GATSBY_API_URL}/users`
).then(res => res.json())
setData(result.data)
})
return (
<ul>
{data.map(user => (
<li key={user.id}>
<a href={user.url}>{user.name}</a>
</li>
))}
</ul>
)
}
export default App

Expose Rails Env to Webpacker

I'm running Rails v5 with Webpacker v2. Everything's been smooth so far, but I've hit one hiccup: how to expose Rails helpers to my TypeScript.
I know Webpacker ships with rails-erb-loader, so I was expecting that I'd be able to add .erb to a TypeScript file, and then import that file elsewhere:
// app/javascript/utils/rails.ts.erb
export const env = "<%= Rails.env %>"
export function isEnv(envName: string) {
return env == envName
}
// app/javascript/packs/application.ts
import { env } from "../utils/rails"
But Webpack can't find the "rails" file even if I modify the typescript loader to include ERB files:
module.exports = {
test: /.ts(\.erb)?$/,
loader: 'ts-loader'
}
All I see is:
error TS2307: Cannot find module '../utils/rails'.
What's the best way to go about exposing Rails helpers and variables to my JavaScript?
Rails env comes from your environment variable. This means you configure it by setting (in bash for example) the variable in this way:
export RAILS_ENV=production
As a consequence, you don't need to deal with Rails at all.
// app/javascript/utils/rails.ts.erb
export const env = process.env.RAILS_ENV || "development"
export function isEnv(envName: string) {
return env == envName
}
This comes with a great advantage: you don't have to load the whole rails app just to compile your javascript. Rails can become really slow on first load if your app grows.
Since you won't have access to process.env on the frontend (browser), you also need a way to make it exist. In webpack, this is done through the DefinePlugin:
Update your webpack configuration to use the plugin (in plugins section): new webpack.DefinePlugin({ "process.env": { RAILS_ENV: process.env.RAILS_ENV } }) and you will get a process.env.RAILS_ENV available in the client
Rails Env can be accessed through:
process.env.RAILS_ENV

YAML - groovy - env var can't be an integer?

Project is in Groovy/Grails/Gradle/Camel Routes
This seems pretty reasonable:
server:
port: ${PORT}
But I get :
java.lang.NumberFormatException: For input string: "${PORT}"
at org.grails.config.CodeGenConfig.convertToType(CodeGenConfig.groovy:191)
at org.grails.config.CodeGenConfig.getProperty(CodeGenConfig.groovy:264)
at grails.config.ConfigMap$getProperty.call(Unknown Source)
at run-app.run(run-app.groovy:31)
at org.grails.cli.profile.commands.script.GroovyScriptCommand.handle(GroovyScriptCommand.groovy:152)
at org.grails.cli.profile.AbstractProfile.handleCommand(AbstractProfile.groovy:452)
at org.grails.cli.GrailsCli.handleCommand(GrailsCli.groovy:373)
at org.grails.cli.GrailsCli$_handleCommandWithCancellationSupport_closure6.doCall(GrailsCli.groovy:464)
at org.grails.cli.GrailsCli$_handleCommandWithCancellationSupport_closure6.call(GrailsCli.groovy)
String env vars do not have an issue and work just fine.
I cannot find any syntax to make cast to an int when I search.
Any thoughts?
In a Grails/Spring Boot app, if the configuration is short hand as below:
server:
port: ${PORT}
then the app expects --PORT=8090 (for example) to be provided as a System arg / environment property upon application startup. Make sure that environment variable is provided.
To make the environment variable value available in application.yml we would also need below task configuration in Grails apps:
bootRun {
systemProperties = System.properties
}
With plain vanilla Spring Boot Maven apps above is not required.
Also, to avoid any kind of exception we can also provide a default value for port if feasible like below:
server:
port: ${PORT:8085}

How do I set NODE_ENV=production on Electron app when packaged with electron-packager?

How do I make packaged releases of my Electron application set NODE_ENV=production when packaged with electron-packager?
UPDATE 2019/12
Use app.isPackaged: https://electronjs.org/docs/api/app#appispackaged-readonly
It returns true if the app is packaged, false otherwise. Assuming you only need a check if it's in production or not, that should do it. The env file solution detailed below would be more suitable if you had different environments/builds with different behaviors.
To my knowledge, you can't pass env vars to a packaged electron app on start (unless you want your users to always start it from the command line and pass it themselves). You can always set that env variable in your application like this: process.env.NODE_ENV = 'production'. You could integrate that with electron-packager by having an env file that gets set in your build and is required by your application to determine what environment it's in.
For example, have a packaging script that looks like:
"package": "cp env-prod.json src/env.json && npm run build"
and in your src/main.js file:
const appEnv = require('./env.json');
console.log(appEnv) //=> { env: "prod", stuff: "hey" }
//you don't really need this, but just in case you're really tied to that NODE_ENV var
if(appEnv.env === 'prod') {
process.env.NODE_ENV = 'production';
}
You can set it in 2 ways.
By command line with --no-prune see here in the usage guide
Or programmatically with this API
var packager = require('electron-packager');
var options = {
'arch': 'ia32',
'platform': 'win32',
'dir': './'
'prune': true //this set the enviroment on production and ignore dev modules
};
packager(options, function done_callback (err, appPaths) { /* … */ })
For more options see this guide

How do I populate my Elixir config from runtime variables? [duplicate]

Following the setup instructions, I have the following Ecto configuration in my config/config.exs file :
config :my_app, MyApp.Repo,
adapter: Ecto.Adapters.Postgres,
url: "postgresql://postgres#localhost/myrepo",
size: 20
If my understanding is correct, the config.exs is evaluated at compile-time.
Is there a way to do this configuration step at runtime ?
This is for an app which will be distributed as a compiled binary (via exrm). The end-user should be able to customize the database url and pool size via flags or environment variables, not by editing sys.config
Loading from the system is possible by using {:system, "KEY" } e.g.:
config :my_app Repo
url: {:system, "DATABASE_URL" },
size: {:system, "DATABASE_POOL_SIZE" }
instead
config :my_app, Repo,
url: "ecto://postgres:postgres#localhost/ecto_simple",
size: 20
In this case you set up Ecto to use the system properties. Of course, a user has to configure it.
Using {:system, "KEY"} has been deprecated in Ecto v3.
Instead, you are advised to define an init/2 callback function within your Repo module to set runtime config:
def init(_type, config) do
config = Keyword.put(config, :url, System.get_env("DATABASE_URL"))
{:ok, config}
end
Using a runtime init/2 function allows configuration to be read from more than just environment variables.

Resources