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 Dockerize and ASP.NET Core doc #1681

Merged
merged 8 commits into from
Jul 25, 2017
Merged

Add Dockerize and ASP.NET Core doc #1681

merged 8 commits into from
Jul 25, 2017

Conversation

kendrahavens
Copy link
Contributor

@kendrahavens kendrahavens commented Feb 15, 2017

Proposed changes

Add "Dockerize an ASP.NET Core app" documentation to the Docker engine examples section.

This doc takes the user through adding a Dockerfile and .dockerignore file to a simple ASP.NET Core application. It includes both Linux and Windows Container options for writing the Dockerfile. It then instructs the user on how to build and run the Docker container and view it in the browser.

Copy link

@mdlinville mdlinville left a comment

Choose a reason for hiding this comment

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

Awesome! I left a few notes. Please let me know if I have misunderstood anything or if you have questions about the feedback.

---
description: Create a Docker image by layering your ASP.NET Core app on debian for Linux Containers or with Windows Nano Server containers using a Dockerfile.
keywords: docker, dockerize, dockerizing, dotnet, .NET, Core, article, example, platform, installation, containers, images, image, dockerfile, build, asp.net, asp.net core
title: Dockerizing a .NET Application

Choose a reason for hiding this comment

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

Please use sentence case (so no caps on "Application")


This example demonstrates how to dockerize an ASP.NET Core application.

> **Note:** This example assumes you already have a published ASP.NET Core app on your machine. If you are new to ASP.NET you can follow a [simple tutorial](https://www.asp.net/get-started) to initialize a project.

Choose a reason for hiding this comment

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

Maybe put this into a prerequisites section instead of a note?


## Why build ASP.NET Core?
- [Open-source](https://github.com/aspnet/home)
- Develop and run your ASP.NET Core apps cross-platform on Windows, Mac and Linux

Choose a reason for hiding this comment

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

s/Mac/macOS

- [Open-source](https://github.com/aspnet/home)
- Develop and run your ASP.NET Core apps cross-platform on Windows, Mac and Linux
- Great for modern cloud-based apps, such as web apps, IoT apps and mobile backends
- ASP.NET Core apps can run on [.NET Core](https://www.microsoft.com/net/core/platform) or on the full [.NET Framework](https://www.microsoft.com/net/framework)

Choose a reason for hiding this comment

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

Please try to wrap lines longer than 80 characters for easier diffing later

- Develop and run your ASP.NET Core apps cross-platform on Windows, Mac and Linux
- Great for modern cloud-based apps, such as web apps, IoT apps and mobile backends
- ASP.NET Core apps can run on [.NET Core](https://www.microsoft.com/net/core/platform) or on the full [.NET Framework](https://www.microsoft.com/net/framework)
- Architected to provide an optimized development framework for apps that are deployed to the cloud or run on-premises

Choose a reason for hiding this comment

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

Maybe s/Architected/Designed

s/on-premises/on-premise

!published
```

> **Note:** If you are using Windows Containers on [Docker for Windows](https://docs.docker.com/docker-for-windows/) be sure to check that you are properly switched to Windows Containers. Do this by opening the system tray up arrow and right clicking on the Docker whale icon for a popup menu. In the popup menu make sure you select 'Switch to Windows Containers'.

Choose a reason for hiding this comment

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

Maybe link to the Docker for Windows instructions for doing this?

1. Open the command prompt and navigate to your project folder.
2. Use the following commands to build and run your Docker image:

```console

Choose a reason for hiding this comment

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

This belongs under step 2. By the way, for numbered lists, everything lines up better if you put two spaces between the dot and the first word, for single-letter bullets. This way, the codeblock (or sub-list or image or whatever) is aligned on the tab stops. Jekyll is very picky about indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great tip! I noticed my indented code blocks weren't recognized in the netlify preview. I'll add two spaces in between my numbered lists and indent the code block.

> **Note:** If you are using Windows Containers on [Docker for Windows](https://docs.docker.com/docker-for-windows/) be sure to check that you are properly switched to Windows Containers. Do this by opening the system tray up arrow and right clicking on the Docker whale icon for a popup menu. In the popup menu make sure you select 'Switch to Windows Containers'.

## Build and run the Docker image
1. Open the command prompt and navigate to your project folder.

Choose a reason for hiding this comment

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

Don't you already have the command prompt open? You already told them to run dotnet restore and stuff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is possible they ran these commands from Visual Studio or VS Code. I'll change it to "In the command prompt." Great point!

docker run -d -p 80:80 aspnetapp
```

## View your web page running from your container

Choose a reason for hiding this comment

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

This is a bit awkardly worded. Lots of "your". Maybe "View the app's live web page" or something like that?

```

## View your web page running from your container
* If you are using a Linux container you can simply browse to http://localhost:80 to access your app in a web browser.

Choose a reason for hiding this comment

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

s/you can simply/,

Also you need to linkify the URL manually. It doesn't get automatically transformed. Looks prettier with a trailing slash too.

@friism
Copy link
Contributor

friism commented Feb 15, 2017

This doesn't look good to me. I'm copy-pasting a critique I've offered to assorted others previously.

The basic problem is that the tutorial assumes users build the .NET app outside of Docker. This means the tutorial requires installing a bunch of random software on the machine for the project to build (in this case VS, .NET Core and Bower and Gulp - in addition to Docker). This nullifies one of the main reasons that developers love Docker, namely that Docker eliminates "It worked on my machine!?" problems. As currently written, to build a .NET app using this method, a developer onboarding to a project still has read through a long'ish setup readme, familiarize themselves with npm, install it, install .NET framework, etc. And woe betide you if you have the wrong version of any of that software installed, or it's misconfigured. An ops-guy will have the same headaches trying to set up and maintain a CI system.

Note that I'm not opposed to the pattern where you build a slim container for deployment. Here's a PR sent to some of Steve's code showing how this can be combined: https://github.com/SteveLasker/BuildASPDotNetInAContainer/pull/1/files

cc @glennc

@kendrahavens
Copy link
Contributor Author

Thank you @friism. That makes a lot of sense. I'll rework the doc based on your feedback.

@friism
Copy link
Contributor

friism commented Feb 17, 2017

@kendrahavens awesome, let me know if I can help.

It's a little contrived, but here's one way you could do the flow:

  1. docker run -v ${PWD}:/app --workdir /app microsoft/dotnet:1.1.0-sdk-msbuild-rc4 dotnet new mvc
  2. Add Dockerfile similar to this
  3. Show that it builds and runs
  4. Show how to add the .deploy Dockerfile
  5. Do the scripting to copy build output from builder to deploy container as done here.

@mdlinville
Copy link

Any movement on this? We'd love to get it in!

@kendrahavens
Copy link
Contributor Author

@mstanleyjones Right now we are rewriting this sample to build the app in an sdk container and then run in a runtime container. This way the user avoids needing .NET Core installed on their local machine. We are considering the work on multi-stage builds that looks right for this scenario. So our Dockerfile would look somewhat like:

FROM microsoft/dotnet:1.1-sdk-msbuild
AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY dotnetapp.csproj .
RUN dotnet restore

# copy and build everything else
COPY . .
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "out/dotnetapp.dll"]

FROM microsoft/dotnet:1.0-runtime
WORKDIR /app
COPY --context=build out .
ENTRYPOINT ["dotnet", "dotnetapp.dll"] 

Should I close this and open a new PR when the new sample is ready?

@mdlinville
Copy link

It is up to you. What is the COPY . . about? I've never seen that syntax before.

@kendrahavens
Copy link
Contributor Author

Cool! COPY is just like Add, but preferred because it is more transparent. It copies files from a source to a destination. The . is the current directory.

@friism
Copy link
Contributor

friism commented Mar 28, 2017

We are considering the work on multi-stage builds that looks right for this scenario

😍

@johndmulhausen johndmulhausen requested review from JimGalasyn and removed request for friism April 8, 2017 00:51
@johndmulhausen
Copy link

What is the overlap between this and the recently-published https://docs.docker.com/compose/aspnet-mssql-compose/ ?

@kendrahavens
Copy link
Contributor Author

We'd like to have an ASP.NET core example that demonstrates how to build with the onbuild image and deploy with the much-smaller dotnet runtime image. The doc you mentioned covers a compose scenario while there is the simpler "Dockerize an app" scenario that could be a good addition to the Docker engine examples section of the documentation.

@glennc
Copy link

glennc commented Apr 14, 2017

Multi arch will also change this, along with mutli-stage build.

@mdlinville
Copy link

Any news?

1 similar comment
@mdlinville
Copy link

Any news?

@kendrahavens
Copy link
Contributor Author

Sorry for not responding sooner! We've been holding off on merging any multi-stage build samples into our samples and guidance repos until it is part of the stable Docker for Windows channel. This shouldn't hold up adding a .NET sample to your docs though! I simply hadn't gotten to it.

@mdlinville
Copy link

Please remove the stalled label when you are ready for us to review this one again.

4. To make your build context as small as possible add a [`.dockerignore`
file](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
to
your project folder and copy the following into it.

```dockerignore

Choose a reason for hiding this comment

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

I don't think this hint works. You can probably go with config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey, I don't understand your meaning here? Could you clarify?

Choose a reason for hiding this comment

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

You can't just put anything after the three backticks to give the language "hint". I don't think dockerfile or dockerignore are supported. We aren't using the same highlighter we used to. However, dockerignore wasn't even supported on our old highlighter. You should use conf instead.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Thanks! Left some suggestions

(Network Address Translation). You must hit the IP of the container
directly. You can get the IP address of your container with the following
steps:
1. Run `docker ps` and copy the hash of your container ID.
Copy link
Member

Choose a reason for hiding this comment

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

If you name the container, this step can be simplified, i.e., in the earlier example;

$ docker run -d -p 80:80 --name myapp aspnetapp

2. Use the following commands to build and run your Docker image:

```console
docker build -t aspnetapp .
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a prompt ($) here?

```console
$ docker build -t aspnetapp .
$ docker run -d -p 80:80 aspnetapp
```


```console
docker build -t aspnetapp .
docker run -d -p 80:80 aspnetapp
Copy link
Member

Choose a reason for hiding this comment

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

it may be worth using a different published port here; port 80 may be taken already on the host, and using a different port for the host than the container can help readers understand "which side" is the container's port and which side the host's port, .e.g. -p 8080:80

2. Run `docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}"
HASH` where `HASH` is replaced with your container ID.
3. Copy the container ip address and paste into your browser with port 80.
(Ex: 172.16.240.197:80)
Copy link
Member

Choose a reason for hiding this comment

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

We generally use e.g. instead of Ex:; "(e.g., 172.16.240.197:80)"

Also may be worth emphasising the part to copy, either making it bold, or inside back tics


This example demonstrates how to dockerize an ASP.NET Core application.

## Why build ASP.NET Core?
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a blank line after all headings? It's consistent with other documents; also, I seem to recall some Markdown renderers having issues if the blank line is missing (but maybe that's no longer the case)

deployed to the cloud or run on-premise
- Modular components with minimal overhead retain flexibility while
constructing
your solutions
Copy link
Member

Choose a reason for hiding this comment

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

can you re-wrap this line?

## Create a Dockerfile for an ASP.NET Core application
1. Create a `Dockerfile` in your project folder.
2. Add the text below to your `Dockerfile` for either Linux or [Windows
Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/).
Copy link
Member

Choose a reason for hiding this comment

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

nit: Indenting looks a bit wobbly in this section (but may be GitHub's source code presentation)

screen shot 2017-07-09 at 00 27 38

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that's just how it indents when a link is line wrapped. Correct me if I'm wrong. I failed to find guidance for this.

Copy link
Member

Choose a reason for hiding this comment

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

no problem, it was just a nit anyway; perhaps you're right and it's due to it being a link that's wrapped. good call!

@mdlinville
Copy link

I can't track the place where @thaJeztah told you to use e.g. but I think it is better to say for example, in the text flow, or just leave that off. Popping into Latin that nobody remembers what it stands for can be problematic for people whose first language is not English, and the amount of benefit you get from it is very small.


## View the web page running from a container

* Go to [localhost:80](http://localhost:80) to access your app in a web browser.
Copy link
Member

Choose a reason for hiding this comment

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

This should be port 8080 now;

* Go to [localhost:8080](http://localhost:8080) to access your app in a web browser.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh shoot, sorry, I double checked in a windows container and forgot about the windows containers not mapping to ports behavior which is why it worked for port 80, but not 8080. I'll leave out the port here.

steps:
1. Run `docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" myapp`
2. Copy the container ip address and paste into your browser with port 80.
(e.g.: `172.16.240.197`:80)
Copy link
Member

Choose a reason for hiding this comment

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

can you include the :80 in the code block?

`172.16.240.197:80`

Copy link
Member

Choose a reason for hiding this comment

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

oh, this is the "e.g." @mstanleyjones was mentioning, so guess it should be

(for example, `172.16.240.197:80`)

@kendrahavens
Copy link
Contributor Author

@mstanleyjones Could you remove the stalled tag? I believe I've addressed all the requested changes.

@kendrahavens
Copy link
Contributor Author

@mstanleyjones @thaJeztah Hey folks, are there any more changes I can make? I see the deploy/netlify preview failed. Is there anything I can fix to get it passing?

@mdlinville
Copy link

I removed the stalled label. You can make Netlify start again by amending and force-pushing the commit. Let me checkout this PR and verify that it builds locally, though.

@mdlinville
Copy link

FYI there are some mistakes in the YAML of the file. You can't word-wrap in the YAML without changing the syntax of it. I'll push a commit that fixes that after I finish testing locally.

@mdlinville
Copy link

I found a few more problems, still working on this. I'll push all the commits I've added when I get this into a better state.

@kendrahavens
Copy link
Contributor Author

@mstanleyjones Thank you so much for your help on this!

@mdlinville
Copy link

@johndmulhausen I tested this locally and it works fine. Netlify is busted thinking it's against the vnext-engine branch. Can you please squash and merge this, and make sure to clean up the commit message when squashing? Thanks!

@johndmulhausen johndmulhausen merged commit c171853 into docker:master Jul 25, 2017
@johndmulhausen
Copy link

Thanks for the review @mstanleyjones !

shin- pushed a commit to shin-/docker.github.io that referenced this pull request Aug 19, 2017
Add Dockerize and ASP.NET Core doc
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.

6 participants