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 Official Support for Windows Docker Images #2136

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

zZHorizonZz
Copy link

@zZHorizonZz zZHorizonZz commented Sep 3, 2024

Description

This PR introduces official support for building windows based docker images for node. At the moment, these images don't include Yarn, I noticed that other PR(s) are pushing to remove it from the Linux images as well, so I followed suit. Although maybe we could enable corepack by default? As currently, based on the discussion in the PR to enable corepack by default in Node itself, it seems like they will be rewriting it because npm has some security concers, so that may take a couple of years.

Motivation and Context

I've seen a few attempts to add windows support over the years, but those PRs seem to have stalled. So, I thought I'd take a look at it. I've combined some useful bits from those previous efforts and added my own improvements to get things working smoothly on newer versions and new build system.

Testing Details

I've successfully built and tested these images locally. Plus, with the new Windows pipeline I added, they've been tested against both Windows Server 2019 and 2022 trough github actions.

Example Output (if appropriate)

None provided

Types of changes

  • Documentation
  • Version change (Update, remove or add more Node.js versions)
  • Variant change (Update, remove or add more variants, or versions of variants)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Other (none of the above)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING.md document.
  • All new and existing tests passed.

@zZHorizonZz
Copy link
Author

zZHorizonZz commented Sep 4, 2024

I see something weird going on in the GitHub action when running the gpg --keyserver command. If I run the build locally, it works, but if it runs in the GitHub action, it's throwing errors:

gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: Signature made 08/22/24 14:16:19 Coordinated Universal Time
gpg:                using RSA key 890C08DBEAB4DFCF[55](https://github.com/zZHorizonZz/docker-node-windows/actions/runs/10681419694/job/29605009626#step:4:56)5EF4
gpg: Can't check signature: No public key

It almost seems like it's not able to call the servers outside.

@zZHorizonZz
Copy link
Author

I see something weird going on in the GitHub action when running the gpg --keyserver command. If I run the build locally, it works, but if it runs in the GitHub action, it's throwing errors:

gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: keyserver receive failed: Server indicated a failure
gpg: Signature made 08/22/24 14:16:19 Coordinated Universal Time
gpg:                using RSA key 890C08DBEAB4DFCF[55](https://github.com/zZHorizonZz/docker-node-windows/actions/runs/10681419694/job/29605009626#step:4:56)5EF4
gpg: Can't check signature: No public key

It almost seems like it's not able to call the servers outside.

The only thing I can think of is that it's being rate limited on the keyserver side, as the requests are coming from GitHub where I imagine a lot of people are sending requests. But in that case, I don't understand why the Linux build would work.

@LaurentGoderre
Copy link
Member

Can you create a docs update PR for this?

@zZHorizonZz
Copy link
Author

Can you create a docs update PR for this?

I have updated the README to include a section about the windowsservercore variant.

@zZHorizonZz
Copy link
Author

zZHorizonZz commented Sep 10, 2024

@LaurentGoderre

Can you create a docs update PR for this?

Maybe I understand it wrong, but did you mean to update the README or is there some separate documentation I should update? I didn't find any other doc files in this project.

@LaurentGoderre
Copy link
Member

There's a separate repo for the documentation on Hub but I realise the Node one is out of sync so I will fix that seperatly.

@LaurentGoderre
Copy link
Member

I will let the other members review it but LGTM

Dockerfile-windows.template Outdated Show resolved Hide resolved
Dockerfile-windows.template Outdated Show resolved Hide resolved
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc ; \
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \
Copy link
Member

@LaurentGoderre LaurentGoderre Sep 19, 2024

Choose a reason for hiding this comment

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

@zZHorizonZz to meet what @tianon said, I think you could change these 2 line to be

if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $NODE_CHECKSUM) { Write-Error 'SHA256 mismatch' } ; \

The reason why this is better is that the images get rebuilt when the base image changes so if the server was compromised, the key would be changed at the same time as the archive. This means that the arcgive can't change or rebuilds would fail.

Copy link
Author

Choose a reason for hiding this comment

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

@LaurentGoderre It's not really just about changing these two lines. If we check the checksum, we don't really need GPG or multistage, which makes it simpler. So, what I'll do is remove the GPG installation and SHA256 download and replace it with verification through the NODE_CHECKSUM variable. I'll also remove the multistage as that's not necessary if we're going this way.

Copy link
Member

Choose a reason for hiding this comment

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

Aren't these two different checks though? One checks it wasn't modified, the other checks it came from the release team

Copy link
Author

Choose a reason for hiding this comment

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

I'm starting to get a little bit confused here.

If we change these two lines:

$sum = $(cat SHASUMS256.txt.asc | sls $('  node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \
    if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \

To this:

if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $NODE_CHECKSUM) { Write-Error 'SHA256 mismatch' } ; 

We validate the checksum against the supplied checksum NODE_CHECKSUM. In the first version, we used the sum extracted from the SHASUMS256.txt.asc file. Maybe I misunderstood you. Did you mean to replace these lines or add a new check but keep the verification from SHASUMS as well? I got confused because @tianon is also discussing whether we should use GPG at all. I looked through the Golang Windows images, and they are also using only one check with a static SHA256.

Copy link
Member

Choose a reason for hiding this comment

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

Ah yeah, my bad. We might be good to just have the hardcoded checksum and no gpg

@zZHorizonZz
Copy link
Author

zZHorizonZz commented Sep 22, 2024

So since this has been merged, it means that users won't be able to use corepack without installing it (In the future). So do we want to install yarn or not? I personally think the decision on what to use for a package manager should be up to the user. So I would personally not install yarn at all and keep it the way it is, just plain Node.js, or install corepack so that users can then enable the package manager of their choice themselves.

@LaurentGoderre
Copy link
Member

@zZHorizonZz I personally think it would be good to not include yarn in this variant by default since it's new and wouldn't break anything but I could see people wanting the variants to be consistent. I will let others weigh in on this.

@zZHorizonZz
Copy link
Author

Yeah, the reason why I'm even discussing this is because of this issue you created, where I see an inclination to not just include yarn even in linux images, or create an image variant with yarn pre-installed.

@iancward
Copy link

Looks like this will address #2063.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 3 out of 9 changed files in this pull request and generated 2 suggestions.

Files not reviewed (6)
  • 22/windowsservercore-ltsc2019/Dockerfile: Language not supported
  • 22/windowsservercore-ltsc2022/Dockerfile: Language not supported
  • Dockerfile-windows.template: Language not supported
  • architectures: Language not supported
  • functions.sh: Language not supported
  • update.sh: Language not supported
Comments skipped due to low confidence (1)

genMatrix.js:22

  • The function name 'getNodeVerionDirs' should be 'getNodeVersionDirs'.
const getNodeVerionDirs = (base) => getChildDirectories(base)

@@ -8,23 +8,25 @@ const testFiles = [
];

const nodeDirRegex = /^\d+$/;
// Directories starting with 'windowsservercore-' are excluded from the matrix windows-2019 are excluded for example
Copy link
Preview

Copilot AI Dec 9, 2024

Choose a reason for hiding this comment

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

[nitpick] The phrase 'windows-2019 are excluded for example' seems to be a typo and should be rephrased for clarity.

Suggested change
// Directories starting with 'windowsservercore-' are excluded from the matrix windows-2019 are excluded for example
// Directories starting with 'windowsservercore-' are excluded; 'windows-2019' is an example

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options

const areTestFilesChanged = (changedFiles) => changedFiles
.some((file) => testFiles.includes(file));

// Returns a list of the child directories in the given path
// Returns a list of the child directories in the given path, excluding those starting with 'windows-'
Copy link
Preview

Copilot AI Dec 9, 2024

Choose a reason for hiding this comment

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

[nitpick] The comment should be 'excluding those starting with 'windowsservercore-'.

Suggested change
// Returns a list of the child directories in the given path, excluding those starting with 'windows-'
// Returns a list of the child directories in the given path, excluding those starting with 'windowsservercore-'

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@zZHorizonZz
Copy link
Author

zZHorizonZz commented Dec 10, 2024

Should I fix the nitpicks that Copilot made? I haven't really used this on GitHub, but there are commit suggestion actions available for both of these.

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