2

I'm building SPA with Vue and serve it with nodejs and wrapping it in docker container. Here is the problem, I'm trying to stick to 12 factor app where for configuration it says keep in env file.

VueJS provides configs for different environment in config folder. But, according to 12 factor app config should not be in files based on environment.

In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy.

So how can I access nodejs environment variables in VueJS app?

EDIT: Thanks for the answers. The whole idea is to change for example api url on run time trough providing different env variable. If I commit the config file with api url, I would have to rebuild the container on commit and deploy it just for this small change.

I could also have a api access key that is different in dev and prod.

I'm looking for the best way possible to do this kind of things in SPA.

7
  • I think you got those principles completely wrong. The intention is clearly stated: Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code. Config varies substantially across deploys, code does not. So you violate 12 factor app principle #3 if you allow your app access to environment variables. Commented Feb 7, 2018 at 20:28
  • 2
    Ummm, it clearly says in principle 3 The twelve-factor app stores config in environment variables (often shortened to env vars or env). Commented Feb 7, 2018 at 20:31
  • Yes, as part of the build process, not as part of the application itself. Commented Feb 7, 2018 at 20:37
  • I've updated question and tried to explain what I am trying to accomplish. Commented Feb 7, 2018 at 20:53
  • Are you using a dockerfile to build the container? Checkout the answer here for how to do it on build stackoverflow.com/questions/19537645/… Commented Feb 7, 2018 at 21:05

3 Answers 3

3

SPA applications nowadays usually go through a build step. This means compiling all of your files into [near to] one dist file and an index.html which may be served statically. This creates a clear separation between front-end (VueJS) and backend (NodeJS). The index.html and js files themselves continue to be static files nonetheless.

This is usually what you want since you can scale server and client independently: Serve static files, say, through s3 + cdn and run your nodejs server independently.

I think what you want is a way to pass runtime configuration to the client. I wouldn't get too caught up on the details of actually sharing the envvars per se.

In your case, I see two possible solutions:

1) Implement an API to access whitelisted envvars from your server - You can think of this as a /config endpoint

2) Render the index.html dynamically via nodejs with something like ejs with the prepopulated envvars - You'll have more coupling between frontend and server but you could extend this to much more than envvars and, say, preopolute the frontend with prefetched data.

Regardless on how you do it, you can consider this runtime configuration for the frontend which should not be attempted to be fixed at build time since otherwise you may be expose sensitive data into static files and it is not always guaranteed that you have all the data at this time.

Sign up to request clarification or add additional context in comments.

7 Comments

I'm using Azure and Web Apps for Containers. Also I'm utilizing visual studio online build and release pipeline to build static files (index.html, js and css) and then using Dockerfile build container. Accessing api config on some other endpoint is not a good practice and it adds to complexity. If I could pass variables to Docker env, how can I make that available to VueJS app within Docker ran by nodejs?
You can't. Docker env is passed as runtime configuration which at this point is useless since you already built your static files.
Also, I would argue that having a /config endpoint doesn't add complexity and is not a bad practice. You don't need less than what you actually need to solve the problem. How would you inject runtime configuration into,say, an iOS app? This is a similar problem since the frontend and backend are completely decoupled and from what I understand about your build system static files are already built
What about during the dockerfile build?
You don't have access to env during docker build. You could use --build-arg and the ARG instruction in the dockerfile but again, you would have to re-build the image every time you make a change since you'd be imprinting the values in the static files.
|
0

The way you access the env variables should be the same no matter which OS you are using. The way you set them is different though. On windows I would set an environment variable like so

set PASSWORD=somepassword

And then in the code I can access this variable by doing the following

var pw = process.env.PASSWORD;

You should be able to use this the same way in VueJS.

EDIT:

If you use docker-compose you can set the endpoint on the fly by using environment variables too. Then whenever you docker-compose up the endpoint will be updated with the current value of your environment variable. In your shell update the api endpoint to whatever you want it to be.

set API_URL=http://my-api-endpoint

Then in the docker-compose.yml you would access this value like so

version: '3'
services:
  app:
    image: 'myapp'
    environment: 
    - API_URL=${API_URL}

You would still access the variable in your code using process.env.API_URL as I mentioned in my example above.

6 Comments

No, you're not. The browser has no process.env. Aside from This is a violation of twelve-factor, which requires strict separation of config from code.
He asked how to access the node env variables. That is how you do it. No one said anything about the browser. Being that he specifically asked how to access the node environment variable you can assume he is asking how to do it using javascript.
OP also clearly states he's developing an SPA. Show me an SPA that does not require a browser.
Show me a SPA that doesn't have the majority of the code written in Javascript...which is clearly how he would need to access the environment variables.
Because you clearly missed the last question in his post So how can I access nodejs environment variables in VueJS app? The example I posted is how you would do it.
|
0

our devops team will use https://github.com/tinou98/vue-12factor However it's really a big question mark how VueJs does not consider that as a mature frontend/spa framework.

We used to build React Apps since more than 6 years with a built-in support of externalizing env.js file ( create-react-app )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.