Pass environment variable value to Angular app from docker file
Asked Answered
C

1

7

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?

Cabbage answered 13/2, 2022 at 16:6 Comment(1)
I see you're trying to use that variable in webpack.config.js - does webpack run in the container or in the dockerfile? If it runs in the dockerfile, it won't have environment variables defined in docker-compose, you could use an ARG instead.Flyspeck
O
5

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:

  1. make a dockerfile, based on the example to first build your project, using the env variable(s).
  2. build the image with the above command.
  3. 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.

Outfox answered 13/2, 2022 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.