Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add windows variant of hello-world #22

Closed
wants to merge 4 commits into from

Conversation

friism
Copy link

@friism friism commented Oct 24, 2016

@tianon This is not as minimal as your images for Linux, but it's still pretty small. I can try and twiddle compiler options to see if a smaller binary is possible.

More importantly, I'd like to see if we could work towards making this the first true multi-arch image, and use the manifest-list tool or similar: https://github.com/estesp/manifest-tool

The goal is that one can do docker run hello-world and the right image is pulled on both Windows and Linux without any tag required.

Note that the microsoft/nanoserver will work appropriately here: It can run on both Nanoserver and Windowsservercore (and on Windows 10 in Hyper-V mode), and in both hyper-v and windows container mode.

Let me know what you think.

cc @taylorb-microsoft @PatrickLang @toli @yosifkit @StefanScherer

@friism friism changed the title Add windows build tools Add windows variant of hello-world Oct 24, 2016
Copy link

@StefanScherer StefanScherer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good aproach!


SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

RUN Install-WindowsFeature NET-Framework-45-Core

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the .Net framework necessary? I compiled a C source in a Windows container only by installing the visualcppbuildtools https://github.com/StefanScherer/win-getaddrinfo/blob/3afdfab3f0fb7b1223d69ead19c93dbe917afed8/Dockerfile.msbuild#L5-L7

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StefanScherer it's listed as dependency here and I don't think it worked without - let me check

RUN [Environment]::SetEnvironmentVariable('PATH', ${Env:ProgramFiles(x86)} + '\Microsoft Visual Studio 14.0\VC\bin;' + ${Env:ProgramFiles(x86)} + '\Windows Kits\8.1\bin\x86;' + $env:PATH, [EnvironmentVariableTarget]::Machine);

RUN pushd 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC' ; \
cmd /c 'vcvarsall.bat&set' | foreach { if ($_ -match '=') { $v = $_.split('='); setx /M $v[0] $v[1] } } ; \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice to burn in all environment variables :-)

@tianon
Copy link
Member

tianon commented Oct 24, 2016

How large is the resulting binary?

@tianon
Copy link
Member

tianon commented Oct 24, 2016

I've done some messing around with compiling the .exe file in Linux using MinGW (which has the benefit of fitting into our existing build system trivially) and I've got a working binary that's ~2560 bytes total.

@tianon
Copy link
Member

tianon commented Oct 24, 2016

(Size matters a lot here since we have to actually check the resulting binary into Git in order for the official build system to be able to pick it up.)

@friism
Copy link
Author

friism commented Oct 24, 2016

@tianon The binary is 111KB. Totally up to you, but ultimately you're going to need a Windows system to create the image, even if you compile the .exe on Linux. Again up to you, but it also seems backward to make build decisions based on the fact that we're storing binary artifacts in git (eg. we could choose to place them in GitHub releases or something).

From my standpoint, there's also something nice in having this Windows image built in a "Windows natural" fashion. That way, when Windows people (or people interested in multi-arch images) come to this repo, they can see something that makes sense to them and would mirror (at a small scale) what they'd do themselves. But that function can also be served by other repos, I suppose.

@tianon
Copy link
Member

tianon commented Oct 24, 2016

I think there's been a bit of a disconnect here, so maybe I can help clarify:

  • the process for preparing this repository for a PR into the official images involves preparing a Dockerfile which the official images process can simply git clone and docker build (whether it's on Windows or Linux), and no additional processing beyond that (so that precludes GitHub releases or similar and requires that any necessary binaries either be built as part of that Dockerfile itself, or available within Git directly for COPY, which is what we do here specifically to create very, very tiny images FROM scratch which otherwise couldn't create said binaries directly)
  • the official builds for the images that actually get pushed to users happen in their native environment -- for both Linux and Windows builds we have a dedicated server which is responsible for taking the Git repo + Dockerfile and performing docker build to create the ending artifacts

So, while I do agree that it'd be nice to build the Windows binaries in a Windows build environment for mental consistency, doing so severely complicates the development process in this repo, since any time that code changes we'll have to fire up a VM to rebuild that code and get it into Git (which is where size starts to become a real concern given GitHub's size constraints and given how binary files in the Git history tend to expand the size of the repo and the time required to clone it). Even if we ignore the "get it into Git" constraint, we still need to fire up that system to build the binary and put it somewhere.

Now, I do think we could optimize this Windows-based build to produce binaries that are similar in size to the ~2kb binary I've created (for comparison, the Linux binaries are currently ~1848 bytes), but the process I went through to create that in our existing build structure in this repo was simply install an additional Debian package and point our Makefile at the MinGW compiler instead (swapping our direct syscall invocations in hello.c for their unistd.h equivalents which we still have in the file for simple reference), making the repo maintenance much simpler, and giving us a simple unified build process for both sets of artifacts.

@friism
Copy link
Author

friism commented Oct 25, 2016

the official builds for the images that actually get pushed to users happen in their native environment

Right, so my point is that you'll need a Windows machine to complete a release no matter what. Why is it a problem that one is also required to build the binary?

since any time that code changes we'll have to fire up a VM to rebuild that code and get it into Git

I guess I don't understand why you think this dual-phase-with-git-check-in build system is desirable, vs. just generating the binaries and the end-product images in one go, on release

given GitHub's size constraints and given how binary files in the Git history tend to expand the size of the repo and the time required to clone it

Very much agreed, so why was the build and release process designed to repeatedly check binaries (however small) into Git?

we still need to fire up that system to build the binary and put it somewhere

... or do the whole process in one motion: https://github.com/docker-library/hello-world/pull/22/files#diff-551831ee99d974a70a5c359eaa535e2aR1

Having said that, I understand if your process precludes building the binary on Windows. Happy to close this PR, and let me know if I can help bring the multi-arch'ness about with a Windows binary built on Linux.

@justincormack
Copy link

We used git lfs for checking binaries into github, it means you never pull the old ones unless you need to and its set up reasonably well on github.

@tianon
Copy link
Member

tianon commented Oct 25, 2016

@friism the end product is not created from the context of this repository -- it's created as part of the larger official images release process, which is governed by a strict set of rules (for both internal and external maintainers) to ensure that the process stays open and repeatable for our community, so from this repository's point of view, the "deliverable" is a tag mapping and a build context, and the artifacts our users download are generated elsewhere (which is especially useful for base image updates where we need to rebuild all the images)

@justincormack indeed! it's good to hear reports of positive experience with it ❤️ -- we've discussed it a bit over in https://github.com/docker-library/official-images/issues/1095 but haven't yet pulled the trigger since we haven't had time to devote to playing with it (especially making sure that the build process there will handle it and making changes to our tooling if necessary)

@tianon
Copy link
Member

tianon commented Oct 26, 2016

I've filed docker-library/official-images#2289 for discussing how to implement manifest lists in the official images too, and tried to add as much detail as I could think of for what we need to figure out in order to implement that in a way which will scale with our needs (both Windows and eventual multi-architecture). 👍

@tianon
Copy link
Member

tianon commented Nov 2, 2016

Alright, I've opened #23 which adds MinGW and includes .exe builds from a single source -- I'm hopeful that we can build on that to include a Dockerfile.windows which can be used to build that C file natively too. ❤️

@tianon
Copy link
Member

tianon commented Nov 17, 2016

@yosifkit came up with something even simpler which I've opened over in #24 👍

(since we have powershell, we don't need to compile an exe file at all)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants