diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-05 14:50:38 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-05 14:50:38 +0200 |
| commit | e8bb95cb35ed1b02a85cf7cbea5bfc20fe0324c2 (patch) | |
| tree | 1f3992d8045437774767556bf20d053b947ed164 | |
| parent | 3c805a50ca710e123aa18ad1bfa01ea4f1ee40d2 (diff) | |
build: Support runtime variables in frontend Docker image
This change adds support for dynamically specifying various variables
for the frontend Docker image through environmental variables.
Previously, these were embedded directly into the source code, which
requires rebuilding the entire image to change these variables.
| -rw-r--r-- | docker-compose.override.yml | 5 | ||||
| -rw-r--r-- | docker-compose.prod.yml | 5 | ||||
| -rw-r--r-- | docker-compose.yml | 6 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/Dockerfile | 17 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/public/index.html | 9 | ||||
| -rwxr-xr-x | opendc-web/opendc-web-ui/scripts/envsubst-html.sh | 19 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/api/routes/token-signin.js | 2 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/api/socket.js | 2 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/containers/auth/Login.js | 6 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/index.js | 5 |
10 files changed, 48 insertions, 28 deletions
diff --git a/docker-compose.override.yml b/docker-compose.override.yml index e48f4dff..172cc4cd 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -3,11 +3,10 @@ version: "3.8" # Docker Compose overrides for development environments services: frontend: - build: - args: - OPENDC_API_BASE_URL: http://localhost:8081 ports: - "8080:80" + environment: + API_BASE_URL: http://localhost:8081 api: ports: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 3cefdcdd..96bb004e 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -3,11 +3,10 @@ version: "3.8" # Docker Compose overrides for production environments services: frontend: - build: - args: - OPENDC_API_BASE_URL: ${OPENDC_API_BASE_URL} ports: - "8080:80" + environment: + API_BASE_URL: ${OPENDC_API_BASE_URL} api: ports: diff --git a/docker-compose.yml b/docker-compose.yml index 982f2ed8..30c00996 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,13 @@ services: frontend: build: context: opendc-web/opendc-web-ui - args: - OPENDC_OAUTH_CLIENT_ID: ${OPENDC_OAUTH_CLIENT_ID} - OPENDC_FRONTEND_SENTRY_DSN: ${OPENDC_FRONTEND_SENTRY_DSN} image: frontend restart: on-failure networks: - backend + environment: + OAUTH_CLIENT_ID: ${OPENDC_OAUTH_CLIENT_ID} + SENTRY_DSN: ${OPENDC_FRONTEND_SENTRY_DSN} api: build: opendc-web/opendc-web-api diff --git a/opendc-web/opendc-web-ui/Dockerfile b/opendc-web/opendc-web-ui/Dockerfile index 20e16b08..7aa3a7bf 100644 --- a/opendc-web/opendc-web-ui/Dockerfile +++ b/opendc-web/opendc-web-ui/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14 AS staging +FROM node:15 AS staging MAINTAINER OpenDC Maintainers <opendc@atlarge-research.com> # Copy package details @@ -6,21 +6,16 @@ COPY ./package.json ./yarn.lock /opendc/ RUN cd /opendc && yarn # Build frontend -FROM node:14 AS build - -ARG OPENDC_OAUTH_CLIENT_ID -ARG OPENDC_API_BASE_URL -ARG OPENDC_FRONTEND_SENTRY_DSN +FROM node:15 AS build COPY ./ /opendc COPY --from=staging /opendc/node_modules /opendc/node_modules RUN cd /opendc/ \ - && export REACT_APP_OAUTH_CLIENT_ID=$OPENDC_OAUTH_CLIENT_ID \ - && export REACT_APP_API_BASE_URL=$OPENDC_API_BASE_URL \ - && export REACT_APP_SENTRY_DSN=$OPENDC_FRONTEND_SENTRY_DSN \ - && yarn build + && yarn build \ + && mv build/index.html build/index.html.template # Setup nginx to serve the frontend -FROM nginx:1.19 +FROM nginx:1.20 +COPY --from=build /opendc/scripts/envsubst-html.sh /docker-entrypoint.d/00-envsubst-html.sh COPY --from=build /opendc/build /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf diff --git a/opendc-web/opendc-web-ui/public/index.html b/opendc-web/opendc-web-ui/public/index.html index 44a0d80f..da734797 100644 --- a/opendc-web/opendc-web-ui/public/index.html +++ b/opendc-web/opendc-web-ui/public/index.html @@ -33,7 +33,7 @@ <meta property="og:locale" content="en_US"> <!-- Google meta tags --> - <meta name="google-signin-client_id" content="%REACT_APP_OAUTH_CLIENT_ID%"> + <meta name="google-signin-client_id" content="$OAUTH_CLIENT_ID"> <meta name="google-site-verification" content="YIR4LkQTv6WmOdWv8MkeiUKni-0Yu3WHylLp4VvUMig"/> <!-- CDN dependencies --> @@ -52,6 +52,13 @@ gtag('js', new Date()) gtag('config', 'UA-84285092-3') </script> + <script> + window.$$env = { + API_BASE_URL: "$API_BASE_URL", + OAUTH_CLIENT_ID: "$OAUTH_CLIENT_ID", + SENTRY_DSN: "$SENTRY_DSN", + }; + </script> </head> <body> <noscript> diff --git a/opendc-web/opendc-web-ui/scripts/envsubst-html.sh b/opendc-web/opendc-web-ui/scripts/envsubst-html.sh new file mode 100755 index 00000000..8ca12e8a --- /dev/null +++ b/opendc-web/opendc-web-ui/scripts/envsubst-html.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +# We can use simple version of envsubst execution as +# envsubst < /usr/share/nginx/html/index.html.template > /usr/share/nginx/html/index.html +# but it replaces everything that looks like environment variable substitution +# so it affects `default values` approach. +# we need to replace only provided environment variables. + +auto_envsubst() { + template_path="/usr/share/nginx/html/index.html.template" + output_path="/usr/share/nginx/html/index.html" + defined_envs=$(printf '${%s} ' $(env | cut -d= -f1)) + envsubst "$defined_envs" < "$template_path" > "$output_path" +} + +auto_envsubst +exit 0 diff --git a/opendc-web/opendc-web-ui/src/api/routes/token-signin.js b/opendc-web/opendc-web-ui/src/api/routes/token-signin.js index d6cff570..e40127f2 100644 --- a/opendc-web/opendc-web-ui/src/api/routes/token-signin.js +++ b/opendc-web/opendc-web-ui/src/api/routes/token-signin.js @@ -1,5 +1,5 @@ export function performTokenSignIn(token) { - const apiUrl = process.env.REACT_APP_API_BASE_URL || '' + const apiUrl = window.$$env['API_BASE_URL'] || '' return fetch(`${apiUrl}/tokensignin`, { method: 'POST', diff --git a/opendc-web/opendc-web-ui/src/api/socket.js b/opendc-web/opendc-web-ui/src/api/socket.js index 1c432167..884c4152 100644 --- a/opendc-web/opendc-web-ui/src/api/socket.js +++ b/opendc-web/opendc-web-ui/src/api/socket.js @@ -7,7 +7,7 @@ const callbacks = {} export function setupSocketConnection(onConnect) { const apiUrl = - process.env.REACT_APP_API_BASE_URL || + window.$$env['API_BASE_URL'] || `${window.location.protocol}//${window.location.hostname}:${window.location.port}` socket = io.connect(apiUrl) diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js index 2f9726bf..9201c09a 100644 --- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -32,15 +32,15 @@ class LoginContainer extends React.Component { return ( <GoogleLogin - clientId={process.env.REACT_APP_OAUTH_CLIENT_ID} + clientId={window.$$env['OAUTH_CLIENT_ID']} onSuccess={this.onAuthResponse.bind(this)} onFailure={this.onAuthFailure.bind(this)} render={(renderProps) => ( <span onClick={renderProps.onClick} className="login btn btn-primary"> - <span className="fa fa-google" /> Login with Google + <span className="fa fa-google"/> Login with Google </span> )} - ></GoogleLogin> + /> ) } } diff --git a/opendc-web/opendc-web-ui/src/index.js b/opendc-web/opendc-web-ui/src/index.js index 3517147e..bddf0b0e 100644 --- a/opendc-web/opendc-web-ui/src/index.js +++ b/opendc-web/opendc-web-ui/src/index.js @@ -12,10 +12,11 @@ setupSocketConnection(() => { const store = configureStore() // Initialize Sentry if the user has configured a DSN - if (process.env.REACT_APP_SENTRY_DSN) { + const dsn = window.$$env['SENTRY_DSN'] + if (dsn) { Sentry.init({ environment: process.env.NODE_ENV, - dsn: process.env.REACT_APP_SENTRY_DSN, + dsn: dsn, integrations: [new Integrations.BrowserTracing()], tracesSampleRate: 0.1, }) |
