Solución:
Me gustaría agradecer a todos los que publicaron respuestas y comentarios. El problema al que me enfrentaba se resolvió mediante una combinación de estas respuestas y la ayuda de otros recursos.
Como lo sugirió @DavidMaze (en los comentarios), comencé a buscar en la configuración del paquete web presente en mi código. Descubrí que el paquete web estaba leyendo todas las variables de entorno declaradas dentro del contenedor.
Así que comencé a experimentar con mi Dockerfile y docker-compose.yml cuando me di cuenta de que REACT_APP_HOST_IP_ADDRESS
no se pasaba como una variable de entorno cuando el react estaba construyendo el código.
Lo primero que cambié fue el Dockerfile. Declaré estáticamente la IP dentro de dockerfile para probar
ENV REACT_APP_HOST_IP_ADDRESS localhost
. Al hacer esto, pude ver el valor localhost dentro de las variables env que fueron leídas por webpack.
Ahora intenté pasar la variable ENV de docker-compose a dockerfile como lo sugirió @Alex en su respuesta, pero no funcionó.
Así que me referí a https://github.com/docker/compose/issues/5600 y cambié el docker-compose.yml y Dockerfile de la siguiente manera
docker-compose.yml
version: '2'
services:
nginx:
container_name: ui
build:
context: nginx/
args:
REACT_APP_HOST_IP_ADDRESS= ${IP_ADDRESS}
ports:
- "80:80"
dónde IP_ADDRESS
se exporta como una variable env.
Dockerfile
FROM node:8 as ui-builder
WORKDIR /home/ui
COPY helloworld .
RUN npm install
ARG REACT_APP_HOST_IP_ADDRESS
ENV REACT_APP_HOST_IP_ADDRESS $REACT_APP_HOST_IP_ADDRESS
RUN npm run build
FROM nginx
COPY --from=ui-builder /home/ui/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
Componente de reacción
import React, { Component } from 'react';
class HelloWorld extends Component {
render() {
console.log(process.env.REACT_APP_HOST_IP_ADDRESS);
return (
<div className="helloContainer">
<h1>Hello, world!</h1>
</div>
);
}
}
export default HelloWorld;
Esta configuración hace que las variables pasadas a través de ARG en docker-compose a Dockerfile durante el proceso de compilación de la imagen y, por lo tanto, las variables se pueden declarar a su vez como variables env que React puede usar durante el proceso de compilación siempre que el paquete web lea las variables env.
El paquete web podrá leer las variables env usando DefinePlugin https://webpack.js.org/plugins/define-plugin/
Las variables de entorno deben comenzar con REACT_APP_; de lo contrario, las variables NODE_ENV están un poco confusas y su variable de entorno no funcionará:
environment:
- REACT_APP_DEBUG=TRUE
De lo contrario, docker-compose.yml
no es válido y verá un mensaje de error:
services.client.environment contains an invalid type, it should be an object, or an array
Aquí hay una muestra de trabajo:
docker-compose.yml
version: "3.3"
services:
client:
container_name: client
environment:
- REACT_APP_DEBUG=TRUE
build:
dockerfile: Dockerfile
context: ./web/client
Dockerfile
FROM node:6.0.0
# Set env variable
ARG REACT_APP_DEBUG
ENV REACT_APP_DEBUG=$REACT_APP_DEBUG
# that will be empty
RUN echo "DEBUG": $REACT_APP_DEBUG
Correr:
->docker-compose run client node
->process.env.REACT_APP_DEBUG
'TRUE'
Aquí está mi solución usando ENV
en mi Dockerfile
, DefinePlugin
en el webpack.config.js
y process.env
en mis códigos javascript:
Primero configure su variable de entorno y su valor en su Dockerfile
:
...
RUN npm install
ENV MY_ENV_VAR my_env_value
...
Luego usando DefinePlugin
complemento, agréguelo a process.env
en webpack.config.js
:
const webpack = require('webpack');
...
plugins: [
new webpack.DefinePlugin({
'process.env.MY_ENV_VAR': JSON.stringify(env.MY_ENV_VAR),
}),
],
...
Y finalmente usa la variable env en tu código:
const host = process.env.MY_ENV_VAR || 'a_default_value_in_case_no_env_is_found';