Skip to content

Commit 0691514

Browse files
authored
chore(ci): do not include dev dependencies in docker images (RocketChat#37481)
1 parent 7d90c9d commit 0691514

7 files changed

Lines changed: 89 additions & 36 deletions

File tree

.github/actions/build-docker/action.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ runs:
7575
set -o xtrace
7676
export DENO_VERSION="${{ inputs.deno-version }}"
7777
78+
# Removes unnecessary swc cores to reduce image sized
79+
swc_arch='x64'
80+
if [[ "${{ inputs.service }}" == 'rocketchat' ]]; then
81+
if [[ "${{ inputs.arch }}" == 'arm64' ]]; then
82+
swc_arch='arm64'
83+
fi
84+
85+
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 {} +
86+
fi
87+
7888
if [[ "${{ inputs.publish-image }}" == 'true' ]]; then
7989
LOAD_OR_PUSH="--push"
8090
else

.github/actions/meteor-build/action.yml

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ runs:
4242
with:
4343
swap-size-gb: 4
4444

45+
- name: Merge dependencies for build
46+
shell: bash
47+
if: steps.cache-build.outputs.cache-hit != 'true'
48+
run: |
49+
# Merge dependencies and devDependencies into a new 'dependencies' field
50+
cd apps/meteor
51+
cp package.json package.json.bak
52+
jq '.dependencies = (.dependencies + .devDependencies) | del(.devDependencies)' package.json > package.json.tmp && mv package.json.tmp package.json
53+
4554
- name: Setup NodeJS
4655
uses: ./.github/actions/setup-node
4756
if: steps.cache-build.outputs.cache-hit != 'true'
@@ -50,6 +59,7 @@ runs:
5059
deno-version: ${{ inputs.deno-version }}
5160
cache-modules: true
5261
install: true
62+
type: 'production'
5363
NPM_TOKEN: ${{ inputs.NPM_TOKEN }}
5464

5565
# - name: Free disk space
@@ -150,12 +160,41 @@ runs:
150160
echo "Coverage enabled"
151161
fi
152162
163+
# Restore original package.json so meteor should not copy devDependencies
164+
mv apps/meteor/package.json.bak apps/meteor/package.json
165+
153166
yarn build:ci
154167
155-
- name: Translation check
156-
shell: bash
157-
if: steps.cache-build.outputs.cache-hit != 'true'
158-
run: yarn turbo run translation-check
168+
declare -a meter_modules_to_remove=(
169+
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-darwin-arm64" # Removes 35M
170+
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-x64-musl" # Removes 58M
171+
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-arm64-musl" # Removes 44M
172+
"meteor/babel-compiler/node_modules/typescript" # Removes 31M
173+
"meteor/babel-compiler/node_modules/@babel" # Removes 14M
174+
175+
"@rocket.chat/i18n/src" # Removes 16M
176+
"typescript" # Removes 19M
177+
# "@babel" # Removes 34M - Needed by Minimongo
178+
)
179+
180+
du -s /tmp/dist/bundle
181+
182+
for dir_path in "${meter_modules_to_remove[@]}"; do
183+
path=/tmp/dist/bundle/programs/server/npm/node_modules/${dir_path}
184+
185+
if [ -d "$path" ]; then
186+
rm -rf "$path"
187+
188+
echo "Removed directory: $path"
189+
else
190+
echo "Path is not a directory or does not exist: $path"
191+
fi
192+
done
193+
194+
# Remove all .d.ts files from node_modules to reduce size
195+
# Removes 184M
196+
find /tmp/dist/bundle -type f -name "*.d.ts" -delete
197+
du -s /tmp/dist/bundle
159198
160199
- name: Prepare build
161200
shell: bash

.github/actions/setup-node/action.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ inputs:
1212
required: false
1313
description: 'Install dependencies'
1414
type: boolean
15+
type:
16+
required: false
17+
description: 'development or production'
18+
type: string
19+
default: 'development'
1520
deno-version:
1621
required: true
1722
description: 'Deno version'
@@ -46,7 +51,8 @@ runs:
4651
apps/meteor/ee/server/services/node_modules
4752
packages/apps-engine/node_modules
4853
packages/apps-engine/.deno-cache
49-
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}-deno-v${{ inputs.deno-version }}-${{ hashFiles('packages/apps-engine/deno-runtime/deno.lock') }}
54+
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
55+
# 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 }}
5056
#
5157
# Could use this command to list all paths to save:
5258
# find . -name 'node_modules' -prune | grep -v "/\.meteor/" | grep -v "/meteor/packages/"
@@ -70,6 +76,11 @@ runs:
7076
echo "//registry.npmjs.org/:_authToken=${{ inputs.NPM_TOKEN }}" > ~/.npmrc
7177
7278
- name: yarn install
73-
if: inputs.install
79+
if: inputs.install && inputs.type == 'development'
7480
shell: bash
7581
run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn
82+
83+
- name: yarn install production
84+
if: inputs.install && inputs.type == 'production'
85+
shell: bash
86+
run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn workspaces focus --all --production

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
--exclude='.git' \
6767
.
6868
69-
SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-v3
69+
SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-v8
7070
7171
# Uncomment the following line to include the run ID in the hash and disable caching between runs
7272
# SOURCE_HASH=$(sha256sum /tmp/RocketChat-source.tar | awk '{ print $1 }')-${{ github.run_id }}

apps/meteor/.docker/Dockerfile.alpine

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
FROM node:22.16.0-alpine3.20 AS builder
2+
3+
ENV LANG=C.UTF-8
4+
5+
RUN apk add --no-cache python3 make g++ py3-setuptools libc6-compat
6+
7+
COPY . /app
8+
9+
ENV NODE_ENV=production
10+
11+
RUN cd /app/bundle/programs/server \
12+
&& npm install --omit=dev \
13+
# Re install sharp dependencies to ensure proper binary for architecture
14+
# We only need the @img folder from sharp dependencies
15+
&& cd /app/bundle/programs/server/npm/node_modules/sharp \
16+
&& npm install --omit=dev \
17+
&& rm -rf ../@img \
18+
&& mv node_modules/@img ../@img \
19+
&& rm -rf node_modules
20+
121
FROM node:22.16.0-alpine3.20
222

323
LABEL maintainer="buildmaster@rocket.chat"
@@ -16,16 +36,13 @@ ENV LANG=C.UTF-8
1636
# and more complex or security conscious daemons run as dedicated users.
1737
# The daemon user is also handy for locally installed daemons.
1838
# """
19-
RUN apk add --no-cache deno ttf-dejavu \
20-
&& apk add --no-cache --virtual deps shadow python3 make g++ py3-setuptools libc6-compat \
39+
RUN apk add --no-cache shadow deno ttf-dejavu \
2140
# Update OpenSSL
2241
# CVE -> https://scout.docker.com/vulnerabilities/id/CVE-2025-9230?s=alpine&n=openssl&ns=alpine&t=apk&osn=alpine&osv=3.21
2342
&& apk upgrade --no-cache openssl \
2443
&& groupmod -n rocketchat nogroup \
2544
&& useradd -u 65533 -r -g rocketchat rocketchat
2645

27-
COPY --chown=rocketchat:rocketchat . /app
28-
2946
# needs a mongo instance - defaults to container linking with alias 'mongo'
3047
ENV DEPLOY_METHOD=docker \
3148
NODE_ENV=production \
@@ -37,27 +54,7 @@ ENV DEPLOY_METHOD=docker \
3754

3855
USER rocketchat
3956

40-
RUN cd /app/bundle/programs/server \
41-
&& npm install --omit=dev \
42-
&& cd /app/bundle/programs/server \
43-
&& rm -rf npm/node_modules/sharp \
44-
&& npm install sharp@0.32.6 --no-save \
45-
&& mv node_modules/sharp npm/node_modules/sharp \
46-
# End hack for sharp
47-
# # Start hack for isolated-vm...
48-
# && rm -rf npm/node_modules/isolated-vm \
49-
# && npm install isolated-vm@4.6.0 \
50-
# && mv node_modules/isolated-vm npm/node_modules/isolated-vm \
51-
# # End hack for isolated-vm
52-
&& cd /app/bundle/programs/server/npm \
53-
&& npm rebuild bcrypt --build-from-source \
54-
&& npm cache clear --force
55-
56-
USER root
57-
58-
RUN apk del deps
59-
60-
USER rocketchat
57+
COPY --from=builder --chown=rocketchat:rocketchat /app /app
6158

6259
VOLUME /app/uploads
6360

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"scripts": {
88
"build": "turbo run build",
99
"build:services": "turbo run build --filter=rocketchat-services...",
10-
"build:ci": "turbo run build:ci",
1110
"testunit": "turbo run testunit",
1211
"test-storybook": "turbo run test-storybook",
1312
"dev": "turbo run dev --env-mode=loose --parallel --filter=@rocket.chat/meteor...",

turbo.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
"lint": {
2323
"outputs": []
2424
},
25-
"translation-check": {
26-
"outputs": []
27-
},
2825
"typecheck": {
2926
"outputs": []
3027
},

0 commit comments

Comments
 (0)