From 4599e5cc0644fc47bcc913a0940633f71350f45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Mon, 12 Jun 2023 09:15:09 +0200 Subject: [PATCH] chore: Optimize docker build oss (#3951) ## About the changes Reduce the build time of OSS docker image from [~30m](https://github.com/Unleash/unleash/actions/workflows/docker_publish.yaml) to [under 15m](https://github.com/Unleash/unleash/actions/runs/5222180536/jobs/9427342758) 1. Build frontend outside docker multiplatform. 2. Allow `frontend/build` to be copied to the image by removing this from `.dockerignore` 3. Run with `--ignore-scripts` to avoid building the frontend on the `prepare` script, but this requires us to run all the prepare scripts manually (except the frontend build). **Note:** we need to build frontend in the `prepare` script to be able to have source code dependencies ## Manual Testing Manually downloaded from https://hub.docker.com/r/unleashorg/unleash-server/tags?page=1 and compared both `unleash` folders from main and the version built with the new process https://github.com/Unleash/unleash/actions/runs/5223078089/jobs/9429430190#step:5:48 ![Screenshot from 2023-06-10 21-11-33](https://github.com/Unleash/unleash/assets/455064/60a41739-904d-480d-8d80-bf17b7a70432) No major difference was spotted (only expected changes due to development done in main) **Command used to extract the contents:** ``` cd /tmp mkdir main && cd main docker pull unleashorg/unleash-server:main-edge-18-alpine docker export $(docker create unleashorg/unleash-server:main-edge-18-alpine) > container.tar && tar xvf container.tar mkdir ../new-process && cd ../new-process docker pull unleashorg/unleash-server:sha-ccac902-18-alpine docker export $(docker create unleashorg/unleash-server:sha-ccac902-18-alpine) > container.tar && tar xvf container.tar meld ./unleash ../main/unleash ``` --- .dockerignore | 1 - .github/workflows/docker_publish.yaml | 15 ++++++++++++++- Dockerfile | 5 +++-- package.json | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.dockerignore b/.dockerignore index 84f97f0519..8c611ae669 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,4 +11,3 @@ !README.md !frontend frontend/node_modules -frontend/build diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index 2b799d75cf..bf47919607 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -6,6 +6,12 @@ on: - main tags: - 'v*' + workflow_dispatch: + inputs: + ignore-push: + description: 'Ignore push to dockerhub. If not set the image will be pushed with the sha of the commit as tag' + required: false + type: boolean jobs: build: @@ -33,16 +39,23 @@ jobs: type=semver,pattern={{ major }},enable=${{ startsWith(github.ref, 'refs/tags/v') }} # only enabled in main: type=edge,prefix=main-,suffix=-${{ matrix.version }},enable=${{ github.ref == 'refs/heads/main' }} + # only enabled on workflow_dispatch: + type=sha,suffix=-${{ matrix.version }},enable=${{ github.event_name == 'workflow_dispatch' }} - name: Login to docker hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build frontend + run: | + yarn --cwd ./frontend install + yarn build:frontend - name: Build tag and push image to Docker hub uses: docker/build-push-action@v3 with: + context: . platforms: linux/amd64,linux/arm64 - push: true + push: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.ignore-push != 'true' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: NODE_VERSION=${{ matrix.version }} diff --git a/Dockerfile b/Dockerfile index 4ec530746a..9b85ac3a5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,9 +8,10 @@ COPY . /unleash RUN yarn config set network-timeout 300000 -RUN yarn install --frozen-lockfile && yarn local:package +RUN yarn install --frozen-lockfile --ignore-scripts && yarn prepare:backend && yarn local:package -RUN mkdir /unleash/build/frontend && cp -r /unleash/frontend/build /unleash/build/frontend/build +# frontend/build should already exist (it needs to be built in the local filesystem +RUN mkdir -p /unleash/build/frontend && mv /unleash/frontend/build /unleash/build/frontend/build WORKDIR /unleash/docker diff --git a/package.json b/package.json index c6904e0af7..c0d08badd7 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "dev:frontend": "wait-on tcp:4242 && yarn --cwd ./frontend run dev", "dev": "concurrently \"yarn:dev:backend\" \"yarn:dev:frontend\"", "prepare": "node scripts/husky-install && yarn --cwd ./frontend install && if [ ! -d ./dist ]; then yarn build; fi", + "prepare:backend": "concurrently \"yarn:copy-templates\" \"yarn:build:backend\"", "prestart:dev": "yarn run clean", "start:dev": "TZ=UTC NODE_ENV=development tsc-watch --strictNullChecks false --onSuccess \"node dist/server-dev.js\"", "db-migrate": "db-migrate --migrations-dir ./src/migrations",