diff --git a/.github/actions/build-docker/action.yml b/.github/actions/build-docker/action.yml index 8149f5817d1..32cec27d209 100644 --- a/.github/actions/build-docker/action.yml +++ b/.github/actions/build-docker/action.yml @@ -75,6 +75,16 @@ runs: set -o xtrace export DENO_VERSION="${{ inputs.deno-version }}" + # Removes unnecessary swc cores to reduce image sized + swc_arch='x64' + if [[ "${{ inputs.service }}" == 'rocketchat' ]]; then + if [[ "${{ inputs.arch }}" == 'arm64' ]]; then + swc_arch='arm64' + fi + + find /tmp/build/bundle/programs/server/npm/node_modules/meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc -type d -name 'core-*' -not -name "*linux-${swc_arch}-gnu*" -exec rm -rf {} + + fi + if [[ "${{ inputs.publish-image }}" == 'true' ]]; then LOAD_OR_PUSH="--push" else diff --git a/.github/actions/meteor-build/action.yml b/.github/actions/meteor-build/action.yml index e9d67580231..934e51bc2ff 100644 --- a/.github/actions/meteor-build/action.yml +++ b/.github/actions/meteor-build/action.yml @@ -42,6 +42,15 @@ runs: with: swap-size-gb: 4 + - name: Merge dependencies for build + shell: bash + if: steps.cache-build.outputs.cache-hit != 'true' + run: | + # Merge dependencies and devDependencies into a new 'dependencies' field + cd apps/meteor + cp package.json package.json.bak + jq '.dependencies = (.dependencies + .devDependencies) | del(.devDependencies)' package.json > package.json.tmp && mv package.json.tmp package.json + - name: Setup NodeJS uses: ./.github/actions/setup-node if: steps.cache-build.outputs.cache-hit != 'true' @@ -50,6 +59,7 @@ runs: deno-version: ${{ inputs.deno-version }} cache-modules: true install: true + type: 'production' NPM_TOKEN: ${{ inputs.NPM_TOKEN }} # - name: Free disk space @@ -150,12 +160,41 @@ runs: echo "Coverage enabled" fi + # Restore original package.json so meteor should not copy devDependencies + mv apps/meteor/package.json.bak apps/meteor/package.json + yarn build:ci - - name: Translation check - shell: bash - if: steps.cache-build.outputs.cache-hit != 'true' - run: yarn turbo run translation-check + declare -a meter_modules_to_remove=( + "meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-darwin-arm64" # Removes 35M + "meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-x64-musl" # Removes 58M + "meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-arm64-musl" # Removes 44M + "meteor/babel-compiler/node_modules/typescript" # Removes 31M + "meteor/babel-compiler/node_modules/@babel" # Removes 14M + + "@rocket.chat/i18n/src" # Removes 16M + "typescript" # Removes 19M + # "@babel" # Removes 34M - Needed by Minimongo + ) + + du -s /tmp/dist/bundle + + for dir_path in "${meter_modules_to_remove[@]}"; do + path=/tmp/dist/bundle/programs/server/npm/node_modules/${dir_path} + + if [ -d "$path" ]; then + rm -rf "$path" + + echo "Removed directory: $path" + else + echo "Path is not a directory or does not exist: $path" + fi + done + + # Remove all .d.ts files from node_modules to reduce size + # Removes 184M + find /tmp/dist/bundle -type f -name "*.d.ts" -delete + du -s /tmp/dist/bundle - name: Prepare build shell: bash diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index 7d1e253bfd2..6865b342b2d 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -12,6 +12,11 @@ inputs: required: false description: 'Install dependencies' type: boolean + type: + required: false + description: 'development or production' + type: string + default: 'development' deno-version: required: true description: 'Deno version' @@ -46,7 +51,8 @@ runs: apps/meteor/ee/server/services/node_modules packages/apps-engine/node_modules packages/apps-engine/.deno-cache - key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}-deno-v${{ inputs.deno-version }}-${{ hashFiles('packages/apps-engine/deno-runtime/deno.lock') }} + key: node-modules-${{ inputs.type }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package.json') }}-${{ hashFiles('yarn.lock') }}-deno-v${{ inputs.deno-version }}-${{ hashFiles('packages/apps-engine/deno-runtime/deno.lock') }}-v3 + # key: node-modules-${{ inputs.type }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package.json') }}-${{ hashFiles('yarn.lock') }}-deno-v${{ inputs.deno-version }}-${{ hashFiles('packages/apps-engine/deno-runtime/deno.lock') }}-v${{ github.run_id }} # # Could use this command to list all paths to save: # find . -name 'node_modules' -prune | grep -v "/\.meteor/" | grep -v "/meteor/packages/" @@ -70,6 +76,11 @@ runs: echo "//registry.npmjs.org/:_authToken=${{ inputs.NPM_TOKEN }}" > ~/.npmrc - name: yarn install - if: inputs.install + if: inputs.install && inputs.type == 'development' shell: bash run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn + + - name: yarn install production + if: inputs.install && inputs.type == 'production' + shell: bash + run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn workspaces focus --all --production diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6897a22d8ce..5ccc1f44e5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,7 +66,7 @@ jobs: --exclude='.git' \ . - SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-v3 + SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-v8 # Uncomment the following line to include the run ID in the hash and disable caching between runs # SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-${{ github.run_id }} diff --git a/apps/meteor/.docker/Dockerfile.alpine b/apps/meteor/.docker/Dockerfile.alpine index 72470b2b677..dbdeb5abc63 100644 --- a/apps/meteor/.docker/Dockerfile.alpine +++ b/apps/meteor/.docker/Dockerfile.alpine @@ -1,3 +1,23 @@ +FROM node:22.16.0-alpine3.20 AS builder + +ENV LANG=C.UTF-8 + +RUN apk add --no-cache python3 make g++ py3-setuptools libc6-compat + +COPY . /app + +ENV NODE_ENV=production + +RUN cd /app/bundle/programs/server \ + && npm install --omit=dev \ + # Re install sharp dependencies to ensure proper binary for architecture + # We only need the @img folder from sharp dependencies + && cd /app/bundle/programs/server/npm/node_modules/sharp \ + && npm install --omit=dev \ + && rm -rf ../@img \ + && mv node_modules/@img ../@img \ + && rm -rf node_modules + FROM node:22.16.0-alpine3.20 LABEL maintainer="buildmaster@rocket.chat" @@ -16,16 +36,13 @@ ENV LANG=C.UTF-8 # and more complex or security conscious daemons run as dedicated users. # The daemon user is also handy for locally installed daemons. # """ -RUN apk add --no-cache deno ttf-dejavu \ - && apk add --no-cache --virtual deps shadow python3 make g++ py3-setuptools libc6-compat \ +RUN apk add --no-cache shadow deno ttf-dejavu \ # Update OpenSSL # CVE -> https://scout.docker.com/vulnerabilities/id/CVE-2025-9230?s=alpine&n=openssl&ns=alpine&t=apk&osn=alpine&osv=3.21 && apk upgrade --no-cache openssl \ && groupmod -n rocketchat nogroup \ && useradd -u 65533 -r -g rocketchat rocketchat -COPY --chown=rocketchat:rocketchat . /app - # needs a mongo instance - defaults to container linking with alias 'mongo' ENV DEPLOY_METHOD=docker \ NODE_ENV=production \ @@ -37,27 +54,7 @@ ENV DEPLOY_METHOD=docker \ USER rocketchat -RUN cd /app/bundle/programs/server \ - && npm install --omit=dev \ - && cd /app/bundle/programs/server \ - && rm -rf npm/node_modules/sharp \ - && npm install sharp@0.32.6 --no-save \ - && mv node_modules/sharp npm/node_modules/sharp \ - # End hack for sharp - # # Start hack for isolated-vm... - # && rm -rf npm/node_modules/isolated-vm \ - # && npm install isolated-vm@4.6.0 \ - # && mv node_modules/isolated-vm npm/node_modules/isolated-vm \ - # # End hack for isolated-vm - && cd /app/bundle/programs/server/npm \ - && npm rebuild bcrypt --build-from-source \ - && npm cache clear --force - -USER root - -RUN apk del deps - -USER rocketchat +COPY --from=builder --chown=rocketchat:rocketchat /app /app VOLUME /app/uploads diff --git a/package.json b/package.json index 266dcbc9dfe..bbb561c80dd 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "scripts": { "build": "turbo run build", "build:services": "turbo run build --filter=rocketchat-services...", - "build:ci": "turbo run build:ci", "testunit": "turbo run testunit", "test-storybook": "turbo run test-storybook", "dev": "turbo run dev --env-mode=loose --parallel --filter=@rocket.chat/meteor...", diff --git a/turbo.json b/turbo.json index edf2a61d708..3f99e554f85 100644 --- a/turbo.json +++ b/turbo.json @@ -22,9 +22,6 @@ "lint": { "outputs": [] }, - "translation-check": { - "outputs": [] - }, "typecheck": { "outputs": [] },