# Nim lang Docker images ## Description At Codex, we are using [Nim](https://nim-lang.org) programming language. Some of our projects are using pre-compiled Nim in Docker for Docker images to simplify and speed up the builds. Also, we are using multi-arch Docker images and for that it is required to have multi-arch source images and we have the following issues with that - :hourglass_flowing_sand: [Make Nim docker images official?](https://forum.nim-lang.org/t/9983) - :hourglass_flowing_sand: [Provide official docker image #515](https://github.com/nim-lang/RFCs/issues/515) - :x: [moigagoo/nimage](https://github.com/moigagoo/nimage) - Only amd64, outdated - :scroll: [theAkito/docker-nim](https://github.com/theAkito/docker-nim) - License, outdated - :hammer_and_wrench: [arm support for Linux #23](https://github.com/nim-lang/choosenim/issues/23) Code in the repository provides a simple way to build multi-arch Docker images with a required Nim version. However, builds are triggered manually. For builds we are using GitHub Actions and rely on [nimv](https://github.com/emizzle/nimv) for Nim installation. **Considerations** - We are using only `amd64` and `arm64` architecture - We are using [ubuntu](https://hub.docker.com/_/ubuntu) for our apps container and use it for nim-lang as well - Multi-platform builds using [QEMU](https://github.com/docker/setup-qemu-action) are very slow `1h56m` vs `12m` ## Docker images Images are pushed and available on [DockerHub](https://hub.docker.com/r/codexstorage/nim-lang/tags) ```shell docker run --rm codexstorage/nim-lang:2.0.14 nim --version ``` ## Build your own images 1. Fork the repository. 2. Add GitHub Actions secrets - `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`. 3. Adjust workflow with your repository name. 4. Run workflow and pass required [Nim version](https://github.com/nim-lang/Nim/tags). ## Build manually [Multi-platform builds](https://docs.docker.com/build/building/multi-platform/) ### On separate VMs
Build guide ### Build Docker images on separate VMs 1. Run `amd64`(`cx32` ,`cpx31`) and `arm64`(`cax21`) VMs on Hetzner 2. Install Docker 3. Clone repository ```shell git clone https://github.com/codex-storage/nim-lang-docker ``` 4. Define variables ```shell repository="codexstorage/nim-lang" nim_version="2.0.14" ``` 5. Run the build on each VM ```shell docker build \ --tag nim-lang:"${nim_version}" \ --build-arg NIM_VERSION="${nim_version}" \ --file Dockerfile . ``` 6. Login to DockerHub ```shell docker login -u ``` 7. Push image and get the digest on each VM ```shell docker image tag nim-lang:"${nim_version}" "${repository}:${nim_version}" docker image push ${repository}:${nim_version} ``` We will get a digest for each image and we need to define appropriate variables ```shell amd64="sha256:43c1ea16d34528b3f195e18ca21f69987a01daaf0ddd5d94b252d37ebace2f5c" arm64="sha256:4b4b3d6617c9bc698adefd0a27d1d18c5236016b92ee7ddc8c42311586568d91" ``` 8. Create a manifest list for multi-arch image and push it from on one of the VM ```shell docker buildx imagetools create \ -t "${repository}:${nim_version}" \ "${amd64}" \ "${arm64}" ``` Duration | Platform | Build | Push | Size | | -------- | ------------ | ----------- | ------- | | `amd64` | `8m20.221s` | `1m17.620s` | `659MB` | | `arm64` | `10m20.591s` | `0m48.888s` | `676MB` | TOTAL: ~ `11m09s`
### On a single VM
Build guide ### Build Docker images on a single VM 1. Run `amd64`(`cx32` ,`cpx31`) VM on Hetzner 2. Install Docker 3. Clone repository ```shell git clone https://github.com/codex-storage/nim-lang-docker ``` 4. Define variables ```shell repository="codexstorage/nim-lang" nim_version="2.0.14" ``` 5. Create a custom builder ```shell docker buildx create \ --name container-builder \ --driver docker-container \ --bootstrap --use ``` 6. Login to DockerHub ```shell docker login -u ``` 7. Run the build for multiple platforms ```shell docker buildx build \ --tag "${repository}:${nim_version}" \ --build-arg NIM_VERSION="${nim_version}" \ --platform linux/amd64,linux/arm64 \ --push \ --file Dockerfile . ``` Duration | Platform | Build | Push | Size | | -------- | ----------- | --------- | ------- | | `amd64` | `-` | `-` | `613MB` | | `arm64` | `78m27.578` | `0m49.9s` | `425MB` | TOTAL: ~ `79m17.478s`
## Known issues 1. We are using [nimv](https://github.com/emizzle/nimv) which requires bash, so alpine images will not work.