Reputation: 475
I am new into angular. I have deployed an angular app into a docker container in aws. The app needs to connect to aws s3 bucket. I dont need to hardcode the aws key so I setup an environment variable in the docker. the angular is deployed such that the dist folder from the ng build is served by an nginx docker container.
Is it possible to read the server environment variable by the angular once the contents from the dist folder is served into the server? like env function in php and nodejs
Upvotes: 4
Views: 21633
Reputation: 133
I know this is an old question, but I wanted to add a potential option for anyone searching for this.
If you are deploying your Angular app in a Docker container using NGinx or something similar, I used a tool called confd
by @kelseyhightower here https://github.com/kelseyhightower/confd .
Basically modifying index.html so it had confd template variables in it, that create a "config" object that is then accessible in your Angular code. You could then use the values in that "config" object to set your environment.ts
values. Confd would need to be set up to run on container start.
This would be added to the end of your Dockerfile
This would be added to your index.html file.
This is the start script for the container. I copy it into /usr/local/bin
as part of my Dockerfile steps.
Access the values in your environment.ts
file
Worked well for me so far, but you may need to find an alternate solution for deployments that are not Container based.
Upvotes: 2
Reputation: 2438
Unfortunately there is no way to read an environment variable in Angular similar to mechanisms that server frameworks like nodejs or Spring Boot offer.
You could however load the environment from the server before the Angular app bootstraps (please read the drawbacks below before taking this path).
Load environment variables from a server:
import { Injectable } from "@angular/core";
@Injectable({ providedIn: "root" })
export class EnvService {
public myEnv: string;
fetchEnv() {
// This has to retrieved from some server.
return fetch("some-url").then(env => {this.myEnv = env.myEnv; return Promise.resolve("env loaded");};
}
}
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent, HelloComponent]
})
export class AppModule {
constructor(private envService: EnvService) {}
ngDoBootstrap(app) {
this.envService.fetchEnv().then(() => app.bootstrap(AppComponent));
}
}
This approach has a couple of drawbacks:
I would therefore recommend configuring the env variables during the build.
There are 2 ways you can set the environment variables during the build:
1) Set the environment variable in the build using a custom webpack config
See this article.
You can specify a custom webpack config in your angular.json:
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "extra-webpack.config.js"
},
...
The webpack config file would look like this:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
// Here you can set your env variables.
SERVER_URL: JSON.stringify(process.env.SERVER_URL)
}
})
]
}
This method requires some more dependencies:
@angular-builders/custom-webpack
dotenv
2) Dynamically create an environment file during build
See e.g. the automatically generated src/environments/environment.prod.ts. You could generate this file with the correct environment values or replace placeholders in this file during the build.
Edit: See also The Fabio's answer. You probably don't want your users to be aware of the S3 bucket anyway and should route your request over a web server to the bucket if possible.
Upvotes: 8
Reputation: 6260
php and nodejs run on the server side, that's why they have access to the server environment variables.
Anything your angular app can read is exposed to the client, as Angular runs in the browser. I would assume you don't want your AWS keys floating around on the client where any user could ready them. This exposes your back-end to malicious use.
You can always create an endpoint in the server app your angular app is talking to expose the server environment variables if you really choose to go that path.
The more common pattern is to have your server endpoints serving data to angular instead of its environment variables:
I am overly simplifying the server interaction as that is something I would advise you to read in separated from this question. This post should help you in getting started with back-end / front-end separation.
Upvotes: 1