We are working on a Dockerized NextJS application that is thought to be built once and deployed to several environments for which we will have different configuration. This configuration is to be set in the Docker container when deployed as environment variables.
In order to achieve this, we are using next.config.js file, splitting the vars on serverRuntimeConfig and publicRuntimeConfig as suggested here, and we are getting the values for the environment variables from process.env. i.e.:
module.exports = {
serverRuntimeConfig: {
mySecret: process.env.MY_SECRET,
secondSecret: process.env.SECOND_SECRET,
},
publicRuntimeConfig: {
staticFolder: process.env.STATIC_FOLDER_URL,
},
}
The problem we have is that these variables are not set on build time (when we run next build), as they are environment specific and supposed to be set on deployment. Because of this, the build fails complaining about the missing variables.
Making a build per environment is not an option: as referred before, we want to build it once (with next build), put the output of the build in a docker container, and use that docker container deploy in several environments.
Is there any way to solve this so that the application builds without environment vars and we pass them afterwards on runtime (deployment)?
We finally found the issue.
We were importing code in a helper that was being used in the isomorphic side and was relaying on serverRuntimeConfig variables, being then required on build time in order to create the bundle.
Removing the import from the helper fixed the issue.
Related
I built a website using Gatsby, Contentful, and deployed on Netlify.
I am going to run this website with multiple domain aliases.
ex:
alias1.example.com
alias2.example.com
In that case, the aliases work well and the website have to show contents that belong to the own alias in Contentful.
For example, let's say the current alias is alias1, then the website have to fetch data only have alias1 entry from Contentful.
What I was trying is to add the codes to identify alias in gatsby-config.js using windows.location.href, and set siteUrl as dynamic, but it didn't work.
I am not sure it could be possible and how to implement it.
Thank you.
The best (and almost the only) approach to achieving this is to use an environment variables for each site/alias and configure the deploy command to trigger and use the variables for each site. In that way, each deploy will fetch the data from each Contentful environment.
In your gatsby-config.js (above the module exportation) add:
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
The next step is to create one environment file for each alias. In your project root:
.env.alias1
.env.alias2
Each file should contain your environment variables from Contentful:
CONTENTFUL_ACCESS_TOKEN:12345
CONTENTFUL_SPACE_ID:12345
Then, in your gatsby-config.js just replace your hardcoded variables for the ones in your environment files:
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
},
},
The last step is to configure the deploy scripts to trigger each desired alias. In your package.json:
"scripts": {
"clean": "gatsby clean",
"test": "jest",
"format": "prettier --write \"**/*.{js,jsx,json,md}\""
"develop-alias1": "gatsby develop GATSBY_ACTIVE_ENV=alias1"
"build-alias1": "gatsby build GATSBY_ACTIVE_ENV=alias1"
"develop-alias2": "gatsby develop GATSBY_ACTIVE_ENV=alias2"
"build-alias2": "gatsby build GATSBY_ACTIVE_ENV=alias2"
},
Note that you will replace the default gatsby develop and gatsby build for your aliased commands.
By adding this bunch of configuration, for each develop or build/deploy you are telling your Gatsby project to which environment file should look at (it will take your .env.alias* instead). Each file will contain the keys for each environment in Contentful with different content in it, allowing you to deploy aliased sites with different content using a unique CMS.
This might be the most critical problem of Gatsby, and almost people has hard time with it.
The core problem is the "browser environment" is not available when you "build" Gatsby project. And gatsby-config.js is used for NodeJS environment. In other words, everything sticked with window variable is not accessible.
You should read the offical docs about gatsby build process here:
https://www.gatsbyjs.com/docs/overview-of-the-gatsby-build-process/#build-time-vs-runtime.
Solution: you can define different "scripts" in package.json for each alias which you can provide environment variables for NodeJS environment. Then in gatsby-config.js, use dotenv package to read passed variables.
You can read more here about using environment variables: https://www.gatsbyjs.com/docs/environment-variables/#reach-skip-nav
I am trying to configure EJBCA 6.15.2.1 on Wildfly 12.0.0.Final inside a Docker container with the help of EJBCA .properties files. In $EJBCA_HOME/conf/externalra-gui.properties.sample there is a comment showing that one of the default settings is: appserver.home=${env.APPSRV_HOME}. I tried to set other options in a similar way, e. g. in database.properties: database.datasource=${env.WF_DATASRC}.
I run ant clean deployear and it didn't deploy my EJBCA instance properly at first - server.log showed that there is no datasource under the name "${env.WF_DATASRC}". It proceeded correctly after I'd changed the line to: database.datasource=ejbcads, which is the exact value of the variable and the name of the data source inside the WildFly server.
I get similar errors during further installation steps. Is there another way of setting EJBCA configuration using environment variables?
I have a static site Vue.Js docker image built on nginx:alpine.
In a component, there is a URL variable for an EndPoint - I would like to be able to change this variable. I understand that I only have access to ENV variables at the build stage after this everything is static.
What I want to achieve is being able to build 1 image: that I can deploy Test-Staging-Prod environments setting a different URL for each.
I can run a script that uses variable substitution on deploy that would replace the URL e.g #{url:urlEndpoint} in the js file (i can see it in plaintext) - but this is dangerous for the obvious reasons.
How can set this up and pass the url in Vue.Js without having different images for Test Staging etc?
I'm working on an app with vuejs frontend and nodejs backend. My frontend makes API https requests to the backend. I've started my projet with vue-cli and webpack.
I need to get the backend API url from env variable (BACKEND_URL).
Since i'm using webpack, I added this line to config/prod.env.js :
module.exports = {
NODE_ENV: '"production"',
-> BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
It works flawlessly in dev mode using webpack-dev-server. I pass the env var throught docker-compose file:
environment:
- BACKEND_URL=https://whatever:3000
But when I run build, I use nginx to serve the static files (but the problem is the same using visual studio code live server extension). I send BACKEND_URL env var the same way as before. The thing is now the process.env.BACKEND_URL is undefined in the app (but defined in the container)!! So I cant make backend http calls :(
I'm struggling finding the problem, please don't be rude with the responses. Thank you
They aren not "translated" during build time, this is what is happening with you. On a node environment, when you ask for process.env it will show all environment variables available in the system, that is true. But a web application does not have access to process.env when it is executing. You need a way to translate them during build time.
To achieve that you have to use DefinePlugin. It translates anything during build time and writes a magical string where this other thing was.
Using you own example:
module.exports = {
NODE_ENV: '"production"',
BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
If you do this during build time, without DefinePlugin, webpack won't know what to do with it, and it is going to be a simple string.
If you use DefinePlugin:
new webpack.DefinePlugin({
"process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL)
});
By doing this, you are allowing webpack to translate this during build time.
Give this a shot: https://www.brandonbarnett.io/blog/2018/05/accessing-environment-variables-from-a-webpack-bundle-in-a-docker-container/
If I'm understanding your problem correctly, you're serving a webpack bundle using nginx, and trying to access an environment variable from that bundle.
Unfortunately, it doesn't quite work that way. Your JS file has no access to the environment since it's a resource that has been delivered to the client. I've proposed a solution that also delivers those env variables alongside the bundle in a separate JS file that gets created on container start.
From VueJS Docs: https://cli.vuejs.org/guide/mode-and-env.html
Using Env Variables in Client-side Code
Only variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. You can access them in your application code:
console.log(process.env.VUE_APP_SECRET)
During build, process.env.VUE_APP_SECRET will be replaced by the corresponding value. In the case of VUE_APP_SECRET=secret, it will be replaced by "secret".
So in your case, the following should do the trick. I had the same problem once in my project, which I started with vue/cli and vue create project ...
VUE_APP_BACKEND_URL=https://whatever:3000
I have a node that runs several applications. These applications each have specific env settings. When I generate a release I start my node by just running ./rel/mynode/bin/mynode start. Is there an option that I could add to this command to override apps' env settings?
To answer your question: No, there is no parameter that you can pass into that command to load a different application env file.
However, if you are trying to load a different config file, for example a development file vs. a production file, you should check out how to do dynamic configuration with rebar.
I use it for running my application between different configured environments (production, and local testing).
I don't quite get what you mean by env settings. If you mean the applications configuration parameters that are set in the {Par,Val} tuples of the key env in the .app files then these can also be overridden in a system configuration file or directly in the command line. See the Configuring an Application section.