Skip to content

Instantly share code, notes, and snippets.

@FilBot3
Last active June 15, 2022 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FilBot3/6caacf4372fcafbaa4a3a294f46b608a to your computer and use it in GitHub Desktop.
Save FilBot3/6caacf4372fcafbaa4a3a294f46b608a to your computer and use it in GitHub Desktop.
Replace variables in Angular or React apps upon startup.

Replace variables in Angular or React upon startup

Overview

The following script is useful for when you want to include variables in your React or Angular web app, but don't want 2 or more container images in your container registry.

Usage

First, you'll need some environment variables. Here are some examples:

export inject_arg_REACT_APP_VARIABLE_ONE=value1

Then you'll need to make sure your values for your .env files are setup like

internal_react_var = inject_arg_REACT_APP_VARIABLE_ONE

When your Angular or React app then transpiles the code, all the variables are replaced with the inject_arg_* string. This is where the following script comes into play. It will scan your source code looking for any inject_arg_* string, make an array/list of them, and then find all .js files and replace that string with the environment variable matching that string with the value.

#!/usr/bin/env bash

#set -x
set -e

cp --recursive /app/* /usr/share/nginx/html

# Get an array/list of the inject_arg_ variables found.
vars=( $(grep -h -o "inject_arg_[a-zA-Z_0-9-]\+" $(find /usr/share/nginx/html -type f -name "*.js") | sort -u ) )
for var in "${vars[@]}"
do
  echo "Found: ${var}"
done

for js_file in $(find /usr/share/nginx/html -type f -name "*.js")
do
  echo "Replacing ${var} in: ${js_file}"

  for var in "${vars[@]}"
  do
    sed --in-place --expression="s|${var}|$(printenv ${var})|g" ${js_file}
  done
done

#starting nginx
nginx -g 'daemon off;'

You'll see there's a cp command. This is used becasue when we deploy this, our filesystems are set to read-only, and we mount an emptyDir into the /usr/share/nginx/html directory, then we copy the app contents to that folder and replace it.

#!/usr/bin/env bash
#set -x
set -e
cp --recursive /app/* /usr/share/nginx/html
# Get an array/list of the inject_arg_ variables found.
vars=( $(grep -h -o "inject_arg_[a-zA-Z_0-9-]\+" $(find /usr/share/nginx/html -type f -name "*.js") | sort -u ) )
for var in "${vars[@]}"
do
echo "Found: ${var}"
done
for js_file in $(find /usr/share/nginx/html -type f -name "*.js")
do
echo "Replacing ${var} in: ${js_file}"
for var in "${vars[@]}"
do
sed --in-place --expression="s|${var}|$(printenv ${var})|g" ${js_file}
done
done
#starting nginx
nginx -g 'daemon off;'
# Build Argument for the FROM statements.
# Thse are above the FROM statements because they're used with the FROM
# statements. If the ARG is going to be used with normal RUN statements, put it
# after the FROM statement they're used in.
ARG NODE_VERSION=16
ARG NGINX_VERSION=1.21.6
# Multi-Stage Build Stage 1
# Pull official base image for NodeJS
FROM docker.io/library/node:${NODE_VERSION} as build
# Set working directory
WORKDIR /app
# Add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# Install app dependencies and build.
COPY . .
RUN ls -l /app
# Install the project dependencies, then install react-scripts.
# THEN build the files for React to be run in an Nginx container.
RUN npm install
RUN npm run build:prod
# Multi-Stage Build Stage 2
# This is where we put the static files from React into Nginx to be served.
FROM docker.io/library/nginx:${NGINX_VERSION}
# Copy from our build stage into our final container image.
COPY --from=build /app/dist/ /app/
# Copy the container_entrypoint that will perform startup and run steps.
COPY containers/container_entrypoint.sh /container_entrypoint.sh
# You need to make the script executable.
RUN chmod +x /container_entrypoint.sh
# Provide an nginx config
COPY containers/nginx.conf /etc/nginx/nginx.conf
# This is what the container will execute without providing any arguments.
ENTRYPOINT ["/container_entrypoint.sh"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment