From e1408a41192706df678db9957634093a6c6f11c4 Mon Sep 17 00:00:00 2001 From: Terence Lim Date: Fri, 3 Jun 2022 16:19:40 +0800 Subject: [PATCH] Shift UI env variables to runtime config --- .dockerignore | 3 - Dockerfile | 57 ++++++------ docker-entrypoint.sh | 69 ++++++++++++++ ui/package.json | 3 +- ui/public/app.config.js | 41 +++++++++ ui/public/index.html | 5 ++ ui/src/App.js | 79 ++++++++-------- ui/src/Home.js | 28 +++--- ui/src/PrivateLayout.js | 3 +- ui/src/bootstrap.js | 26 ++++-- ui/src/components/page/PageTitle.js | 4 +- ui/src/config.js | 30 ++++++- ui/src/experiments/ExperimentsLandingPage.js | 89 ++++++++++--------- .../configuration/GeneralInfoConfigSection.js | 3 +- .../general_config/ScheduleConfigPanel.js | 3 +- .../history/ListExperimentHistoryTable.js | 3 +- .../history/ListExperimentHistoryView.js | 3 +- .../experiments/list/ListExperimentsTable.js | 3 +- .../experiments/list/ListExperimentsView.js | 3 +- .../search/components/ExperimentDateFilter.js | 3 +- ui/src/hooks/useXpApi.js | 3 +- .../history/ListSegmentHistoryView.js | 3 +- ui/src/segments/list/ListSegmentsView.js | 3 +- .../history/ListTreatmentHistoryView.js | 3 +- ui/src/treatments/list/ListTreatmentsView.js | 3 +- .../ExperimentsConfigGroup.js | 5 +- ui/yarn.lock | 5 ++ 27 files changed, 333 insertions(+), 150 deletions(-) create mode 100755 docker-entrypoint.sh create mode 100644 ui/public/app.config.js diff --git a/.dockerignore b/.dockerignore index 084e0a95..a8ba48e4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,2 @@ # Management Service API ./management-service/bin - -# XP UI -./ui/build diff --git a/Dockerfile b/Dockerfile index 45512c65..63375295 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # Build xp-management binary FROM golang:1.16-alpine as api-builder -ARG API_BIN_NAME +ARG API_BIN_NAME=xp-management ENV GOOS=linux GOARCH=amd64 @@ -12,41 +12,40 @@ RUN chmod +x ./bin/${API_BIN_NAME} COPY ./api/*.yaml ./bin/ -# Build optimized static xp-ui bundle -FROM node:16 as ui-builder - -ARG REACT_APP_ENVIRONMENT -ARG REACT_APP_XP_API="/v1" -ARG REACT_APP_MLP_API -ARG REACT_APP_OAUTH_CLIENT_ID -ARG REACT_APP_SENTRY_DSN -ARG REACT_APP_USER_DOCS_URL - -RUN mkdir -p /opt/xp_ui -COPY ./ui /opt/xp_ui -WORKDIR /opt/xp_ui - -ENV NODE_OPTIONS "--max_old_space_size=4096" - -RUN yarn install --network-concurrency 1 -RUN yarn build - # Clean image with xp-management binary and production build of xp-ui FROM alpine:latest -ARG API_BIN_NAME -ENV API_BIN_NAME ${API_BIN_NAME} -ENV XP_UI_APP_DIRECTORY "./xp-ui" +# Install bash +USER root +RUN apk add --no-cache bash + +ARG API_BIN_NAME=xp-management +ARG XP_UI_DIST_PATH=ui/build + +ENV XPUICONFIG_SERVINGDIRECTORY "/app/xp-ui" ENV XP_PORT "8080" +ENV XP_USER "xp" +ENV XP_USER_GROUP "app" EXPOSE ${XP_PORT} -RUN addgroup -S app && adduser -S app -G app -USER app +RUN addgroup -S ${XP_USER_GROUP} \ + && adduser -S ${XP_USER} -G ${XP_USER_GROUP} -H \ + && mkdir /app \ + && chown -R ${XP_USER}:${XP_USER_GROUP} /app + +COPY --chown=${XP_USER}:${XP_USER_GROUP} --from=api-builder /app/bin/* /app/ +COPY --chown=${XP_USER}:${XP_USER_GROUP} --from=api-builder /app/database /app/database/ + +USER ${XP_USER} WORKDIR /app -COPY --from=api-builder /app/bin/* ./ -COPY --from=api-builder /app/database ./database -COPY --from=ui-builder /opt/xp_ui/build ${XP_UI_APP_DIRECTORY}/ +# UI must be built outside docker +COPY --chown=${XP_USER}:${XP_USER_GROUP} ${XP_UI_DIST_PATH} ${XPUICONFIG_SERVINGDIRECTORY}/ + +COPY ./docker-entrypoint.sh ./ + +ENV XP_API_BIN "./${API_BIN_NAME}" +ENV XP_UI_DIST_DIR ${XPUICONFIG_SERVINGDIRECTORY} -ENTRYPOINT [ "./xp-management" ] +ENTRYPOINT [ "./docker-entrypoint.sh" ] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 00000000..230af237 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +CMD=() +XP_UI_CONFIG_PATH= +XP_UI_DIST_DIR=${XP_UI_DIST_DIR:-} +XP_UI_DIST_CONFIG_FILE=${XP_UI_DIST_DIR}/app.config.js +XP_API_BIN=${XP_API_BIN:?"ERROR: XP_API_BIN is not specified"} + +show_help() { + cat < <...> + -ui-config JSON file containing configuration of XP UI +EOF +} + +main(){ + parse_command_line "$@" + + if [[ -n "$XP_UI_CONFIG_PATH" ]]; then + echo "XP UI config found at ${XP_UI_CONFIG_PATH}..." + if [[ -n "$XP_UI_DIST_DIR" ]]; then + echo "Overriding UI config at $XP_UI_DIST_CONFIG_FILE" + + echo "var xpConfig = $(cat $XP_UI_CONFIG_PATH);" > "$XP_UI_DIST_CONFIG_FILE" + + echo "Done." + else + echo "XP_UI_DIST_DIR: XP UI static build directory not provided. Skipping." + fi + else + echo "XP UI config is not provided. Skipping." + fi +} + +parse_command_line(){ + while [[ $# -gt 0 ]]; do + case "$1" in + -ui-config) + if [[ -n "$2" ]]; then + XP_UI_CONFIG_PATH="$2" + shift + else + echo "ERROR: '-ui-config' cannot be empty." >&2 + show_help + exit 1 + fi + ;; + *) + CMD+=("$1") + ;; + esac + + shift + done + + if [[ -n "$XP_UI_CONFIG_PATH" ]]; then + if [ ! -f "$XP_UI_CONFIG_PATH" ]; then + echo "ERROR: config file $XP_UI_CONFIG_PATH does not exist." >&2 + show_help + exit 1 + fi + fi +} + +main "$@" + +echo "Launching xp-api server: " "$XP_API_BIN" "${CMD[@]}" +exec "$XP_API_BIN" "${CMD[@]}" diff --git a/ui/package.json b/ui/package.json index f37cdbbe..424fd61d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -12,6 +12,7 @@ "json-bigint": "1.0.0", "lint-staged": "^11.1.2", "moment": "^2.29.0", + "object-assign-deep": "^0.4.0", "react": "16.14.0", "react-dom": "16.14.0", "resize-observer-polyfill": "^1.5.1", @@ -70,4 +71,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/ui/public/app.config.js b/ui/public/app.config.js new file mode 100644 index 00000000..654b60a4 --- /dev/null +++ b/ui/public/app.config.js @@ -0,0 +1,41 @@ +var xpConfig = { + "apiConfig": { + /* + * Timeout (in milliseconds) for requests to API + * "apiTimeout": 10000, + * + * Endpoint to XP API + * "xpApiUrl": "/api/xp/v1", + * + * Endpoint to MLP API + * "mlpApiUrl": "/api/v1" + */ + }, + + "authConfig": { + /* + * OAuth2 Client ID + * "oauthClientId": "CLIENT_ID" + */ + }, + + "appConfig": { + /* + * Environment name + * "environment": "dev", + * + * Default page for documentation + * "docsUrl": "https://github.com/gojek/xp" + */ + }, + + "sentryConfig": { + /* + * DSN of Sentry project + * "dsn": "SENTRY_DSN", + * + * Sentry environment (if it's different from appConfig.environment) + * "environment": "dev" + */ + } +}; diff --git a/ui/public/index.html b/ui/public/index.html index a441aa95..c7d7e252 100644 --- a/ui/public/index.html +++ b/ui/public/index.html @@ -8,6 +8,11 @@ + +