From ae58c1a631db26f22460e1d80aaf53fb3fba16af Mon Sep 17 00:00:00 2001 From: MichaelSimons Date: Fri, 3 Nov 2017 17:07:18 -0500 Subject: [PATCH 1/2] Add sample to illustrate usage of the Alpine preview images --- README.md | 7 ++ dotnetapp-prod-alpine-preview/.dockerignore | 2 + dotnetapp-prod-alpine-preview/Dockerfile | 18 +++++ .../Dockerfile.globalization | 25 +++++++ dotnetapp-prod-alpine-preview/NuGet.config | 9 +++ dotnetapp-prod-alpine-preview/Program.cs | 71 +++++++++++++++++++ dotnetapp-prod-alpine-preview/README.md | 56 +++++++++++++++ .../dotnetapp.csproj | 10 +++ 8 files changed, 198 insertions(+) create mode 100644 dotnetapp-prod-alpine-preview/.dockerignore create mode 100644 dotnetapp-prod-alpine-preview/Dockerfile create mode 100644 dotnetapp-prod-alpine-preview/Dockerfile.globalization create mode 100644 dotnetapp-prod-alpine-preview/NuGet.config create mode 100644 dotnetapp-prod-alpine-preview/Program.cs create mode 100644 dotnetapp-prod-alpine-preview/README.md create mode 100644 dotnetapp-prod-alpine-preview/dotnetapp.csproj diff --git a/README.md b/README.md index 9ae8710..5ab4ad4 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,13 @@ The following samples show different ways to use .NET Core images. * [.NET Core self-contained application Docker Production Sample](dotnetapp-selfcontained) - This sample includes instructions for running a self-contained image with Linux on a Raspberry Pi. * Related: See [.NET Core on Raspberry Pi](https://github.com/dotnet/core/blob/master/samples/RaspberryPiInstructions.md) +### Alpine Preview + +* [.NET Core Docker Alpine Production Sample](dotnetapp-prod-alpine-preview) - This sample illustrates how to use the new lightweight Alpine based .NET Core Runtime image that is currently in preview. + +>**TODO** +* Related: See [.NET Core Alpine Image](https://gist.github.com/richlander/9529644df6df25e902682aee7f5c0846) + ## Related Repositories See the following related Docker Hub repos: diff --git a/dotnetapp-prod-alpine-preview/.dockerignore b/dotnetapp-prod-alpine-preview/.dockerignore new file mode 100644 index 0000000..cd42ee3 --- /dev/null +++ b/dotnetapp-prod-alpine-preview/.dockerignore @@ -0,0 +1,2 @@ +bin/ +obj/ diff --git a/dotnetapp-prod-alpine-preview/Dockerfile b/dotnetapp-prod-alpine-preview/Dockerfile new file mode 100644 index 0000000..18be011 --- /dev/null +++ b/dotnetapp-prod-alpine-preview/Dockerfile @@ -0,0 +1,18 @@ +FROM microsoft/dotnet-nightly:2.1-sdk AS build-env +WORKDIR /app + +# copy csproj and restore as distinct layers +COPY *.csproj ./ +COPY NuGet.config ./ +RUN dotnet restore + +# copy everything else and build +COPY . ./ +RUN dotnet publish -c Release -o out --no-restore + + +# build runtime image +FROM microsoft/dotnet-nightly:2.1-runtime-alpine +WORKDIR /app +COPY --from=build-env /app/out ./ +ENTRYPOINT ["dotnet", "dotnetapp.dll"] diff --git a/dotnetapp-prod-alpine-preview/Dockerfile.globalization b/dotnetapp-prod-alpine-preview/Dockerfile.globalization new file mode 100644 index 0000000..4d6f05c --- /dev/null +++ b/dotnetapp-prod-alpine-preview/Dockerfile.globalization @@ -0,0 +1,25 @@ +FROM microsoft/dotnet-nightly:2.1-sdk AS build-env +WORKDIR /app + +# copy csproj and restore as distinct layers +COPY *.csproj ./ +COPY NuGet.config ./ +RUN dotnet restore + +# copy everything else and build +COPY . ./ +RUN dotnet publish -c Release -o out --no-restore + + +# build runtime image +FROM microsoft/dotnet-nightly:2.1-runtime-alpine + +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false +RUN apk add --no-cache icu-libs + +ENV LC_ALL en_US.UTF-8 +ENV LANG en_US.UTF-8 + +WORKDIR /app +COPY --from=build-env /app/out ./ +ENTRYPOINT ["dotnet", "dotnetapp.dll"] diff --git a/dotnetapp-prod-alpine-preview/NuGet.config b/dotnetapp-prod-alpine-preview/NuGet.config new file mode 100644 index 0000000..f1c634b --- /dev/null +++ b/dotnetapp-prod-alpine-preview/NuGet.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dotnetapp-prod-alpine-preview/Program.cs b/dotnetapp-prod-alpine-preview/Program.cs new file mode 100644 index 0000000..3ce37e3 --- /dev/null +++ b/dotnetapp-prod-alpine-preview/Program.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using System.Globalization; +using static System.Console; + +public static class Program +{ + public static void Main(string[] args) + { + string message = "Dotnet-bot: Welcome to using .NET Core!"; + + if (args.Length > 0) + { + message = String.Join(" ", args); + } + + WriteLine(GetBot(message)); + WriteLine("**Environment**"); + WriteLine($"Platform: .NET Core 2.0"); + WriteLine($"OS: {RuntimeInformation.OSDescription}"); + WriteLine($"Culture: {CultureInfo.CurrentCulture.DisplayName}"); + WriteLine(); + } + + public static string GetBot(string message) + { + string bot = $"\n {message}"; + bot += @" + __________________ + \ + \ + .... + ....' + .... + .......... + .............'..'.. + ................'..'..... + .......'..........'..'..'.... + ........'..........'..'..'..... + .'....'..'..........'..'.......'. + .'..................'... ...... + . ......'......... ..... + . ...... + .. . .. ...... + .... . ....... + ...... ....... ............ + ................ ...................... + ........................'................ + ......................'..'...... ....... + .........................'..'..... ....... + ........ ..'.............'..'.... .......... + ..'..'... ...............'....... .......... + ...'...... ...... .......... ...... ....... + ........... ....... ........ ...... +....... '...'.'. '.'.'.' .... +....... .....'.. ..'..... + .. .......... ..'........ + ............ .............. + ............. '.............. + ...........'.. .'.'............ + ............... .'.'............. + .............'.. ..'..'........... + ............... .'.............. + ......... .............. + ..... + +"; + return bot; + } +} diff --git a/dotnetapp-prod-alpine-preview/README.md b/dotnetapp-prod-alpine-preview/README.md new file mode 100644 index 0000000..2ac7030 --- /dev/null +++ b/dotnetapp-prod-alpine-preview/README.md @@ -0,0 +1,56 @@ +# .NET Core Docker Alpine Production Sample (Preview) + +This .NET Core Docker sample demonstrates a best practice pattern for building Alpine based Docker images for .NET Core apps for production. The primary goal of Alpine is very small deployments. Images can be pulled quicker and will have a smaller attack surface area. The .NET Core Alpine Docker images are currently in preview. See the [.NET Core Alpine Docker Image announcement](https://gist.github.com/richlander/9529644df6df25e902682aee7f5c0846) for additional details. + +The [sample Dockerfile](Dockerfile) creates an .NET Core application Docker image based off of the [.NET Core Runtime Alpine Preview Docker image](https://hub.docker.com/r/microsoft/dotnet-nightly/). + +It uses the [Docker multi-stage build feature](https://github.com/dotnet/announcements/issues/18) to build the sample in a container based on the larger [.NET Core SDK Docker base image](https://hub.docker.com/r/microsoft/dotnet/) and then copies the final build result into a Docker image based on the smaller [.NET Core Docker Runtime base image](https://hub.docker.com/r/microsoft/dotnet/). The SDK image contains tools that are required to build applications while the runtime image does not. + +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). You need the latest Windows 10 or Windows Server 2016 to use [Windows containers](http://aka.ms/windowscontainers). The instructions assume you have the [Git](https://git-scm.com/downloads) client installed. + +## Getting the sample + +The easiest way to get the sample is by cloning the samples repository with git, using the following instructions. You can also just download the repository (it is small) as a zip from the [.NET Core Docker samples](https://github.com/dotnet/dotnet-docker-samples/) respository. + +```console +git clone https://github.com/dotnet/dotnet-docker-samples/ +``` + +## Build and run the sample with Docker + +You can build and run the sample in Docker using the following commands. The instructions assume that you are in the root of the repository. + +```console +cd dotnetapp-prod-alpine-preview +docker build -t dotnetapp-prod-alpine-preview . +docker run --rm dotnetapp-prod-alpine-previewHello .NET Core from Docker +``` + +Note: The instructions above work only with Linux containers. + +## Build and run the sample without the Globalization Invariant Mode + +The Alpine based .NET Core Runtime Docker image has the [.NET Core 2.0 Globalization Invariant Mode](https://github.com/dotnet/announcements/issues/20) enabled in order to reduce the default size of the image. Use cases that cannot tolerate Globalization Invariant Mode can reset the `DOTNET_SYSTEM_GLOBALIZATION_INVARIANT` environment variable and install the required ICU package. The [Globalization Dockerfile](Dockerfile.globalization) illustrates how this can be done. + +You can build and run the sample in Docker using the following commands. The instructions assume that you are in the root of the repository. + +```console +cd dotnetapp-prod-alpine-preview +docker build -t dotnetapp-prod-alpine-preview -f Dockerfile.globalization . +docker run --rm dotnetapp-prod-alpine-previewHello .NET Core from Docker +``` + +Note: The instructions above work only with Linux containers. + +## Docker Images used in this sample + +The following Docker images are used in this sample + +* [microsoft/dotnet-nightly:2.1-sdk](https://hub.docker.com/r/microsoft/dotnet-nightly) +* [microsoft/dotnet-nightly:2.1-runtime-alpine](https://hub.docker.com/r/microsoft/dotnet-nightly) + +## Related Resources + +* [ASP.NET Core Production Docker sample](../aspnetapp/README.md) +* [.NET Core Docker samples](../README.md) +* [.NET Framework Docker samples](https://github.com/Microsoft/dotnet-framework-docker-samples) diff --git a/dotnetapp-prod-alpine-preview/dotnetapp.csproj b/dotnetapp-prod-alpine-preview/dotnetapp.csproj new file mode 100644 index 0000000..58ef7d9 --- /dev/null +++ b/dotnetapp-prod-alpine-preview/dotnetapp.csproj @@ -0,0 +1,10 @@ + + + + + Exe + netcoreapp2.1 + 2.1.0-preview1-25919-02 + + + From 1a35020ad7bd98b0e19cc475162dffb4182ce9a9 Mon Sep 17 00:00:00 2001 From: MichaelSimons Date: Tue, 21 Nov 2017 12:55:49 -0600 Subject: [PATCH 2/2] Update announcement link and added missing space --- README.md | 3 +-- dotnetapp-prod-alpine-preview/README.md | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5ab4ad4..358e26c 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,7 @@ The following samples show different ways to use .NET Core images. * [.NET Core Docker Alpine Production Sample](dotnetapp-prod-alpine-preview) - This sample illustrates how to use the new lightweight Alpine based .NET Core Runtime image that is currently in preview. ->**TODO** -* Related: See [.NET Core Alpine Image](https://gist.github.com/richlander/9529644df6df25e902682aee7f5c0846) +* Related: See [.NET Core Alpine Docker Image announcement](https://github.com/dotnet/dotnet-docker-nightly/issues/500) ## Related Repositories diff --git a/dotnetapp-prod-alpine-preview/README.md b/dotnetapp-prod-alpine-preview/README.md index 2ac7030..9b4637f 100644 --- a/dotnetapp-prod-alpine-preview/README.md +++ b/dotnetapp-prod-alpine-preview/README.md @@ -1,6 +1,6 @@ # .NET Core Docker Alpine Production Sample (Preview) -This .NET Core Docker sample demonstrates a best practice pattern for building Alpine based Docker images for .NET Core apps for production. The primary goal of Alpine is very small deployments. Images can be pulled quicker and will have a smaller attack surface area. The .NET Core Alpine Docker images are currently in preview. See the [.NET Core Alpine Docker Image announcement](https://gist.github.com/richlander/9529644df6df25e902682aee7f5c0846) for additional details. +This .NET Core Docker sample demonstrates a best practice pattern for building Alpine based Docker images for .NET Core apps for production. The primary goal of Alpine is very small deployments. Images can be pulled quicker and will have a smaller attack surface area. The .NET Core Alpine Docker images are currently in preview. See the [.NET Core Alpine Docker Image announcement](https://github.com/dotnet/dotnet-docker-nightly/issues/500) for additional details. The [sample Dockerfile](Dockerfile) creates an .NET Core application Docker image based off of the [.NET Core Runtime Alpine Preview Docker image](https://hub.docker.com/r/microsoft/dotnet-nightly/). @@ -23,7 +23,7 @@ You can build and run the sample in Docker using the following commands. The ins ```console cd dotnetapp-prod-alpine-preview docker build -t dotnetapp-prod-alpine-preview . -docker run --rm dotnetapp-prod-alpine-previewHello .NET Core from Docker +docker run --rm dotnetapp-prod-alpine-preview Hello .NET Core from Docker ``` Note: The instructions above work only with Linux containers. @@ -37,7 +37,7 @@ You can build and run the sample in Docker using the following commands. The ins ```console cd dotnetapp-prod-alpine-preview docker build -t dotnetapp-prod-alpine-preview -f Dockerfile.globalization . -docker run --rm dotnetapp-prod-alpine-previewHello .NET Core from Docker +docker run --rm dotnetapp-prod-alpine-preview Hello .NET Core from Docker ``` Note: The instructions above work only with Linux containers.