sdk
sdk copied to clipboard
BWS Docker image for ARM contains x86 binary/libs and doesn't run on ARM natively
Steps To Reproduce
- Use an ARM based system with Docker installed (no Apple Silicon emulation / Rosetta)
- Run the official bws docker image via
docker run -it bitwarden/bws:0.5.0
Expected Result
The bws executable should print the help output.
Bitwarden Secrets CLI
Usage: bws [OPTIONS] [COMMAND]
Commands:
config Configure the CLI
...
Actual Result
exec /bin/bws: exec format error
The binary and libraries found in the ARM image are x86 architecture and thus cannot be run on a native ARM-based system.
This does not happen when running the ARM image on an Apple Silicon device with Rosetta as this somehow emulates the x86 binary even if the Docker image is declared as ARM architecture (validated via docker image/container inspect). Basically the ARM and x86 images are identical. An Apple Silicon Mac is also able to run the x86 image directly using emulation: docker run -i -t --platform=linux/amd64 bitwarden/bws:0.5.0
shows the expected output as it is emulated.
Running the image on a system that does not have emulation causes the issue. This is reproducible on e.g. a Raspberry Pi 4 or an ARM based server VM (e.g. Graviton instance).
Screenshots or Videos
No response
Additional Context
This issue is present with the Dockerfile used for building the 0.5.0 release (the modified one with a scratch runtime image rather than a debian base): https://github.com/bitwarden/sdk/blob/c7120e6db1e37615c01e418b1dc96695701818ec/crates/bws/Dockerfile
I'm not really familiar with the specifics of the Rust cross-compilation process but usually when building multi-architecture docker images there are two options:
- Using a build stage with the BUILDPLATFORM architecture AND making use of the toolchain's own cross-compilation. This avoids emulating the whole toolchain for other architectures but requires special configs/arguments when executing the compilation (e.g. setting GOOS/GOARCH when compiling go binaries).
- Using a TARGETPLATFORM specific build stage (by not adding
--platform=$BUILDPLATFORM
) and running a regular build (no special cross-platform configs/arguments required) but this either requires dedicated builders for the different architectures or the full docker build of all non-native architectures has to run in an emulated way.
With the current Dockerfile, a fixed platform is used for the build stage but there are no specific cross-compilation configurations set, so no matter which target platform is used, the compilation always happens for the default platform of the build system which is x86 in this case.
As the bws build does not produce a static binary but rather relies on some platform specific libs to be available at runtime, I'm not sure if option 1 is a feasible way. When the build is executed on an ARM based builder (where BUILDPLATFORM=linux/arm64), the produced image contains a valid library and also the necessary aarch64 libs. Validated on Apple Silicon and an ARM based VM.
Operating System
macOS, Linux
Operating System Version
No response
Shell
Zsh
Build Version
0.5.0
Issue Tracking Info
- [X] I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.