0

I am using docker-compose with an image made by someone else and I would like to use environment variables to assign it dynamically

docker-compose.yml

version: "3.7"

services:
  appfronted2:
    image: trafex/alpine-nginx-php7
    container_name: fronted2
    ports:
      - "80:8080"
    volumes:
      - ./fronted2:/var/www/html
    environment:
      - HOST_BACKEND=172.99.0.11
      - PORT_BACKEND=4000
    networks:
      tesis:
        ipv4_address: 172.99.0.13

and this is my javascript where I would like to get the variables but I can't get those variables

api.js

const HOST = process.env.HOST_BACKEND || "127.0.0.1"
const PORT = process.env.PORT_BACKEND || "4000"

const URL_API = `http://${HOST}:${PORT}/api`
Silvio Peña
  • 78
  • 2
  • 11

1 Answers1

2

You are using nginx web server container to serve your html and JS files. The web server serves these files to browser as they are. This is different from using npm start where Node engine serves the HTML and JS files dynamically.

When your JS file runs on client browser, there's no variable called process.env.

Going over comments for following issue in Create React app might help you understand more:

https://github.com/facebook/create-react-app/issues/2353

If you don't have more environment variables, simplest solution would be to use window.location.hostname and prepare or select the API url accordingly.

app-config.js

let backendHost;

const hostname = window && window.location && window.location.hostname;

if(hostname === 'whatsgoodonmenu.com') {
  backendHost = 'https://api.whatsgoodonmenu.com';
} else {
  backendHost = 'http://localhost:8080';
}

export const API_ROOT = `${backendHost}`;

Using in component


import React from "react"
import {API_ROOT} from './app-config'

export default class UserCount extends  React.Component {
    constructor(props) {
        super(props);

        this.state = {
          data: null,
        };
    }

    componentDidMount() {
        fetch(`${API_ROOT}/count`)
            .then(response => response.json())
            .then(data => this.setState({ data }));
    }

    render(){
        return(
            <label>Total visits: {this.state.data}</label>
        );
    }
}
CoderPraBhu
  • 346
  • 3
  • 9
  • Im not using react, im using JavaScript vanilla – Silvio Peña Jun 14 '20 at 02:51
  • Okay. High level explanation remains same. – CoderPraBhu Jun 14 '20 at 05:01
  • if it is the same, but to be a little clearer if I do the configuration of "app-config.js", can I send it my configuration variable from my docker-compose?. Thanks for taking the time to answer me. – Silvio Peña Jun 14 '20 at 05:06
  • Not actually. Even, I faced the problem just two days ago. So I decided to use the hostname from where the UI is hosted and figure out the api url based on it.. The docker compose creates the image with environment variable. These variables are visible to Nginx.. Nginx is not doing any processing but just serving the html and js files without even looking at the environment variables.. Thats why docker compose variables can't be used by Java script code that runs in browser. – CoderPraBhu Jun 14 '20 at 05:14
  • I wish there was a better solution but I thank you for taking the time – Silvio Peña Jun 14 '20 at 05:18
  • Sure. I will update if I find anything interesting. Please update if you find better approach too!. Thanks. – CoderPraBhu Jun 14 '20 at 05:22
  • Answers to following question are interesting. Basically talking about modifying JS files based on environment variable when container starts. I have mixed feelings about this approach but probably the only way forward. [How to pass environment variables to a frontend web application?](https://stackoverflow.com/a/49349963/2080053) – CoderPraBhu Jun 14 '20 at 05:48
  • I did not understand much the example of how I could apply it in my case – Silvio Peña Jun 14 '20 at 05:59