How to Access Environment Variables in React Production Build
I’ve been transitioning my React app from development to production and ran into issues regarding environment variables.
Problem
Development generally involves running npm start
, or react-scripts start
.
Production generally involves running npm run build
, or react-scripts build
.
Suppose I had a single environment
variable in my docker-compose.yml
.
In development, this REACT_APP_URI
is available in my React application.
# docker-compose.yml
version: "3"
services:
client:
build:
context: .
dockerfile: Dockerfile
environment:
- REACT_APP_URI=http://localhost:5000
ports:
- 3000:3000
However, when I bundle my React app into production-ready static files with npm run build
, this REACT_APP_URI
is not available as an environment variable.
# Dockerfile
FROM node:14.16.0-alpine3.10 as builder
WORKDIR /usr/app
COPY package*.json .
RUN npm install --only=prod
COPY . .
RUN npm run build
Solution
The issue here is that environment variables are only available after the container starts up.
In development, the application is running on webpack-dev-server
after the container is started.
In production, our React application needs this variable during the build itself. In order to fix this, we can use build arguments in our docker-compose.yml
.
Let’s move our REACT_APP_URI
from environment
to build.args
, and for clarity, let’s rename it to URI
.
# docker-compose.yml
version: "3"
services:
client:
build:
context: .
dockerfile: Dockerfile
args:
- URI=http://localhost:5000
ports:
- 3000:3000
We can pull these values inside our Dockerfile
using ARG
.
We’ll then be setting a new environment variable REACT_APP_URI
equal to our ARG
variable $URI
.
# Dockerfile
FROM node:14.16.0-alpine3.10 as builder
WORKDIR /usr/app
COPY package*.json .
RUN npm install --only=prod
COPY . .
# Get build argument and set environment variable
ARG URI
ENV REACT_APP_URI=$URI
# Continue with rest of script
RUN npm run build
This REACT_APP_URI
is now available in our production-ready React bundle.
This, of course, can also be achieved with a docker build
command using --build-arg
.