mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-25 01:04:58 +03:00
feat: merge front and server dockerfiles and optimize build (#4589)
* feat: merge front and server dockerfiles and optimize build * fix: update image label * fix: bring back support for REACT_APP_SERVER_BASE_URL injection at runtime * fix: remove old entries & add nx cache in dockerignore * feat: generate frontend config at runtime using Nest * fix: format and filename * feat: use the EnvironmentService and leave default blank * feat: add support for DB migrations
This commit is contained in:
parent
3fa8c4bace
commit
1aa48d3bf7
@ -1,2 +1,4 @@
|
|||||||
server/node_modules/
|
.git
|
||||||
server/.env
|
.env
|
||||||
|
node_modules
|
||||||
|
.nx/cache
|
||||||
|
@ -29,6 +29,12 @@ prod-docs-build:
|
|||||||
prod-docs-run:
|
prod-docs-run:
|
||||||
@docker run -d -p 3000:3000 --name twenty-docs twenty-docs
|
@docker run -d -p 3000:3000 --name twenty-docs twenty-docs
|
||||||
|
|
||||||
|
prod-build:
|
||||||
|
@cd ../.. && docker build -f ./packages/twenty-docker/prod/twenty/Dockerfile --tag twenty . && cd -
|
||||||
|
|
||||||
|
prod-run:
|
||||||
|
@docker run -d -p 3000:3000 --name twenty twenty
|
||||||
|
|
||||||
prod-front-build:
|
prod-front-build:
|
||||||
@cd ../.. && docker build -f ./packages/twenty-docker/prod/twenty-front/Dockerfile --tag twenty-front . && cd -
|
@cd ../.. && docker build -f ./packages/twenty-docker/prod/twenty-front/Dockerfile --tag twenty-front . && cd -
|
||||||
|
|
||||||
|
77
packages/twenty-docker/prod/twenty/Dockerfile
Normal file
77
packages/twenty-docker/prod/twenty/Dockerfile
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Base image for common dependencies
|
||||||
|
FROM node:18.17.1-alpine as common-deps
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy only the necessary files for dependency resolution
|
||||||
|
COPY ./package.json ./yarn.lock ./.yarnrc.yml ./tsconfig.base.json ./nx.json /app/
|
||||||
|
COPY ./.yarn/releases /app/.yarn/releases
|
||||||
|
|
||||||
|
COPY ./packages/twenty-emails/package.json /app/packages/twenty-emails/
|
||||||
|
COPY ./packages/twenty-server/package.json /app/packages/twenty-server/
|
||||||
|
COPY ./packages/twenty-server/patches /app/packages/twenty-server/patches
|
||||||
|
COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/
|
||||||
|
COPY ./packages/twenty-front/package.json /app/packages/twenty-front/
|
||||||
|
|
||||||
|
# Install all dependencies
|
||||||
|
RUN yarn && yarn cache clean && npx nx reset
|
||||||
|
|
||||||
|
|
||||||
|
# Build the back
|
||||||
|
FROM common-deps as twenty-server-build
|
||||||
|
|
||||||
|
# Copy sourcecode after installing dependences to accelerate subsequents builds
|
||||||
|
COPY ./packages/twenty-emails /app/packages/twenty-emails
|
||||||
|
COPY ./packages/twenty-server /app/packages/twenty-server
|
||||||
|
|
||||||
|
RUN npx nx run twenty-server:build && \
|
||||||
|
mv /app/packages/twenty-server/dist /app/packages/twenty-server/build && \
|
||||||
|
npx nx run twenty-server:build:packageJson && \
|
||||||
|
mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json && \
|
||||||
|
rm -rf /app/packages/twenty-server/dist && \
|
||||||
|
mv /app/packages/twenty-server/build /app/packages/twenty-server/dist
|
||||||
|
|
||||||
|
RUN yarn workspaces focus --production twenty-emails twenty-server
|
||||||
|
|
||||||
|
|
||||||
|
# Build the front
|
||||||
|
FROM common-deps as twenty-front-build
|
||||||
|
|
||||||
|
ARG REACT_APP_SERVER_BASE_URL
|
||||||
|
|
||||||
|
COPY ./packages/twenty-front /app/packages/twenty-front
|
||||||
|
COPY ./packages/twenty-ui /app/packages/twenty-ui
|
||||||
|
RUN yarn nx build twenty-front
|
||||||
|
|
||||||
|
|
||||||
|
# Final stage: Run the application
|
||||||
|
FROM node:18.17.1-alpine as twenty
|
||||||
|
|
||||||
|
# Used to run healthcheck in docker
|
||||||
|
RUN apk add --no-cache curl jq
|
||||||
|
|
||||||
|
COPY ./packages/twenty-docker/prod/twenty/entrypoint.sh /app/entrypoint.sh
|
||||||
|
RUN chmod +x /app/entrypoint.sh
|
||||||
|
|
||||||
|
WORKDIR /app/packages/twenty-server
|
||||||
|
|
||||||
|
ARG REACT_APP_SERVER_BASE_URL
|
||||||
|
ENV REACT_APP_SERVER_BASE_URL $REACT_APP_SERVER_BASE_URL
|
||||||
|
|
||||||
|
# Copy built applications from previous stages
|
||||||
|
COPY --chown=1000 --from=twenty-server-build /app /app
|
||||||
|
COPY --chown=1000 --from=twenty-server-build /app/packages/twenty-server /app/packages/twenty-server
|
||||||
|
COPY --chown=1000 --from=twenty-front-build /app/packages/twenty-front/build /app/packages/twenty-server/dist/front
|
||||||
|
|
||||||
|
# Set metadata and labels
|
||||||
|
LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty
|
||||||
|
LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the backend and frontend, ensuring it deploys faster and runs the same way regardless of the deployment environment."
|
||||||
|
|
||||||
|
RUN mkdir /app/.local-storage
|
||||||
|
RUN chown -R 1000 /app
|
||||||
|
|
||||||
|
# Use non root user with uid 1000
|
||||||
|
USER 1000
|
||||||
|
|
||||||
|
CMD ["node", "dist/src/main"]
|
||||||
|
ENTRYPOINT ["/app/entrypoint.sh"]
|
17
packages/twenty-docker/prod/twenty/entrypoint.sh
Executable file
17
packages/twenty-docker/prod/twenty/entrypoint.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Check if the initialization has already been done and that we enabled automatic migration
|
||||||
|
if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/${STORAGE_LOCAL_PATH}/db_initialized ]; then
|
||||||
|
echo "Running database setup and migrations..."
|
||||||
|
|
||||||
|
# Run setup and migration scripts
|
||||||
|
npx ts-node ./scripts/setup-db.ts
|
||||||
|
yarn database:migrate:prod
|
||||||
|
|
||||||
|
# Mark initialization as done
|
||||||
|
echo "Successfuly migrated DB!"
|
||||||
|
touch /app/${STORAGE_LOCAL_PATH}/db_initialized
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Continue with the original Docker command
|
||||||
|
exec "$@"
|
@ -41,3 +41,7 @@ This should work out of the box with the eslint extension installed. If this doe
|
|||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docker container build
|
||||||
|
|
||||||
|
To successfully build Docker images, ensure that your system has a minimum of 2GB of memory available. For users of Docker Desktop, please verify that you've allocated sufficient resources to Docker within the application's settings.
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
"graphql-middleware": "^6.1.35",
|
"graphql-middleware": "^6.1.35",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"passport": "^0.7.0",
|
"passport": "^0.7.0",
|
||||||
"psl": "^1.9.0"
|
"psl": "^1.9.0",
|
||||||
|
"tsconfig-paths": "^4.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "10.3.0",
|
"@nestjs/cli": "10.3.0",
|
||||||
|
@ -11,6 +11,7 @@ import '@sentry/tracing';
|
|||||||
|
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
import { generateFrontConfig } from './utils/generate-front-config';
|
||||||
import { settings } from './engine/constants/settings';
|
import { settings } from './engine/constants/settings';
|
||||||
import { LoggerService } from './engine/integrations/logger/logger.service';
|
import { LoggerService } from './engine/integrations/logger/logger.service';
|
||||||
import { EnvironmentService } from './engine/integrations/environment/environment.service';
|
import { EnvironmentService } from './engine/integrations/environment/environment.service';
|
||||||
@ -60,6 +61,9 @@ const bootstrap = async () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Create the env-config.js of the front at runtime
|
||||||
|
generateFrontConfig();
|
||||||
|
|
||||||
await app.listen(app.get(EnvironmentService).get('PORT'));
|
await app.listen(app.get(EnvironmentService).get('PORT'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
31
packages/twenty-server/src/utils/generate-front-config.ts
Normal file
31
packages/twenty-server/src/utils/generate-front-config.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
|
||||||
|
const environmentService = new EnvironmentService(new ConfigService());
|
||||||
|
|
||||||
|
export function generateFrontConfig(): void {
|
||||||
|
const configObject = {
|
||||||
|
window: {
|
||||||
|
_env_: {
|
||||||
|
REACT_APP_SERVER_BASE_URL: environmentService.get('SERVER_URL'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const configString = `window._env_ = ${JSON.stringify(
|
||||||
|
configObject.window._env_,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
)};`;
|
||||||
|
|
||||||
|
const distPath = path.join(__dirname, '../..', 'front');
|
||||||
|
|
||||||
|
if (!fs.existsSync(distPath)) {
|
||||||
|
fs.mkdirSync(distPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(distPath, 'env-config.js'), configString, 'utf8');
|
||||||
|
}
|
@ -45763,6 +45763,7 @@ __metadata:
|
|||||||
passport: "npm:^0.7.0"
|
passport: "npm:^0.7.0"
|
||||||
psl: "npm:^1.9.0"
|
psl: "npm:^1.9.0"
|
||||||
rimraf: "npm:^5.0.5"
|
rimraf: "npm:^5.0.5"
|
||||||
|
tsconfig-paths: "npm:^4.2.0"
|
||||||
typescript: "npm:^5.3.3"
|
typescript: "npm:^5.3.3"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
Loading…
Reference in New Issue
Block a user