-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slim Down Docker Image (Attempt 2) #4481
base: dev
Are you sure you want to change the base?
Conversation
Branch preview✅ Deploy successful! Storybook: |
📦 Next.js Bundle Analysis for safe-wallet-webThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
Testing Docker build in CI here: https://github.com/safe-global/safe-wallet-web/actions/runs/11686228763/job/32541499128?pr=4481 |
Coverage report
Show new covered files 🐣
Test suite run success1593 tests passing in 215 suites. Report generated by 🧪jest coverage report action from 270b583 |
RUN apk add --no-cache libc6-compat git python3 py3-pip make g++ libusb-dev eudev-dev linux-headers | ||
WORKDIR /app | ||
COPY . . | ||
|
||
# Fix arm64 timeouts | ||
RUN yarn config set network-timeout 300000 && yarn global add node-gyp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer needed, we build on native arch.
@@ -1,24 +1,39 @@ | |||
FROM node:18-alpine | |||
FROM --platform=$BUILDPLATFORM node:18-alpine AS build | |||
ARG BUILDPLATFORM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a built-in Docker arg that resolves to the native platform of the builder: https://docs.docker.com/build/building/multi-platform/#cross-compilation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know that, good to know
998d414
to
270b583
Compare
@nlordell but this way we will not be able to set up environment variables on the run, right? Like we do here when running the docker image: https://github.com/safe-global/safe-infrastructure/blob/main/container_env_files/ui.env |
Ah, I hadn't noticed (I thought it was just serving static files), but you are that it will not. It looks like it does a ui:
build: https://github.com/safe-global/safe-wallet-web.git#${UI_VERSION}
env_file:
- container_env_files/ui.env
depends_on:
- nginx
expose:
- 8080 The alternative, would be to implement env value substitution ONLY before serving the static |
Agree, but also building was so slow for M1 computers in the past
I tried that in the past but I couldn't make it, maybe @katspaugh knows a workaround |
Just tried it out, and it isn't because of how the environment variables are used (they are directly replaced in the static files). Some hand-rolled thing could work - but may be brittle.
I think the speed should be similar-ish to pulling a 6GB image 😅. I guess one strategy would be to split the build into different layers so that when replacing the |
What it solves
This is a long awaited follow up to #3707, which reduces the Docker image size of the web interface from ~6GB to ~70MB. This iteration addresses build issues that it introduced in the previous version.
In particular, we now use a multi-stage Docker build, where building the web assets is done on the
BUILDPLATFORM
(i.e. the native build platform) instead of the target platform. This means that the image forlinux/arm64
will first build the front-end on the native architecture of the CI runner (linux/amd64
by default) before copying. This should make building the Docker image MUCH quicker, while still producing a multi-platform image, and avoid the Docker build timeouts that were happening in CI. Documentation on howBUILDPLATFORM
works and can be used for cross-compilation can be found here.How this PR fixes it
The docker image size is significantly reduced by using a multistage build where the first stage builds the static website, and the actual image just hosts the static webside (here using BusyBox
httpd
which is nice and lightweight).This gets the image down to around 70MB, around 1% of the original image size (sizes computed from Docker images built on amd64 Linux).
Note that there is one weird detail is that static HTTP servers typically don't have support for automatically adding
.html
endings to URL paths. It was worked around here with symlinks. See comment in the Dockerfile for more details.How to test it
Build the docker image and run the container locally:
docker build . -t safe-wallet-web docker run --rm -p 3000:3000 safe-wallet-web
This should give you a local interface at http://localhost:3000.
It was also able to successfully build in CI without timing out:
"Screenshots"
Checklist