Skip to content

Commit 89ad87a

Browse files
authored
Make twenty-front build env agnostic (#20055)
## Introduction In aim to reduce and optimize the number of twenty-front build we do during our cd process and allow twenty-front build promotion ### Build time **Nothing is baked.** The `build/` directory is a clean, env-agnostic artifact. `index.html` contains the empty placeholder: ```html <script id="twenty-env-config"> window._env_ = { // This will be overwritten }; </script> ``` The JS bundles contain no hardcoded server URL. --- ### Deploy mode 1: Frontend served by the backend (Docker / NestJS) 1. Container starts, NestJS boots in `main.ts` 2. `generateFrontConfig()` runs, reads `process.env.SERVER_URL` 3. Rewrites `dist/front/index.html`, replacing the placeholder with: ```html <script id="twenty-env-config"> window._env_ = { REACT_APP_SERVER_BASE_URL: "https://api.example.com" }; </script> ``` 4. NestJS serves the static `dist/front/` directory 5. Browser loads `index.html`, `window._env_` is set before the app JS executes 6. `src/config/index.ts` reads `window._env_.REACT_APP_SERVER_BASE_URL` and uses it --- ### Deploy mode 2: Frontend served standalone (CDN / nginx / static server) 1. Take the `build/` artifact as-is 2. Before serving, run at deploy time: ```bash REACT_APP_SERVER_BASE_URL=https://api.example.com sh ./scripts/inject-runtime-env.sh ``` 3. This does the same `sed` replacement on `build/index.html` 4. Serve the `build/` directory with your static server of choice 5. Same resolution in the browser: `window._env_.REACT_APP_SERVER_BASE_URL` is picked up by `src/config/index.ts` --- ### Fallback: no injection at all If neither mechanism runs (e.g. local dev with `vite dev`), `window._env_.REACT_APP_SERVER_BASE_URL` is `undefined`, and `getDefaultUrl()` kicks in: - **Localhost**: returns `http://localhost:3000` - **Non-localhost**: returns same-origin (`window.location.origin`)
1 parent 0c5c9c8 commit 89ad87a

7 files changed

Lines changed: 14 additions & 19 deletions

File tree

packages/twenty-docker/twenty/Dockerfile

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ RUN yarn workspaces focus --production twenty-emails twenty-shared twenty-sdk tw
4949

5050
FROM common-deps AS twenty-front-build
5151

52-
ARG REACT_APP_SERVER_BASE_URL
53-
5452
COPY ./packages/twenty-front /app/packages/twenty-front
5553
COPY ./packages/twenty-front-component-renderer /app/packages/twenty-front-component-renderer
5654
COPY ./packages/twenty-ui /app/packages/twenty-ui
@@ -138,9 +136,6 @@ USER 1000
138136

139137
FROM twenty-server AS twenty
140138

141-
ARG REACT_APP_SERVER_BASE_URL
142-
ENV REACT_APP_SERVER_BASE_URL=$REACT_APP_SERVER_BASE_URL
143-
144139
COPY --chown=1000 --from=twenty-front-build /app/packages/twenty-front/build /app/packages/twenty-server/dist/front
145140

146141
LABEL org.opencontainers.image.description="Twenty image with backend and frontend."
@@ -232,7 +227,6 @@ RUN mkdir -p /data/postgres /data/redis /app/packages/twenty-server/.local-stora
232227
&& chown -R postgres:postgres /data/postgres \
233228
&& chown 1000:1000 /data/redis /app/packages/twenty-server/.local-storage
234229

235-
ARG REACT_APP_SERVER_BASE_URL
236230
ARG APP_VERSION=0.0.0
237231

238232
ENV S6_KEEP_ENV=1
@@ -241,7 +235,6 @@ ENV PG_DATABASE_URL=postgres://twenty:twenty@localhost:5432/default \
241235
REDIS_URL=redis://localhost:6379 \
242236
STORAGE_TYPE=local \
243237
APP_SECRET=twenty-app-dev-secret-not-for-production \
244-
REACT_APP_SERVER_BASE_URL=$REACT_APP_SERVER_BASE_URL \
245238
APP_VERSION=$APP_VERSION \
246239
NODE_ENV=development \
247240
NODE_PORT=2020 \

packages/twenty-front/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"private": true,
44
"type": "module",
55
"scripts": {
6-
"build": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 npx vite build && sh ./scripts/inject-runtime-env.sh",
7-
"build:sourcemaps": "NODE_ENV=production VITE_BUILD_SOURCEMAP=true NODE_OPTIONS=--max-old-space-size=8192 npx vite build && sh ./scripts/inject-runtime-env.sh",
6+
"build": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 npx vite build",
7+
"build:sourcemaps": "NODE_ENV=production VITE_BUILD_SOURCEMAP=true NODE_OPTIONS=--max-old-space-size=8192 npx vite build",
88
"start:prod": "NODE_ENV=production npx serve -s build",
99
"tsup": "npx tsup"
1010
},

packages/twenty-front/scripts/inject-runtime-env.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/bin/sh
22

3+
if [ -z "$REACT_APP_SERVER_BASE_URL" ]; then
4+
echo "Error: REACT_APP_SERVER_BASE_URL is not set."
5+
exit 1
6+
fi
7+
38
echo "Injecting runtime environment variables into index.html..."
49

510
CONFIG_BLOCK=$(cat << EOF

packages/twenty-front/src/config/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,4 @@ const getDefaultUrl = () => {
1818
};
1919

2020
export const REACT_APP_SERVER_BASE_URL =
21-
window._env_?.REACT_APP_SERVER_BASE_URL ||
22-
process.env.REACT_APP_SERVER_BASE_URL ||
23-
getDefaultUrl();
21+
window._env_?.REACT_APP_SERVER_BASE_URL || getDefaultUrl();
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
22

3+
import { REACT_APP_SERVER_BASE_URL } from '~/config';
4+
35
export const mockedApolloClient = new ApolloClient({
46
link: new HttpLink({
5-
uri: process.env.REACT_APP_SERVER_BASE_URL + '/metadata',
7+
uri: REACT_APP_SERVER_BASE_URL + '/metadata',
68
}),
79
cache: new InMemoryCache(),
810
});
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
22

3+
import { REACT_APP_SERVER_BASE_URL } from '~/config';
4+
35
export const mockedApolloCoreClient = new ApolloClient({
46
link: new HttpLink({
5-
uri: process.env.REACT_APP_SERVER_BASE_URL + '/graphql',
7+
uri: REACT_APP_SERVER_BASE_URL + '/graphql',
68
}),
79
cache: new InMemoryCache(),
810
});

packages/twenty-front/vite.config.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export default defineConfig(({ mode }) => {
2020
const env = loadEnv(mode, __dirname, '');
2121

2222
const {
23-
REACT_APP_SERVER_BASE_URL,
2423
VITE_BUILD_SOURCEMAP,
2524
VITE_HOST,
2625
SSL_CERT_PATH,
@@ -232,11 +231,7 @@ export default defineConfig(({ mode }) => {
232231
envPrefix: 'REACT_APP_',
233232

234233
define: {
235-
_env_: {
236-
REACT_APP_SERVER_BASE_URL,
237-
},
238234
'process.env': {
239-
REACT_APP_SERVER_BASE_URL,
240235
IS_DEBUG_MODE,
241236
IS_DEV_ENV: mode === 'development' ? 'true' : 'false',
242237
},

0 commit comments

Comments
 (0)