I have an Angular app where i'm trying to set the environment variable from outside of the app i.e., from docker compose file.
I'm referring below article
https://codinglatte.com/posts/angular/using-os-environment-variables-in-angular-with-docker/
docker-compose.yml
version: '3'
services:
tomcat-server:
image: "tomcat:latest"
ports:
- "8071:8080"
environment:
- API_URL=http://demo-production.com
I could even see the environment variable set when I execute the below command
docker exec -it <dockerName> sh
env
but somehow the value is not being received by Angular app, below is my Angular app code as per the above article
environment.prod.ts
export const environment = {
production: true,
API_URL: $ENV.API_URL,
TEST_ENV: 'testing'
// API_URL: 'http://production.com'
};
typings.d.ts
declare var $ENV: Env;
interface Env {
API_URL: string
}
custom-webpack.config.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
$ENV: {
API_URL: JSON.stringify(process.env.API_URL)
}
})
]
};
Command I used to create the build
ng build --configuration=production --base-href=/demoapp/
I couldn't figure out the issue here as the environment value set in docker file is not reflecting in my app.
Can I get some help here?
CodePudding user response:
The problem is that you confuse build time with run time. What you need are variables passed at build time. You can pass them in a build command:
docker build -t my_image --build-arg API_URL=http://demo-production.com .
The .
in the end gives the context
, in this case the current directory. It will expect to find a dockerfile named Dockerfile
there. In the link you posted you find a dockerfile in the bottom, there you also see the environment variables defined as expected.
In that file they first use a node image to build the app WITH your env variables, and then a deploy stage where they copy the outputs to the correct location inside an nginx container.
You specify a tomcat container in the docker-compose file. That container will not build anything. Even if you would pass the arguments correctly, it has no way of knowing what to do with it.
What you should probably do is:
- make a dockerfile, based on the example to first build your project, using the env variable(s).
- build the image with the above command.
- run a container based on the image with:
docker run --name my-container-name -p "8071:8080" my-image
This is assuming that in the second stage of the dockerfile you use tomcat, which uses port 8080 that you are mapping. If you would like to use docker compose it could look like:
version: '3'
services:
tomcat-server:
build:
context: .
args:
API_URL=http://demo-production.com
ports:
- "8071:8080"
This would then call the docker build and run command for you, so you obviously still need the dockerfile.
If you are interested in passing the environment variables in run time to angular it is a different thing. You can read about it here in a blog I wrote, if you want.