-
Notifications
You must be signed in to change notification settings - Fork 41
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 docker support #394
Add docker support #394
Conversation
@ryanbrandenburg, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, got some comments, mostly about structuring the images so that it's easy to see what they are in docker images
(it also opens us up to be able to publish to Docker Hub or a registry at some point)
files/KoreBuild/KoreBuild.sh
Outdated
@@ -13,7 +14,7 @@ set_korebuildsettings() { | |||
local config_file="${4:-}" # optional. Not used yet. | |||
|
|||
[ -z "${dot_net_home:-}" ] && dot_net_home="$HOME/.dotnet" | |||
[ -z "${tools_source:-}" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' | |||
[ -z "${tools_source:-}" ] && tools_source=default_tools_source |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a $
? tools_source=$default_tools_source
{ | ||
var buildArgs = new List<string> { "build" }; | ||
|
||
var tag = $"{ImagePrefix}:{ContainerName}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First off: we shouldn't mix the container name into the image name, it can add confusion.
Docker image tag names are generally in the form: [owner]/[name]:[variant]
. Here, owner
should map to an account on Docker Hub (eventually, doesn't have to right now), I think "aspnetbuild" is a good name. name
generally refers to the content of the image (regardless of base OS, etc.), so korebuild
or build
would be good names. variant
is used to distinguish between versions and OSes usually. Take a look at the microsoft/dotnet
image for some examples: https://hub.docker.com/r/microsoft/dotnet/
I'd suggest something like aspnetbuild/korebuild:jessie
. We may even want to get in to version number tags at some point, but I think we can start with this, since we're always building the container "fresh" (using caches) rather than pulling from Docker Hub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combined with the above comment re:"Platform", this string would become something like var tag = $"{ImagePrefix}:{Image}
and ImagePrefix
becomes aspnetbuild/korebuild
|
||
public override void Configure(CommandLineApplication application) | ||
{ | ||
Platform = application.Argument("platform", "The docker platform to run on."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest using a term like Image
for this (I realize it makes up only part of the image name, see comment below, but I think it's a clearer name regardless). It's a little more aligned with Docker terminology. Platform makes me thing of Docker for Windows vs Docker for Linux.
return buildResult; | ||
} | ||
|
||
var runArgs = new List<string> { "run", "--rm", "-it", "--name", ContainerName, tag }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're using --name
we should use a uniquely-generated (possibly timestamp-based?) name, perhaps something like aspnetbuild_[timestamp]
. If there's already a container with this name, it will conflict.
Also, we should make it possible to disable --rm
. If my build fails, it would be nice to have the container stick around.
Finally, make sure the container name is dumped to the console so I know which containers come from which builds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--name
is most useful for long-running containers. In this scenario, I would just use the random name assigned by Docker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured you wouldn't ever run two at the same time due to --rm
, but I guess it's still possible, and as below I would like to let you run interactive in the future, so I'll do that.
I had intended to add disabling --rm
as an option later on. I was intending to get this running in an actual scenario (one of the CI builds) before complicating things with more options. I just filed #395 for that. Is that good or do you think that option is more important that that?
Good point about the container name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think --name
becomes relevant when --rm
is removable. @mikeharder is definitely right that if the container is just going to be removed after the build, there's no need to know the name.
Perhaps the best solution is to remove --name
for now, and when we make --rm
removable, we can also add an option to the docker-build
command to allow providing a container name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually partial to supplying the name ourselves because:
- We can easily output the name in case it persists for some reason (including future interactivity).
- It makes it easy to tell at a glance which containers belong to KoreBuild.
- It doesn't hurt anything (unless there's something I don't know).
I do agree that allowing people to specify the container name in the future would be a nice feature. I created #396 to enumerate all the future improvements we think of while doing this work.
apt-get install -y git && \ | ||
apt-get install -y curl && \ | ||
apt-get install -y unzip && \ | ||
apt-get install -y apt-transport-https |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add rm -rf /var/lib/apt/lists/*
to the end of this chain. See https://github.com/anurse/ConferencePlanner/blob/735d5ef3352d18c7a258267a1f18aad359479ec2/docker/base.Dockerfile#L9
That deletes the files apt-get update
downloaded, which take up a fair amount of space and are only needed during installation. You need to chain it in to the RUN
command so that it all ends up being baked as one layer in the image. That ensures that the layer includes only the files added by the packages you installed, and no other cruft.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also only need one call to apt-get install
. Example:
https://github.com/aspnet/benchmarks/blob/dev/docker/benchmarks/Dockerfile#L3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 more a performance that space saving issue, but definitely a good one.
return buildResult; | ||
} | ||
|
||
var runArgs = new List<string> { "run", "--rm", "-it", "--name", ContainerName, tag }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--name
is most useful for long-running containers. In this scenario, I would just use the random name assigned by Docker.
apt-get install -y git && \ | ||
apt-get install -y curl && \ | ||
apt-get install -y unzip && \ | ||
apt-get install -y apt-transport-https |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also only need one call to apt-get install
. Example:
https://github.com/aspnet/benchmarks/blob/dev/docker/benchmarks/Dockerfile#L3
apt-get install -y unzip && \ | ||
apt-get install -y apt-transport-https | ||
|
||
ADD ./ ./ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've typically see this as ADD . .
, though I think the two are equivalent.
|
||
ADD ./ ./ | ||
|
||
RUN rm -f ./korebuild-lock.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to exclude this via a .dockerignore
file, rather than copying and then removing.
|
||
RUN rm /net461dev.exe | ||
|
||
ADD . c:/repo/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided not to dump this in c:\ because it's cleaner, but also because I ran into a problem with running KoreBuild from the drive root on windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've typically seen Dockerfiles use the following order of statements instead:
WORKDIR c:\\repo
ADD . .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, our docs (https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile) recommend escaped backslashes rather than forward slashes, though both may work:
WORKDIR c:\\windows
🆙📅 |
|
||
RUN rm /net461dev.exe | ||
|
||
ADD . c:/repo/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've typically seen Dockerfiles use the following order of statements instead:
WORKDIR c:\\repo
ADD . .
@@ -0,0 +1,15 @@ | |||
FROM microsoft/aspnet:4.6.2 | |||
|
|||
ADD https://download.microsoft.com/download/F/1/D/F1DEB8DB-D277-4EF9-9F48-3A65D4D8F965/NDP461-DevPack-KB3105179-ENU.exe /net461dev.exe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to download, install, and remove in a single command (which is more efficient) like so:
https://github.com/Microsoft/aspnet-docker/blob/master/4.6.2/Dockerfile#L12-L16
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually somewhat complicated since NDP461-DevPack-KB3105179-ENU.exe /Passive /NoRestart
immediately exits with error code 0, and the install runs in the background. So, the delete will fail unless you wait a bit after starting the install. In your original Dockerfile, I think there's a small delay between the two run commands which usually causes the delete to succeed, but it's not guaranteed. And technically, I don't think it's guaranteed the install will be complete by the time build.cmd
tries to use it. The following should work, but there's no way to know the correct length of time to sleep:
RUN Invoke-WebRequest https://download.microsoft.com/download/F/1/D/F1DEB8DB-D277-4EF9-9F48-3A65D4D8F965/NDP461-DevPack-KB3105179-ENU.exe \
-OutFile C:\NDP461-DevPack-KB3105179-ENU.exe; \
C:\NDP461-DevPack-KB3105179-ENU.exe /Passive /NoRestart; \
Start-Sleep -s 10; \
Remove-Item C:\NDP461-DevPack-KB3105179-ENU.exe -Force;
The most reliable way would be to block until we know the install is complete, perhaps using the existence of a file or registry key.
37d299c
to
516c03d
Compare
|
||
RUN rm /net461dev.exe | ||
|
||
WORKDIR c:\\repo\\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to remove the trailing backslash, otherwise it seems Docker treats it as a line continuation:
Step 5/7 : WORKDIR c:\\repo\ADD . .
5224cca
to
778b1a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with one small change to Windows dockerfile.
@@ -0,0 +1,17 @@ | |||
FROM microsoft/aspnet:4.6.2 | |||
|
|||
WORKDIR c:\\repo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move WORKDIR
after RUN
to improve caching, so if you decide to change the WORKDIR
you don't need to re-execute the RUN
command.
The tests are failing...
|
# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) | ||
chmod +x "$__korebuild_dir/scripts/get-netfx.sh"; sync | ||
"$__korebuild_dir/scripts/get-netfx.sh" $verbose_flag $netfx_version "$tools_source" "$ReferenceAssemblyRoot" \ | ||
# we don't include netfx in the BuildTools artifacts currently, it ends up on the blob store through other means, so we'll only look for it in the default_tools_source | ||
"$__korebuild_dir/scripts/get-netfx.sh" $verbose_flag $netfx_version "$default_tools_source" "$ReferenceAssemblyRoot" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change? This should be reverted as it makes it impossible to override --tools-source
for the netfx asset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the comment says, overriding --tools-source for the netfx asset doesn't work right now. Currently the buildtools artifact does not contain netfx, it gets added to the blob store by some other process. If we want to fix that I feel it's better dealt with in another issue/PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, we'll track that here: #399
{ | ||
var app = _fixture.CreateTestApp("SimpleRepo"); | ||
var platform = "jessie"; | ||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should check which platform the docker host is using, not which platform is running this test. Windows machines can use Linux containers.
Also, I would be good to make this test skip if docker is not installed.
docker version -f "{{ .Server.Os }}"
{ | ||
private const string DockerIgnore = ".dockerignore"; | ||
private const string DockerfileExtension = ".dockerfile"; | ||
private const string Owner = "aspnetbuild"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we already own this docker hub account? Or are you planning on using a private container registry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably claim it if we can. I think it would be useful to take the simple steps to prepare to use a registry of some kind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Squated.
# DevPack returns exit 0 immediately, but it's not done, so we wait. | ||
# A more correct thing would be to block on a registry key existing or similar. | ||
RUN \ | ||
Invoke-WebRequest https://download.microsoft.com/download/F/1/D/F1DEB8DB-D277-4EF9-9F48-3A65D4D8F965/NDP461-DevPack-KB3105179-ENU.exe -OutFile .\\net461dev.exe ; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully this will be unnecessary once we fix #399
{ | ||
dockerToolsSource = "ToolsSource"; | ||
toolsSourceDestination = Path.Combine(RepoPath, dockerToolsSource); | ||
DirectoryCopy(ToolsSource, toolsSourceDestination); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An easier and faster way to do this to volume mount this folder into the container.
} | ||
|
||
arguments.AddRange(new[] | ||
{ | ||
"-ToolsSource", _toolsSource, | ||
"-Update" | ||
"-s", _toolsSource, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I personally prefer the readability of the long option name. The short option is good for command-line shorthand, but harder to interpret from logs and code.
34671f4
to
570269a
Compare
🆙📅 |
ping @natemcmaster. |
scripts/bootstrapper/run.sh
Outdated
@@ -218,6 +218,7 @@ fi | |||
[ -z "$channel" ] && channel='dev' | |||
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' | |||
|
|||
__warn "ts: $tools_source" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warn?
@@ -55,5 +58,85 @@ public SimpleRepoTests(ITestOutputHelper output, RepoTestFixture fixture) | |||
Assert.Same(task, build); | |||
Assert.NotEqual(0, build.Result); | |||
} | |||
|
|||
[DockerExistsFact] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One comment about the __warn
addition (I assume it was added to debug stuff), but otherwise looks good.
8f7c2cc
to
8878da9
Compare
Add the docker-build command to KoreBuild. Fixes aspnet/Coherence-Signed#647.