From 66b635df97bb99156b1f55430d00105a560b2c22 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:10:28 -0800 Subject: [PATCH 1/9] Initial windows containers support --- .github/workflows/erlang.yaml | 42 +++++++++++++++++++++++++++++++++++ 24/windows/Dockerfile | 33 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 24/windows/Dockerfile diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 6cce09a9..53a20091 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -27,3 +27,45 @@ jobs: docker build --pull -t "$image" "${VARIANT:-.}" ~/official-images/test/run.sh "$image" docker images + docker-win: + strategy: + matrix: + os: + - windows-latest + from-image-name: + - windows + - windows/servercore + from-image-tag: + - "10.0.17763.2114" + otp: + - version: "24.2" + hash: "C22052C4920F06A9044F514A427B1C4116DA6DB6D6D6070EEDEB2955F1F6869B" + runs-on: ${{ matrix.os }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Build + run: | + # Windows docker builds must take into account two extra things: + # * The base image OS version _must_ be the same as the host OS. Therefore it's + # important to include the OS version in the docker tag. + # * Nanoserver variants omit huge amounts, so a separate build stage is required. + $from_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:${{ matrix.from-image-tag }}" + $build_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:${{ matrix.from-image-tag }}" + + $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" + $otp_tag = @($otp_version, $windows_tag) -join "-" + $image= "erlang:${otp_tag}" + + docker build ` + --build-arg "OTP_VERSION=$otp_version" ` + --build-arg "OTP_HASH=$otp_hash" ` + --build-arg "FROM_IMAGE=$from_image" ` + --build-arg "BUILD_IMAGE=$build_image" ` + -t $image ` + . + + # It looks like the official images repo does contain some level of support for testing + # windows images but I'm not certain how this should be implemented. + + docker images diff --git a/24/windows/Dockerfile b/24/windows/Dockerfile new file mode 100644 index 00000000..3f359b41 --- /dev/null +++ b/24/windows/Dockerfile @@ -0,0 +1,33 @@ +ARG BUILD_IMAGE=mcr.microsoft.com/windows:10.0.17763.2114 +ARG FROM_IMAGE=${BUILD_IMAGE} + +FROM $BUILD_IMAGE as build + +# Use powershell, fail fast on errors +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +ARG OTP_VERSION +ARG OTP_HASH + +ADD https://github.com/erlang/otp/releases/download/OTP-${OTP_VERSION}/otp_win64_${OTP_VERSION}.exe ./otp-installer.exe + +RUN if ((Get-FileHash ".\otp-installer.exe" -Algorithm SHA256).Hash -ne $Env:OTP_HASH) { exit 1; } + +FROM $FROM_IMAGE + +ARG OTP_VERSION + +# run OTP installer in this image, copying Program Files over doesn't work +COPY --from=build ["C:/otp-installer.exe", "C:/otp-installer.exe"] + +RUN .\otp-installer.exe /S /w /v"/qn"; \ + del /f .\otp-installer.exe + +# This is a workaround for nanoserver where not possible to set PATH using setx or similar +ENV PATH="C:\Windows\system32;C:\Windows;C:/Program Files/erl-${OTP_VERSION}/bin" + +# Some failed attempts below; someone could fix these! +# RUN setx /M PATH "%PATH%;%ProgramFiles%\erl-%OTP_VERSION%\bin" +# RUN setx /M PATH $($Env:PATH + ';C:\Program Files\erl-' + $Env:OTP_VERSION + '\bin') + +CMD [ "erl.exe" ] From 78da7d94dd55ee50671fa666ec0b0fb5802ccb6c Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:13:30 -0800 Subject: [PATCH 2/9] Fix from image tag --- .github/workflows/erlang.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 53a20091..fceb033c 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -50,8 +50,9 @@ jobs: # * The base image OS version _must_ be the same as the host OS. Therefore it's # important to include the OS version in the docker tag. # * Nanoserver variants omit huge amounts, so a separate build stage is required. - $from_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:${{ matrix.from-image-tag }}" - $build_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:${{ matrix.from-image-tag }}" + $from_image_tag = "${{ matrix.from-image-tag }}" + $from_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:$from_image_tag" + $build_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:$from_image_tag" $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" $otp_tag = @($otp_version, $windows_tag) -join "-" From 6d493dcb035e660d0787490c0952009e3d209938 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:16:11 -0800 Subject: [PATCH 3/9] Fix from image --- .github/workflows/erlang.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index fceb033c..4f3bdfe5 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -50,9 +50,10 @@ jobs: # * The base image OS version _must_ be the same as the host OS. Therefore it's # important to include the OS version in the docker tag. # * Nanoserver variants omit huge amounts, so a separate build stage is required. + $from_image_name = "${{ matrix.from-image-name }}" $from_image_tag = "${{ matrix.from-image-tag }}" - $from_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:$from_image_tag" - $build_image = "mcr.microsoft.com/${{ matrix.from-image-name }}:$from_image_tag" + $from_image = "mcr.microsoft.com/$from_image_name:$from_image_tag" + $build_image = "mcr.microsoft.com/$from_image_name:$from_image_tag" $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" $otp_tag = @($otp_version, $windows_tag) -join "-" From 0b0d388a7e7dc970676a6f009b3c8dc100d54a6b Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:17:18 -0800 Subject: [PATCH 4/9] Add delimiters --- .github/workflows/erlang.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 4f3bdfe5..552e0389 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -52,8 +52,8 @@ jobs: # * Nanoserver variants omit huge amounts, so a separate build stage is required. $from_image_name = "${{ matrix.from-image-name }}" $from_image_tag = "${{ matrix.from-image-tag }}" - $from_image = "mcr.microsoft.com/$from_image_name:$from_image_tag" - $build_image = "mcr.microsoft.com/$from_image_name:$from_image_tag" + $from_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" + $build_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" $otp_tag = @($otp_version, $windows_tag) -join "-" From f6b155929a9076f7ea6799f582209d84fd99449c Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:18:29 -0800 Subject: [PATCH 5/9] Formatting --- .github/workflows/erlang.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 552e0389..01bcd867 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -57,7 +57,7 @@ jobs: $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" $otp_tag = @($otp_version, $windows_tag) -join "-" - $image= "erlang:${otp_tag}" + $image = "erlang:${otp_tag}" docker build ` --build-arg "OTP_VERSION=$otp_version" ` From 147589b7eb77f9fa37cf3b5c709ddbc368cb1ac0 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:21:38 -0800 Subject: [PATCH 6/9] Fix otp vars --- .github/workflows/erlang.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 01bcd867..585f2e06 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -55,6 +55,9 @@ jobs: $from_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" $build_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" + $otp_version = "${{ matrix.otp.version }}" + $otp_hash = "${{ matrix.otp.hash }}" + $windows_tag = ($from_image_name.Split("/") + $from_image_tag) -join "-" $otp_tag = @($otp_version, $windows_tag) -join "-" $image = "erlang:${otp_tag}" From 12d448d3ff283a3cdd5a0de3f3fb904eb9707e62 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:26:17 -0800 Subject: [PATCH 7/9] Set docker ctx --- .github/workflows/erlang.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 585f2e06..1b44a3e1 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -62,13 +62,18 @@ jobs: $otp_tag = @($otp_version, $windows_tag) -join "-" $image = "erlang:${otp_tag}" + $dir = $otp_version.Split(".")[0] + $variant = "windows" + + cd $dir + docker build ` --build-arg "OTP_VERSION=$otp_version" ` --build-arg "OTP_HASH=$otp_hash" ` --build-arg "FROM_IMAGE=$from_image" ` --build-arg "BUILD_IMAGE=$build_image" ` -t $image ` - . + $variant # It looks like the official images repo does contain some level of support for testing # windows images but I'm not certain how this should be implemented. From 98e3a4e4f7b1f2464d1aaee6f11d13a9c0184ee8 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:31:04 -0800 Subject: [PATCH 8/9] Always use windows img for building --- .github/workflows/erlang.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/erlang.yaml b/.github/workflows/erlang.yaml index 1b44a3e1..e577996b 100644 --- a/.github/workflows/erlang.yaml +++ b/.github/workflows/erlang.yaml @@ -53,7 +53,7 @@ jobs: $from_image_name = "${{ matrix.from-image-name }}" $from_image_tag = "${{ matrix.from-image-tag }}" $from_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" - $build_image = "mcr.microsoft.com/${from_image_name}:${from_image_tag}" + $build_image = "mcr.microsoft.com/windows:${from_image_tag}" $otp_version = "${{ matrix.otp.version }}" $otp_hash = "${{ matrix.otp.hash }}" From fb0fe55597189a781f6ea01f408b393cbfc9a5d5 Mon Sep 17 00:00:00 2001 From: Joe Pearson Date: Wed, 22 Dec 2021 11:40:25 -0800 Subject: [PATCH 9/9] Add docs --- 24/windows/Dockerfile | 11 ++++++----- README.md | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/24/windows/Dockerfile b/24/windows/Dockerfile index 3f359b41..27796ae2 100644 --- a/24/windows/Dockerfile +++ b/24/windows/Dockerfile @@ -1,3 +1,5 @@ +# Use a separate build and distribution base image because some variants of Windows (i.e. +# nanoserver) don't include the necessary dependencies to run the installer) ARG BUILD_IMAGE=mcr.microsoft.com/windows:10.0.17763.2114 ARG FROM_IMAGE=${BUILD_IMAGE} @@ -11,23 +13,22 @@ ARG OTP_HASH ADD https://github.com/erlang/otp/releases/download/OTP-${OTP_VERSION}/otp_win64_${OTP_VERSION}.exe ./otp-installer.exe +# Check installer integrity RUN if ((Get-FileHash ".\otp-installer.exe" -Algorithm SHA256).Hash -ne $Env:OTP_HASH) { exit 1; } FROM $FROM_IMAGE ARG OTP_VERSION -# run OTP installer in this image, copying Program Files over doesn't work COPY --from=build ["C:/otp-installer.exe", "C:/otp-installer.exe"] +# Run and cleanup the installer RUN .\otp-installer.exe /S /w /v"/qn"; \ del /f .\otp-installer.exe # This is a workaround for nanoserver where not possible to set PATH using setx or similar ENV PATH="C:\Windows\system32;C:\Windows;C:/Program Files/erl-${OTP_VERSION}/bin" -# Some failed attempts below; someone could fix these! -# RUN setx /M PATH "%PATH%;%ProgramFiles%\erl-%OTP_VERSION%\bin" -# RUN setx /M PATH $($Env:PATH + ';C:\Program Files\erl-' + $Env:OTP_VERSION + '\bin') - +# werl.exe isn't suitable here so we just use plain erl.exe; see +# https://www.erlang.org/doc/man/werl.html CMD [ "erl.exe" ] diff --git a/README.md b/README.md index 52575f47..80792c82 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Build Status](https://github.com/erlang/docker-erlang-otp/workflows/erlang/badge.svg)](https://github.com/erlang/docker-erlang-otp/actions) This is used as docker base image for Erlang OTP. -The goal is to provide images for a few last erlang releases (currently 24 / 23 / 22 / 21 / 20 / 19 / 18), in close to full feature Erlang OTP, and relatively slim images. Support to 17, R16 and R15 are provided in this repo on a best-effort basis, and not part of official-image effort in docker-library/official-images#1075 . +The goal is to provide images for a few last erlang releases (currently 24 / 23 / 22 / 21 / 20 / 19 / 18), in close to full feature Erlang OTP, and relatively slim images. Support to 17, R16 and R15 are provided in this repo on a best-effort basis, and not part of official-image effort in docker-library/official-images#1075 . Windows container based images are available for OTP 24 + with `windows` and `windows/servercore` base images (`windows/nanoserver` is not yet supported). ### use the Erlang 23 @@ -88,6 +88,7 @@ Read from https://github.com/erlang/otp/releases for each tag description as rel 3. the slim version is built from `debian:buster` install building tools (compilers & -dev packages) on the fly and uninstall after compilation finished, to shrink image size; 4. the alpine version is built from last alpine stable image, install building tools (compilers & -dev packages) on the fly and uninstall after compilation finished, also removed src/\*.erl include/\*.hrl / all docs (include man info) / examples / static archives / build and unittest tools, and strip the ELF binaries, to get a really slim image, ideally smaller than 20MB; 5. rebar and rebar3 tool is bundled in `erlang:23`, `erlang:22`, `erlang:21`, `erlang:20`, `erlang:19` and `erlang:18` image; +6. Windows variants are not built and instead are sourced from the official Windows installer. Images are tagged with the Windows base image name and operating system version, since the container OS and host OS versions must match when using Windows containers. ### Sizes