docker-node icon indicating copy to clipboard operation
docker-node copied to clipboard

WIP: Introduce Windows Docker images

Open LaurentGoderre opened this issue 6 years ago • 26 comments

LaurentGoderre avatar May 07 '18 19:05 LaurentGoderre

Got AppVeyor setup on my fork: https://ci.appveyor.com/project/LaurentGoderre/docker-node/history

LaurentGoderre avatar May 07 '18 19:05 LaurentGoderre

This is coming along really good!!

LaurentGoderre avatar May 09 '18 19:05 LaurentGoderre

@StefanScherer want to help finish this?

LaurentGoderre avatar May 10 '18 03:05 LaurentGoderre

Very nice @LaurentGoderre ! But see also the discussion about multi-stage builds in #362

StefanScherer avatar May 10 '18 05:05 StefanScherer

Had a closer look at this PR, I really like the matrix build 👍

We should consider similar tags as discussed (by Tianon and Taylor) in https://github.com/docker-library/hello-world/pull/41

New Docker images 1803 are available now so we have these base images:

  • microsoft/nanoserver:sac2016
  • microsoft/nanoserver:1709
  • microsoft/nanoserver:1803

as well as

  • microsoft/windowsservercore:ltsc2016
  • microsoft/windowsservercore:1709
  • microsoft/windowsservercore:1803

The 1803 variants work on Windows 10 April Update 2018 as well as Windows Server, version 1803 and have a relevant improvement working with bind mounted volumes (without that ContainerMappedDirectories symlink that causes trouble with Node.js).

The resulting image names should be

  • node:10.1.0-nanoserver-sac2016
  • node:10.1.0-nanoserver-1709
  • node:10.1.0-nanoserver-1803
  • node:10.1.0-windowsservercore-ltsc2016
  • node:10.1.0-windowsservercore-1709
  • node:10.1.0-windowsservercore-1803

Currently AppVeyor does not have build agents for 1709 and 1803. For my images I use a rebase-docker-image step as a workaround to avoid setting up and maintaining own build agents. This rebase step still works, the resulting Docker image works on a Windows Server, version 1803 pretty well. For official images I guess you will have to have own 1803 servers to build images for that.

And another topic. The Linux node images uses FROM buildpack-deps:jessie to have a compiler for native Node modules. I provide a Docker image for that as we sometimes depend on native bindings. See https://github.com/StefanScherer/dockerfiles-windows/blob/master/node/8.11/build-tools/Dockerfile:

FROM node:8.11.1-windowsservercore

RUN npm install --global windows-build-tools ; \
    $env:PATH += ';{0}\.windows-build-tools\python27' -f $env:USERPROFILE ; \
    [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine)

The npm module windows-build-tools makes it pretty simple.

StefanScherer avatar May 10 '18 07:05 StefanScherer

@StefanScherer can you help wor on some of these items because I'm not very knowledgeable with PowerShell.

LaurentGoderre avatar May 10 '18 14:05 LaurentGoderre

@StefanScherer checkout the build matrix! https://ci.appveyor.com/project/LaurentGoderre/docker-node/build/1.0.136

LaurentGoderre avatar Jun 01 '18 14:06 LaurentGoderre

@LaurentGoderre that looks awesome 😍

BTW I'm updating my Node.js Dockerfiles to allow build args for the base images used. I hope that I can use only one Dockerfile for 2016, 1709 and 1803. I'm trying to find a way that the last RUN instruction works with setx instead of setx /M that is needed for 1709 and newer images. But then the 2016 image cannot find the node.exe.

There was demand from the community to add Git into the windowsservercore and nanoserver image to support links to eg. GitHub. I'm adding this with https://github.com/StefanScherer/dockerfiles-windows/pull/336 at the moment.

StefanScherer avatar Jun 01 '18 15:06 StefanScherer

@StefanScherer I just added the multiple versions of nanoserver and servercore, though I don't have aliases setup in stackbrew yet

LaurentGoderre avatar Jun 01 '18 15:06 LaurentGoderre

And here is the build: https://ci.appveyor.com/project/LaurentGoderre/docker-node/build/1.0.138

LaurentGoderre avatar Jun 01 '18 15:06 LaurentGoderre

Very good. But at the moment AppVeyor cannot be used to build 1709 or 1803 images. The plan is to add a Windows 10 1803 build agent and allow hyperv isolation, so maybe we can build such images in the near future with AppVeyor.

StefanScherer avatar Jun 01 '18 15:06 StefanScherer

@StefanScherer can we try getting those Windows image working without Multi-stage for now?

LaurentGoderre avatar Jun 11 '18 19:06 LaurentGoderre

@LaurentGoderre It depends. You could build a node image based on windowsservercore by removing the second FROM and the two COPY instructions. But then gpg tools are also installed in the image. When you start building multi-line RUN instructions to download GPG, install it, run it and remove it then this layer still has a lot of temporary artifacts with GPG binaries I guess. MSI packages and EXE installers normally cache these things at a second place on disk.

For a nanoserver image the GPG tools won't work (MSI/EXE installer, probably only 32bit). An image based on microsoft/nanoserver:sac2016 could work.

For Windows builds I really depend on multi-stage builds (or at least the old fashioned way with docker build -t download ; docker create / docker cp ; docker build -t final to ship a usable and small image. Having only a fat image gives a very poor experience for Windows developers (downloading 6 GB image...)

StefanScherer avatar Jun 12 '18 14:06 StefanScherer

6GB??? What artifacts causes this?

If we want Windows images soon, we don't have much choice but to forgo the Multi-stage until they are supported for official-images.

LaurentGoderre avatar Jun 12 '18 15:06 LaurentGoderre

6GB is when someone wants to pull or create a „tiny“ node hello world app on a fresh Windows 10 or 2016 server. This is the windowsservercore image which weighs so much.

I know the hard constraint for official images. But it‘s a solvable problem in the (more or less small) CI pipeline compared to the benefit for the whole Windows community getting a great and fast experience.

StefanScherer avatar Jun 12 '18 18:06 StefanScherer

I can't solve the multibuild but i can try to solve the images. Right now the install works on nanoserver but the subsequent call to gpg fails, as if it isn't aware of the change to $PATH

LaurentGoderre avatar Jun 13 '18 00:06 LaurentGoderre

You can check binaries with the NanoServer API Scan tool. I‘ve built an image for such tasks.
32bit binaries can‘t be used in NanoServer. But maybe only a runtime DLL is missing.

StefanScherer avatar Jun 13 '18 04:06 StefanScherer

@StefanScherer do you know if there's a way to get access to a cloud version of Windows 10 Enterprise so I could test this without appveyor? I discovered I have PowerShell on my workmachine (which mildly shocked me) so that part is now easier, but the docker part is still hard.

LaurentGoderre avatar Jun 13 '18 12:06 LaurentGoderre

@LaurentGoderre You could use the 30 days trial at Azure to spin up Windows 10 Pro 1803 which should be good enough to use containers. Use eg. a Standard_D2_v3 (or bigger) instance type which has nested Hyper-V support to be able to run eg. Docker for Windows in such an Azure instance. Otherwise DM me via email.

StefanScherer avatar Jun 13 '18 13:06 StefanScherer

@StefanScherer what is the benefit of having Windows Containers where there are already Linux Containers, especially since LCOW is now possible - (appveyor does support this on a paid plan).

swissarmykirpan avatar Jun 26 '18 22:06 swissarmykirpan

@swissarmykirpan It all depends on your application and environment. When one of your node modules needs Windows API then it's good to have same packaging as Docker image as on Linux. When you can run your app in Linux containers then I recommend a Linux VM and not LCOW. But it all depends on your environment, the servers and OS you can choose etc.

StefanScherer avatar Jun 27 '18 04:06 StefanScherer

@LaurentGoderre Yesterday I saw that the golang image has several Windows versions supported. Now that the Windows Server 2019 images are a lot smaller it gets more interesting to stay at the servercore variant for a first release.

Is the build infra for the official node images also able to build for Windows Server 2019? I may have asked that years ago if you use the same infra as eg. for the other official Docker images? :-)

So if there is support for at least Windows Server 2016 and 2019 I could help to get this done as it makes sense to me.

Ok, a version without multi-stage build, so far so good.

One obstacle is that nanoserver no longer has PowerShell support, the 1809 images now have curl.exe and tar.exe in a CMD shell, but scripting all the GPG loop will be painful in just cmd scripts.

So maybe drop the nanoserver image and just use mcr.microsoft.com/windows/servercore:ltsc2016 and mcr.microsoft.com/windows/servercore:ltsc2019

WDYT?

StefanScherer avatar Jan 08 '19 15:01 StefanScherer

Is the build infra for the official node images also able to build for Windows Server 2019? I may have asked that years ago if you use the same infra as eg. for the other official Docker images?

We have our own CI to test PRs, but the official images (the ones you pull down) are built by Docker on their own infra

SimenB avatar Jan 08 '19 15:01 SimenB

Thanks @SimenB

Do you think it would be possible to check PR's for Windows Server 2016 only on your side and let the Docker infra build all four Windows variants to provide a manifest list like the golang?

$ docker run --rm mplatform/mquery node
Image: node
 * Manifest List: Yes
 * Supported platforms:
   - linux/amd64
   - linux/arm/v7
   - linux/arm64
   - linux/ppc64le
   - linux/s390x

$ docker run --rm mplatform/mquery golang
Image: golang
 * Manifest List: Yes
 * Supported platforms:
   - linux/amd64
   - linux/arm/v7
   - linux/arm64
   - linux/386
   - linux/ppc64le
   - linux/s390x
   - windows/amd64:10.0.14393.2665
   - windows/amd64:10.0.16299.846
   - windows/amd64:10.0.17134.469
   - windows/amd64:10.0.17763.194

There are 2016, 1709, 1803 and 1809 variants there, so on any Windows Version it picks the best fitting image (just like working on different Linux CPU architectures).

Windows Server 2019 / Windows 10 1809 brings so many bugfixes for Node.js on Windows (the mapped folders for source code from the host work, port mapping to localhost works, docker pull and extract is faster than on 2016, ...).

And then we have to choose which PR we want to update, this one or #362.

StefanScherer avatar Jan 08 '19 15:01 StefanScherer

FYI, for testing Windows images, we've used AppVeyor for a long time (https://github.com/docker-library/golang/blob/60879215d473711ae500cc43acbfa037cf808fb0/.appveyor.yml), but they only currently support the LTSC release of 2016.

Travis recently (https://blog.travis-ci.com/2018-10-11-windows-early-release) added support for Windows with 1803 (https://github.com/docker-library/golang/blob/60879215d473711ae500cc43acbfa037cf808fb0/.travis.yml#L6-L8), which makes it easier to run similar tests across both Windows and Linux, even with Docker. :+1:

tianon avatar Jan 08 '19 23:01 tianon

Any plans on merging this?

DavidMarquezF avatar Jul 08 '21 10:07 DavidMarquezF