I’m having trouble accessing environment variables in a React app which has its build served by a Flask app. The client was initialized with CRA and later modified to use CRACO for customization. The whole project is containerized with Docker and hosted on Heroku. I’m trying to figure out the best way to handle and pass environment variables in the builds. Any advice on how to properly configure this setup for accessing env vars on the client side? It works only locally. Things I have tried:
- Set env var in Docker and Heroku configs
- Updated CRACO config to include
webpack.DefinePlugin
Here is the Dockerfile:
FROM node:18 as builder
WORKDIR /frontend
COPY /frontend/package.json .
COPY /frontend .
ARG REACT_APP_SOCKET_URL
ENV REACT_APP_SOCKET_URL=$REACT_APP_SOCKET_URL
RUN npm install && npm run build
FROM python:3.10-alpine
WORKDIR /app
COPY /backend/requirements.txt ./backend/
RUN pip install -r ./backend/requirements.txt
# Install dockerize to allow containers to wait for dependency containers to be done
RUN apk add openssl \
&& wget https://github.com/jwilder/dockerize/releases/download/v0.6.1/dockerize-alpine-linux-amd64-v0.6.1.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-v0.6.1.tar.gz \
&& rm dockerize-alpine-linux-amd64-v0.6.1.tar.gz
COPY /backend ./backend
ENV PYTHONPATH "${PYTHONPATH}:/app/backend"
COPY --from=builder /frontend/build ./build
CMD ["python", "backend/app.py"]
And the docker-compose file:
version: "3.8"
services:
web:
build:
context: ./
dockerfile: Dockerfile.web
args:
- REACT_APP_SOCKET_URL=${REACT_APP_SOCKET_URL}
env_file:
- ./.env
ports:
- "5001:5001"
volumes:
- ./backend:/app/backend
depends_on:
- db
- migration
- redis
- elasticsearch
command: >
sh -c "
dockerize -wait tcp://db:5432 -wait tcp://redis:6379 -wait tcp://elasticsearch:9200 -timeout 120s
&& python backend/app.py
"
db:
image: postgres:alpine
environment:
POSTGRES_DB: dev
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:alpine
ports:
- "6379:6379"
migration:
build:
context: ./
dockerfile: Dockerfile.migration
env_file:
- ./.env
volumes:
- ./backend/migrations:/app/migrations
depends_on:
- db
command: >
sh -c "
dockerize -wait tcp://db:5432 -timeout 10s
&& flask --app run_migrations:app db upgrade
"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4
environment:
- discovery.type=single-node
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- "9200:9200"
depends_on:
- db
- migration
volumes:
postgres-data:
esdata:
driver: local
Heroku config:
build:
docker:
web: Dockerfile.web
migration: Dockerfile.migration
release:
image: migration
command:
- flask --app run_migrations:app db upgrade
run:
web:
image: web
command:
- gunicorn backend.app:app
And Webpack plugins setting in craco-config:
plugins: [
new webpack.DefinePlugin({
"process.env.REACT_APP_SOCKET_URL": JSON.stringify(
process.env.REACT_APP_SOCKET_URL
)
})
]