DEV Community

Biswarup Adhikari
Biswarup Adhikari

Posted on

Streamlining React App Deployments: Overcoming Docker Build Args Limitations with `env-config.js`

When deploying React applications or any javascript based frontend applications such as Angular, Vuejs etc across various environments like development, staging, and production, developers often face a common challenge with Docker: the limitations of build arguments (--build-arg). Build arguments are frequently used to pass environment-specific configurations to a Docker image at build time. However, this approach hardcodes the values into the image, reducing flexibility and requiring separate builds for each environment. This article explores an alternative strategy using env-config.js, enhancing the reusability and flexibility of Docker images across different environments.

Understanding the Problem with Docker Build Args

Docker's build arguments allow you to pass configuration during the image build process. For instance:

ARG REACT_APP_API_URL
ENV REACT_APP_API_URL=$REACT_APP_API_URL
Enter fullscreen mode Exit fullscreen mode

While this method is effective for injecting environment variables into the Docker image, it has a significant drawback. The variables become hardcoded into the image. As a result, the same image cannot be reused across different environments (dev, staging, prod) without rebuilding it for each one. This leads to a lack of flexibility and increased complexity in your CI/CD pipeline.

The Solution: env-config.js

A more flexible approach involves using a JavaScript file, env-config.js, generated dynamically at runtime. This file is created using a bash script and loaded before your React application starts:

#!/bin/bash
echo "window._env_ = {" > /var/www/html/env-config.js
echo "  REACT_APP_API_URL: \"${REACT_APP_API_URL}\"" >> /var/www/html/env-config.js
echo "}" >> /var/www/html/env-config.js
Enter fullscreen mode Exit fullscreen mode

With this setup, the environment variables are not hardcoded into the Docker image. Instead, they are injected at runtime, allowing the same image to be used across multiple environments.

Integrating env-config.js with Docker

Here's how to configure the Dockerfile for this approach:

# Build stage for React app
FROM node:latest as build
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
RUN yarn install
COPY . ./
RUN yarn build

# Nginx stage
FROM nginx:alpine
COPY --from=build /app/build /var/www/html
COPY env-to-js.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/env-to-js.sh
CMD ["/bin/sh", "-c", "/usr/local/bin/env-to-js.sh && nginx -g 'daemon off;'"]
Enter fullscreen mode Exit fullscreen mode

This Dockerfile builds the React app and sets up Nginx to serve it. The critical addition is the env-to-js.sh script that generates env-config.js at container startup, injecting the current environment's variables.

Accessing Environment Variables in React

In your React application, access these variables from the global window object:

const apiUrl = window._env_.REACT_APP_API_URL || 'default-api-url';
Enter fullscreen mode Exit fullscreen mode

Security Considerations

It’s important to note that any information in env-config.js is publicly visible. Be cautious not to include sensitive data like private API keys, secrets etc. Treat env-config.js as a publicly accessible resource.

Conclusion: Enhanced Flexibility and Reusability

By adopting the env-config.js strategy in your Dockerized React application, you achieve significant flexibility. This approach allows you to use the same Docker image across various environments without the need for separate builds, simplifying your deployment process and enhancing maintainability.

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong · web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌶️🔥

Top comments (0)

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

👋 Kindness is contagious

If this post resonated with you, feel free to hit ❤️ or leave a quick comment to share your thoughts!

Okay