I’m new to Docker. I’ve been learning some basics of docker lately.
I’m working on a c++ project that is supposed to work on windows, linux and macos. And there is two arch supported on each OS, x64 and arm64. Since the repo is a private repo, I have to setup my own self-hosted runners for CI/CD.
I’ve setup a docker image (ubuntu x64) that can help me build my source code on a real x64 linux machine.
Ideally, I would like to run x64 Windows, arm64 Windows, x64 Mac, arm64 Mac and arm64 windows on the same linux machine through another 5 different docker images.
But after searching through some basics online, it doesn’t look like this is very realistic. Though, I’m not sure.
There are two purposes that I’m interested in using docker in my CI/CD setup
- Every time I need to swap a physical machine for my CI/CD, I don’t need to install a bunch of tool chains needed to compile my source code.
- In the worst case, I will have to run 6 machines 24 7 to keep the service on. Of course, in reality, I guess I can use Arm Mac to compile code on both arm64 and x64 through Rosetta 2. The same could go true for Windows as well. That means I would need 4 machines without the help of docker. It would be great if I can just use one linux PC to build the source code everywhere.
To clarify, when I say build the code, I actually need to run the unit test in the CI/CD to make sure the behavior of the problem stays expected.
I would appreciate it if anyone could offer some suggestions.
I guess I’m not even sure if Docker is supposed to solve these problems in the first place.
I made a few attempts that work so far
- Build a docker image (ubuntu x64) run it on arm64 mac, x64 linux, x64 windows. It all builds my code and run the unit test fine.
- Build a docker image (ubuntu arm4) run it on arm64 mac, x64 linux, x64 windows. It all builds my code and run the unit test fine.
- I’ve also configured a CI/CD workflow that helps building code on x64 ubuntu through my docker image successfully.
- It does look like I can build a docker image (windows) that so far only runs on a real windows machine. I’ve only tried x64 in this case, not sure about arm64.
What doesn’t seem to work is
- Github action seems only support docker images on linux builders.
- Somehow github action won’t even work if the ubuntu imagge is based on arm64, even if the same x64 image works fine.
- Windows image doesn’t seem to run on a mac or linux machine at all.
Thanks
2
Answers
If you using self-hosted runner all you need to do is to add arch emulation (qemu). Try to run a
helloworld
docker with different arches. Actually, it’s possible to build a windows apps on Linux images. You just need to setup an enviroment and build cross-compiler(or setup a multiarch compiller, but for ci-cd I highly recommended build your own instance of cross-compiler).Using Docker in your GitHub CI/CD pipeline can provide significant benefits, especially when dealing with multiple operating systems and architectures. However, there are some inherent limitations when it comes to Docker and cross-platform compatibility. Let’s break down how Docker can help and what approaches you can take to achieve your goals.
Benefits of Docker in CI/CD
Challenges and Solutions
Cross-Platform Builds
Running Docker images for different OS and architectures on a single host machine is inherently challenging because Docker containers share the host kernel. Here are some specific points:
Given these limitations, your idea of running different OS containers on a single Linux machine is not fully feasible. However, you can still leverage Docker in your CI/CD setup in a few ways:
Multi-Platform Builds
QEMU for Emulation: You can use QEMU to emulate different architectures. Docker can integrate with QEMU to run multi-architecture builds. For example, you can build and test ARM64 binaries on an x64 host using QEMU. However, performance might be slower compared to running on native hardware.
Docker Buildx: Docker Buildx supports cross-platform builds using QEMU. This allows you to build multi-architecture Docker images. You can set up your GitHub Actions workflow to build for multiple architectures.
Self-Hosted Runners
For scenarios where Docker cannot solve cross-platform issues (like running Windows or MacOS containers on a Linux host), self-hosted runners are necessary:
Workflow Example
Here’s a basic example of a GitHub Actions workflow that uses Docker for Linux builds and self-hosted runners for Windows and MacOS builds:
Summary
By combining Docker and self-hosted runners, you can create an efficient CI/CD pipeline that handles builds and tests across multiple operating systems and architectures.