Skip to content

Commit

Permalink
feat: add runtime publicpath and switch to nginx (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
kleyow authored Oct 8, 2021
1 parent 23cce5a commit 2d19a17
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ jobs:
name: Build Docker local image
command: |
echo "Building Docker image: local"
docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local . --build-arg REACT_APP_VERSION=`npm run version --silent` --build-arg REACT_APP_COMMIT=`git rev-parse HEAD` --build-arg PUBLIC_PATH=https://localhost:8080/
docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local . --build-arg REACT_APP_VERSION=`npm run version --silent` --build-arg REACT_APP_COMMIT=`git rev-parse HEAD`
- run:
name: Save docker image to workspace
Expand Down
45 changes: 27 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# First part, build the app
FROM node:16-alpine as reporting-hub-bop-role-ui-builder
LABEL stage=reporting-hub-bop-role-ui-builder
FROM node:lts-alpine as builder

COPY package.json .
COPY yarn.lock .
WORKDIR /opt/reporting-hub-bop-shell
ENV PATH /opt/reporting-hub-bop-shell/node_modules/.bin:$PATH

RUN apk add --no-cache -t build-dependencies git make gcc g++ python libtool autoconf automake \
&& cd $(npm root -g)/npm \
&& npm config set unsafe-perm true \
&& npm install -g node-gyp

COPY package.json /opt/reporting-hub-bop-shell/
COPY yarn.lock /opt/reporting-hub-bop-shell/

RUN yarn --frozen-lockfile

COPY ./ .
COPY ./ /opt/reporting-hub-bop-shell/

# Adds the package version and commit hash
ARG REACT_APP_NAME
Expand All @@ -19,25 +25,28 @@ ENV REACT_APP_VERSION=$REACT_APP_VERSION
ARG REACT_APP_COMMIT
ENV REACT_APP_COMMIT=$REACT_APP_COMMIT

# Public Path
# Public Path - Placeholder that is overwritten at runtime
ARG PUBLIC_PATH
ENV PUBLIC_PATH=$PUBLIC_PATH
ENV PUBLIC_PATH=__PUBLIC_PATH__

RUN yarn build

# Second part, create a config at boostrap via entrypoint and and serve it
FROM caddy/caddy:alpine
FROM nginx:1.16.0-alpine

# JQ is used to convert from JSON string to json file in bash
RUN apk add --no-cache jq

COPY --from=0 dist/ .
COPY docker/Caddyfile /srv/Caddyfile
COPY docker/entrypoint.sh /entrypoint.sh
COPY docker/loadRuntimeConfig.sh /loadRuntimeConfig.sh
COPY --from=builder /opt/reporting-hub-bop-shell/dist/ /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf /etc/nginx/nginx.conf
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY nginx/start.sh /usr/share/nginx/start.sh

COPY docker/entrypoint.sh /usr/share/nginx/html/entrypoint.sh
COPY docker/loadRuntimeConfig.sh /usr/share/nginx/html/loadRuntimeConfig.sh

RUN chmod +x /entrypoint.sh
RUN chmod +x /loadRuntimeConfig.sh
RUN chmod +x /usr/share/nginx/html/entrypoint.sh
RUN chmod +x /usr/share/nginx/html/loadRuntimeConfig.sh

# Provide environment variables for setting endpoints dynamically
ARG REACT_APP_API_BASE_URL
Expand All @@ -46,11 +55,11 @@ ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
ARG REACT_APP_MOCK_API
ENV REACT_APP_MOCK_API=$REACT_APP_MOCK_API

EXPOSE 8080
EXPOSE 8081

ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/usr/share/nginx/html/entrypoint.sh"]

CMD ["caddy", "run", "--watch"]
CMD ["sh", "/usr/share/nginx/start.sh"]
# TODO: Need to add 8080 to image-scan whitelist
# Need to switch user away from root
# Investigate Feed data unavailable, cannot perform CVE scan for distro: alpine:3.14.2
5 changes: 2 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ services:
context: .
cache_from:
- mojaloop/reporting-hub-bop-role-ui
args:
- PUBLIC_PATH=https://localhost:8081/
environment:
- PUBLIC_PATH=http://localhost:8081/
- REACT_APP_API_BASE_URL=http://localhost:3008/
- REACT_APP_MOCK_API=false
ports:
- "8081:8080"
- "8081:8081"
networks:
- mojaloop-net
healthcheck:
Expand Down
5 changes: 0 additions & 5 deletions docker/Caddyfile

This file was deleted.

2 changes: 1 addition & 1 deletion docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

# Run the script before starting the server
sh /loadRuntimeConfig.sh
sh /usr/share/nginx/html/loadRuntimeConfig.sh

# This will exec the CMD from your Dockerfile, i.e. "npm start"
exec "$@"
8 changes: 6 additions & 2 deletions docker/loadRuntimeConfig.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash
sed -i 's#__REACT_APP_API_BASE_URL__#'"$REACT_APP_API_BASE_URL"'#g' runtime-env.js
sed -i 's#__REACT_APP_MOCK_API__#'"$REACT_APP_MOCK_API"'#g' runtime-env.js
sed -i 's#__REACT_APP_API_BASE_URL__#'"$REACT_APP_API_BASE_URL"'#g' /usr/share/nginx/html/runtime-env.js
sed -i 's#__REACT_APP_MOCK_API__#'"$REACT_APP_MOCK_API"'#g' /usr/share/nginx/html/runtime-env.js

sed -i 's#__PUBLIC_PATH__#'"$PUBLIC_PATH"'#g' /usr/share/nginx/html/index.html
sed -i 's#__PUBLIC_PATH__#'"$PUBLIC_PATH"'#g' /usr/share/nginx/html/main.js
sed -i 's#__PUBLIC_PATH__#'"$PUBLIC_PATH"'#g' /usr/share/nginx/html/app.js

exec "$@"
64 changes: 64 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# auto detects a good number of processes to run
worker_processes auto;

#Provides the configuration file context in which the directives that affect connection processing are specified.
events {
# Sets the maximum number of simultaneous connections that can be opened by a worker process.
worker_connections 8000;
# Tells the worker to accept multiple connections at a time
multi_accept on;
}


http {
# what times to include
include /etc/nginx/mime.types;
# what is the default one
default_type application/octet-stream;

# Sets the path, format, and configuration for a buffered log write
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $upstream_addr '
'"$http_referer" "$http_user_agent"';

server {
# listen on port 8081
listen 8081;

gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1000;

# where the root here
root /usr/share/nginx/html;
# what file to server as index
index index.html index.htm;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
try_files $uri $uri/ /index.html;
}

# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}

# Javascript and CSS files
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}

# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
}
}
1 change: 1 addition & 0 deletions nginx/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nginx -g "daemon off;"
3 changes: 1 addition & 2 deletions public/runtime-env.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// public/env.js
// https://medium.com/@hasniarif/how-to-handle-runtime-environment-variables-with-react-ec809cb07831
window.env = {
window.roleEnv = {
REACT_APP_API_BASE_URL: '__REACT_APP_API_BASE_URL__',
REACT_APP_MOCK_API: '__REACT_APP_MOCK_API__',
};
2 changes: 1 addition & 1 deletion src/types/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export {};
declare global {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Window {
env: {
roleEnv: {
REACT_APP_API_BASE_URL: string;
REACT_APP_MOCK_API: string;
};
Expand Down
4 changes: 2 additions & 2 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import buildApi, { buildEndpointBuilder, EndpointConfig } from '@modusbox/redux-
let baseUrl: string;
let mockApi: string;
if (process.env.NODE_ENV === 'production') {
baseUrl = window.env.REACT_APP_API_BASE_URL;
mockApi = window.env.REACT_APP_MOCK_API;
baseUrl = window.roleEnv.REACT_APP_API_BASE_URL;
mockApi = window.roleEnv.REACT_APP_MOCK_API;
} else if (process.env.REACT_APP_API_BASE_URL && process.env.REACT_APP_REMOTE_MOCK_API) {
baseUrl = process.env.REACT_APP_API_BASE_URL.replace(/\/$/, '');
mockApi = process.env.REACT_APP_REMOTE_MOCK_API;
Expand Down

0 comments on commit 2d19a17

Please sign in to comment.