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 instructions for developing in a container #420

Merged
merged 20 commits into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ This image contains the operating system with all of the native dependencies nee

View [license information](https://github.com/dotnet/dotnet-docker/blob/master/LICENSE) for the software contained in this image.

The .NET Core Windows container images use the same license as the [Windows Server 2016 Nano Server base image](https://hub.docker.com/r/microsoft/nanoserver/), as follows:
The .NET Core Windows images use the same license as the [Windows Server 2016 Nano Server base image](https://hub.docker.com/r/microsoft/nanoserver/), as follows:

MICROSOFT SOFTWARE SUPPLEMENTAL LICENSE TERMS

Expand Down
2 changes: 1 addition & 1 deletion samples/README.DockerHub.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ See the following related repos for other application types:

View [license information](https://www.microsoft.com/net/dotnet_library_license.htm) for the software contained in this image.

The .NET Core Windows container images use the same license as the [Windows Server 2016 Nano Server base image](https://hub.docker.com/r/microsoft/nanoserver/), as follows:
The .NET Core Windows images use the same license as the [Windows Server 2016 Nano Server base image](https://hub.docker.com/r/microsoft/nanoserver/), as follows:

MICROSOFT SOFTWARE SUPPLEMENTAL LICENSE TERMS

Expand Down
5 changes: 5 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ docker run --rm microsoft/dotnet-samples
* [.NET Core Docker Sample](dotnetapp/README.md) - This [sample](dotnetapp/Dockerfile) builds, tests, and runs the sample. It includes and builds multiple projects.
* [ASP.NET Core Docker Sample](aspnetapp/README.md) - This [sample](aspnetapp/Dockerfile) demonstrates using Docker with an ASP.NET Core Web App.

## Develop .NET Core Apps in a Container

* [Develop .NET Core Applications](dotnetapp/dotnet-docker-dev-in-container.md) - This sample shows how to develop and test .NET Core applications with Docker without the need to install the .NET Core SDK.
* [Develop ASP.NET Core Applications](aspnetapp/aspnet-docker-dev-in-container.md) - This sample shows how to develop and test ASP.NET Core applications with Docker without the need to install the .NET Core SDK.

## Push Images to a Container Registry

* [Push Docker Images to Azure Container Registry](dotnetapp/push-image-to-acr.md)
Expand Down
18 changes: 18 additions & 0 deletions samples/aspnetapp/Directory.build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project>

<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' != 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/local/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/local/</BaseOutputPath>
</PropertyGroup>

</Project>
22 changes: 17 additions & 5 deletions samples/aspnetapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ The sample builds the application in a container based on the larger [.NET Core

This sample requires [Docker 17.06](https://docs.docker.com/release-notes/docker-ce) or later of the [Docker client](https://www.docker.com/products/docker).

The [.NET Core Docker Sample](../dotnetapp/README.md) demonstrates more functionality, including unit testing, publishing self-contained applications and using the Alpine base image. The same techniques can be applied to ASP.NET applications.

## Try a pre-built ASP.NET Core Docker Image

You can quickly try a pre-built [sample ASP.NET Core Docker image](https://hub.docker.com/r/microsoft/dotnet-samples/), based on this sample.

Type the following command to run a sample with [Docker](https://www.docker.com/products/docker):

```console
docker run --rm -p 8000:80 --name aspnetcore_sample microsoft/dotnet-samples:aspnetapp
docker run --name aspnetcore_sample --rm -it -p 8000:80 microsoft/dotnet-samples:aspnetapp
```

After the application starts, navigate to `http://localhost:8000` in your web browser. You need to navigate to the application via IP address instead of `localhost` for Windows containers, which is demonstrated in the [View the ASP.NET Core app in a running container on Windows](#view-the-aspnet-core-app-in-a-running-container-on-windows) section.
Expand All @@ -38,13 +36,13 @@ You can build and run the sample in Docker using the following commands. The ins
cd samples
cd aspnetapp
docker build --pull -t aspnetapp .
docker run --rm -p 8000:80 --name aspnetcore_sample aspnetapp
docker run --name aspnetcore_sample --rm -it -p 8000:80 aspnetapp
```

You should see the following console output as the application starts.

```console
C:\git\dotnet-docker\samples\aspnetapp>docker run --rm --name aspnetcore_sample aspnetapp
C:\git\dotnet-docker\samples\aspnetapp>docker run --name aspnetcore_sample --rm -it -p 8000:80 aspnetapp
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Expand Down Expand Up @@ -94,10 +92,24 @@ C:\git\dotnet-docker\samples\aspnetapp>docker inspect -f "{{ .NetworkSettings.Ne
172.25.157.148
```

## Deploying to Production vs Development

The approach for running containers differs between development and production.

In production, you will typically start your container with `docker run -d`. This argument starts the container as a service, without any console interaction. You then interact with it through other Docker commands or APIs exposed by the containerized application.

In development, you will typically start containers with `docker run --rm -it`. These arguments enable you to see a console (important when there are errors), terminate the container with `CTRL-C` and cleans up all container resources when the container is termiantes. You also typically don't mind blocking the console. This approach is demonstrated in prior examples in this document.

We recommend that you do not use `--rm` in production. It cleans up container resources, preventing you from collecting logs that may have been captured in a container that has either stopped or crashed.

## Build and run the sample for Linux ARM32 with Docker

You can build and run the sample for ARM32 and Raspberry Pi with [Build ASP.NET Core Applications for Raspberry Pi with Docker](aspnetcore-docker-arm32.md) instructions.

## Develop ASP.NET Core Applications in a container

You can develop applications without a .NET Core installation on your machine with the [Develop ASP.NET Core applications in a container](aspnet-docker-dev-in-container.md) instructions. These instructions are also useful if your development and production environments do not match.

## Build and run the sample locally

You can build and run the sample locally with the [.NET Core 2.0 SDK](https://www.microsoft.com/net/download/core) using the following commands. The commands assume that you are in the root of the repository.
Expand Down
65 changes: 65 additions & 0 deletions samples/aspnetapp/aspnet-docker-dev-in-container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Develop ASP.NET Core Applications in a Container

You can use containers to establish a .NET Core development environment with only Docker and optionally a code editor installed on your machine. The environment can be made to match your local machine, production or both. If you support multiple operating systems, then this approach might become a key part of your development process.

A common use case of Docker is to [containerize an application](README.md). You can define the environment necessary to run the application and even build the application itself within a Dockerfile. This document describes a much more iterative and dynamic use of Docker, defining the container environment primarily via the commandline. .NET Core includes a command called `dotnet watch` that can rerun your application or your tests on each code change. This document describes how to use the Docker CLI and `dotnet watch` to develop applications in a container.

See [Develop .NET Core Applications in a Container](../dotnetapp/aspnet-docker-dev-in-container.md) for .NET Core-specific instructions.

## Getting the sample

The easiest way to get the sample is by cloning the samples repository with [git](https://git-scm.com/downloads), using the following instructions:

```console
git clone https://github.com/dotnet/dotnet-docker/
```

You can also [download the repository as a zip](https://github.com/dotnet/dotnet-docker/archive/master.zip).

## Requirements

The instructions below use .NET Core 2.1 Preview 2 images. It is possible to make this scenario work with .NET Core 2.0 but requires many extra steps and a bit of magic. You do not need to switch to .NET Core 2.1 on your local machine to try out these instructions. They will work fine with .NET Core 2.0 projects.

It is recommended that you add a [Directory.Build.props](Directory.Build.props) file to your project to use different `obj` and `bin` folders for local and container use, to avoid conflicts between them. You should delete your existing obj and bin folders before making this change. You can also use `dotnet clean` for this purpose.

This approach relies on [volume mounting](https://docs.docker.com/engine/admin/volumes/volumes/) (that's the `-v` argument in the following commands) to mount source into the container (without using a Dockerfile). You may need to [Enable shared drives (Windows)](https://docs.docker.com/docker-for-windows/#shared-drives) or [file sharing (macOS)](https://docs.docker.com/docker-for-mac/#file-sharing) first.

## Run your application in a container while you Develop

You can re-run your application in a container with every local code change. This scenario works for both console applications and websites. The syntax differs a bit for Windows and Linux containers.

The instructions assume that you are in the root of the repository. You can use the following commands, given your environment:

**Windows** using **Linux containers**

```console
docker run --rm -it -p 8000:80 -v c:\git\dotnet-docker\samples\aspnetapp:/app/ -w /app/aspnetapp microsoft/dotnet-nightly:2.1-sdk dotnet watch run
```

Navigate to the site at `http://localhost:8000` in your browser. You can use CTRL-C to terminate `dotnet watch`. It can take up to 20s to terminate.

**macOS or Linux** using **Linux containers**

```console
docker run --rm -it -p 8000:80 -v ~/git/dotnet-docker/samples/aspnetapp:/app/ -w /app/aspnetapp microsoft/dotnet-nightly:2.1-sdk dotnet watch run
```

Navigate to the site at `http://localhost:8000` in your browser. You can use CTRL-C to terminate `dotnet watch`. It can take up to 20s to terminate.

**Windows** using **Windows containers**

`dotnet watch run` is not working correctly in containers at this time. The instructions are still documented while we work on enabling this scenario.

```console
docker run --rm -it -p 8000:80 -v c:\git\dotnet-docker\samples\aspnetapp:c:\app\ -w \app\aspnetapp --name aspnetappsample microsoft/dotnet-nightly:2.1-sdk dotnet watch run
```

In another command window, type `docker exec aspnetappsample ipconfig`. Navigate to the IP address you see in your browser.

### Updating the site while the container is running

You can demo a relaunch of the site by changing the About controller method in `HomeController.cs`, waiting a few seconds for the site to recompile and then visit `http://localhost:8000/Home/About`

## Test your application in a container while you develop

You can retest your application in a container with every local code change. You can see this demonstrated in [Develop .NET Core Applications in a Container](../dotnetapp/dotnet-docker-dev-in-container.md).
1 change: 1 addition & 0 deletions samples/aspnetapp/aspnetapp/aspnetapp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions samples/dotnetapp/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project>

<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' != 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/local/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/local/</BaseOutputPath>
</PropertyGroup>

</Project>
14 changes: 8 additions & 6 deletions samples/dotnetapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ The sample builds the application in a container based on the larger [.NET Core

This sample requires [Docker 17.06](https://docs.docker.com/release-notes/docker-ce) or later of the [Docker client](https://www.docker.com/products/docker).

The [ASP.NET Core Docker Sample](../aspnetapp/README.md) demonstrates how to use ASP.NET Core and Docker together.

## Try a pre-built .NET Core Docker Image

You can quickly try a pre-built [sample .NET Core Docker image](https://hub.docker.com/r/microsoft/dotnet-samples/), based on this sample.

Type the following command to run a sample with [Docker](https://www.docker.com/products/docker):

```console
docker run --rm microsoft/dotnet-samples
docker run --rm -it microsoft/dotnet-samples
```

## Getting the sample
Expand Down Expand Up @@ -43,7 +41,7 @@ The commands above run unit tests as part `docker build`. You can also [run .NET

```console
docker build --target testrunner -t dotnetapp:test .
docker run --rm dotnetapp:test
docker run --rm -it dotnetapp:test
```

You can mount a volume while running the image in order to save the test results to your local disk. The instructions to do that are provided in [Running Unit Tests with Docker](dotnet-docker-unit-testing.md)
Expand All @@ -67,10 +65,10 @@ You can build and run the sample with [Alpine](https://hub.docker.com/_/alpine/)
cd samples
cd dotnetapp
docker build --pull -t dotnetapp:alpine -f Dockerfile.alpine-x64 .
docker run --rm dotnetapp:alpine Hello .NET Core from Alpine
docker run --rm -it dotnetapp:alpine Hello .NET Core from Alpine
```

[Globalization is disabled](https://github.com/dotnet/announcements/issues/20) by default with Alpine images in order to produce smaller container images. You can re-enable globalization if your application relies on it. [Dockerfile.alpine-x64-globalization](Dockerfile.alpine-x64-globalization) enables globalization for Alpine images, but produces larger images.
[Globalization is disabled](https://github.com/dotnet/announcements/issues/20) by default with Alpine images in order to produce smaller images. You can re-enable globalization if your application relies on it. [Dockerfile.alpine-x64-globalization](Dockerfile.alpine-x64-globalization) enables globalization for Alpine images, but produces larger images.

> Related: [.NET Core Alpine Docker Image announcement](https://github.com/dotnet/dotnet-docker-nightly/issues/500)

Expand All @@ -82,6 +80,10 @@ You can build and run the sample for ARM32 and Raspberry Pi with [Build .NET Cor

You can build [Build .NET Core Self-Contained Applications with Docker](dotnet-docker-selfcontained.md).

## Develop ASP.NET Core Applications in a container

You can develop applications without a .NET Core installation on your machine with the [Develop .NET Core applications in a container](dotnet-docker-dev-in-container.md) instructions. These instructions are also useful if your development and production environments do not match.

## Run Docker Image on Another Device

You can push the image to a container registry so that you can pull and run it on another device. Straightforward instructions are provided for pushing to both Azure Container Registry and DockerHub.
Expand Down
Loading