diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e47a6d..9b8be2e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 command: docker save -o /tmp/docker-image.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:local diff --git a/Dockerfile b/Dockerfile index 8e55253..24bfad1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,18 @@ -# First part, build the app -FROM node:lts-alpine as reporting-hub-bop-shell-builder -LABEL stage=reporting-hub-bop-shell-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_VERSION @@ -16,29 +21,32 @@ 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/createJSONConfig.sh /createJSONConfig.sh -COPY docker/createRemoteConfig.sh /createRemoteConfig.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/createJSONConfig.sh /usr/share/nginx/html/createJSONConfig.sh +COPY docker/createRemoteConfig.sh /usr/share/nginx/html/createRemoteConfig.sh +COPY docker/loadRuntimeConfig.sh /usr/share/nginx/html/loadRuntimeConfig.sh -RUN chmod +x /entrypoint.sh -RUN chmod +x /createJSONConfig.sh -RUN chmod +x /createRemoteConfig.sh -RUN chmod +x /loadRuntimeConfig.sh +RUN chmod +x /usr/share/nginx/html/entrypoint.sh +RUN chmod +x /usr/share/nginx/html/createJSONConfig.sh +RUN chmod +x /usr/share/nginx/html/createRemoteConfig.sh +RUN chmod +x /usr/share/nginx/html/loadRuntimeConfig.sh # Provide environment variables for setting endpoints dynamically ARG REMOTE_API_BASE_URL @@ -70,9 +78,9 @@ ENV REMOTE_2_URL=$REMOTE_2_URL EXPOSE 8080 -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 diff --git a/docker-compose.yaml b/docker-compose.yaml index dd93de3..edbbf94 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,9 +12,8 @@ services: context: . cache_from: - mojaloop/reporting-hub-bop-shell - args: - - PUBLIC_PATH=https://localhost:8080/ environment: + - PUBLIC_PATH=http://localhost:8080/ - AUTH_API_BASE_URL=/ - AUTH_MOCK_API=true - REMOTE_API_BASE_URL=/ @@ -22,8 +21,8 @@ services: - LOGIN_URL=https://your-login-url - LOGOUT_URL=https://your-logout-url - AUTH_ENABLED=true - - REMOTE_1_URL=https://localhost:8081 - - REMOTE_2_URL=https://localhost:8082 + - REMOTE_1_URL=http://localhost:8081 + - REMOTE_2_URL=http://localhost:8082 ports: - "8080:8080" networks: diff --git a/docker/Caddyfile b/docker/Caddyfile deleted file mode 100644 index 451b60b..0000000 --- a/docker/Caddyfile +++ /dev/null @@ -1,5 +0,0 @@ -localhost:8080 - -encode zstd gzip -try_files {path} /index.html -file_server \ No newline at end of file diff --git a/docker/createJSONConfig.sh b/docker/createJSONConfig.sh index 60ca3dc..91ad096 100644 --- a/docker/createJSONConfig.sh +++ b/docker/createJSONConfig.sh @@ -9,7 +9,7 @@ echo "{ \"AUTH_ENABLED\": \"${AUTH_ENABLED}\", \"LOGIN_URL\": \"${LOGIN_URL}\", \"LOGOUT_URL\": \"${LOGOUT_URL}\" -}" | jq '.' > config.json +}" | jq '.' > /usr/share/nginx/html/config.json # This will exec the CMD from your Dockerfile, i.e. "npm start" exec "$@" diff --git a/docker/createRemoteConfig.sh b/docker/createRemoteConfig.sh index 1f4c5a0..fba4770 100644 --- a/docker/createRemoteConfig.sh +++ b/docker/createRemoteConfig.sh @@ -18,7 +18,7 @@ echo "[ \"url\": \"${REMOTE_2_URL}/app.js\", \"appName\": \"reporting_hub_bop_trx_ui\" } -]" | jq '.' > remotes.json +]" | jq '.' > /usr/share/nginx/html/remotes.json # This will exec the CMD from your Dockerfile, i.e. "npm start" exec "$@" diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index ff95d93..20a7cf6 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,9 +1,9 @@ #!/bin/sh # Run the script before starting the server -sh /createJSONConfig.sh -sh /createRemoteConfig.sh -sh /loadRuntimeConfig.sh +sh /usr/share/nginx/html/createJSONConfig.sh +sh /usr/share/nginx/html/createRemoteConfig.sh +sh /usr/share/nginx/html/loadRuntimeConfig.sh # This will exec the CMD from your Dockerfile, i.e. "npm start" exec "$@" diff --git a/docker/loadRuntimeConfig.sh b/docker/loadRuntimeConfig.sh index 83e5310..2b02f3b 100644 --- a/docker/loadRuntimeConfig.sh +++ b/docker/loadRuntimeConfig.sh @@ -1,5 +1,12 @@ #!/bin/bash -sed -i 's#__REMOTE_1_URL__#'"$REMOTE_1_URL"'#g' runtime-env.js -sed -i 's#__REMOTE_1_URL__#'"$REMOTE_1_URL"'#g' index.html +sed -i 's#__REMOTE_1_URL__#'"$REMOTE_1_URL"'#g' /usr/share/nginx/html/runtime-env.js +sed -i 's#__REMOTE_1_URL__#'"$REMOTE_1_URL"'#g' /usr/share/nginx/html/index.html + +sed -i 's#__REMOTE_2_URL__#'"$REMOTE_2_URL"'#g' /usr/share/nginx/html/runtime-env.js +sed -i 's#__REMOTE_2_URL__#'"$REMOTE_2_URL"'#g' /usr/share/nginx/html/index.html + +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 exec "$@" + diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..240d2cd --- /dev/null +++ b/nginx/nginx.conf @@ -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 8080 + listen 8080; + + 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; + } + } +} diff --git a/nginx/start.sh b/nginx/start.sh new file mode 100644 index 0000000..b4dff01 --- /dev/null +++ b/nginx/start.sh @@ -0,0 +1 @@ +nginx -g "daemon off;" diff --git a/public/index.html b/public/index.html index 35010bc..6f862c2 100644 --- a/public/index.html +++ b/public/index.html @@ -4,6 +4,7 @@ +
diff --git a/public/runtime-env.js b/public/runtime-env.js index 5a57a13..701aa4c 100644 --- a/public/runtime-env.js +++ b/public/runtime-env.js @@ -1,5 +1,5 @@ -// public/env.js // https://medium.com/@hasniarif/how-to-handle-runtime-environment-variables-with-react-ec809cb07831 -window.env = { +window.shellEnv = { REMOTE_1_URL: '__REMOTE_1_URL__', + REMOTE_2_URL: '__REMOTE_2_URL__', };