Let’s now see how to publish the application to any cloud provider that supports Docker containers, like Heroku. To get started, I will go over the Dockerfile that will build the image that we can then host in Heroku:
# build image FROM microsoft/aspnetcore-build:2.0.3 as build WORKDIR /app COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out # runtime image FROM microsoft/aspnetcore:2.0.3 ENV PORT=5000 WORKDIR /app COPY --from=build /app/out . CMD ASPNETCORE_URLS=http://*:$PORT dotnet Daycare.dll
First, notice that the file uses multi-stage builds, which is a Docker feature that allows to create intermediate images that can be used as the source of the final image to build. In this case, the first stage will use a base image that has enough tools in it to build the application, the second stage will use the result of the first to load the application into a base image that just has the .NET Core runtime. If you are interested in a step by step description:
- Line #2 get the aspnetcore-build image, which is published by Microsoft and not only does it have the .NET Core SDK installed, but also node.js.
- Line #5 copies the .csproj file into the image and then runs dotnet restore to pull all .NET dependencies into the image. Why are only the .csproj files copied instead of all the source code? Becase Docker caches the result of every step, so as long as the csproj file hasn’t changed subsequent builds won’t have to keep running dotnet restore over and over.
- Line #8 copies the rest of the source code and runs dotnet publish. Remember from my previous post that this command will download all node dependencies AND run webpack to create the production assets. The whole application will be placed in an ‘out’ folder.
- Line #12 the second stage begins and gets the aspnetcore base image. This image has only the runtime bits and is smaller than the build image.
- Line #15 copies the output from the first stage into this new image.
- Line #16 starts the application in a special way. This has to do with how Heroku expects images to be built in order to host them:
- First, you cannot use the ENTRYPOINT command, so you have to fall back to use the CMD command.
- Second, Heroku exposes a random port for your container and makes it available on a $PORT variable. We need to pass this port down to kestrel, fortunately, ASP.NET Core reads an environment variable named ‘ASPNETCORE_URLS’ that can be used to configure kestrel. So the CMD command, first sets the environment variable using the $PORT set by Heroku and then launches the application using the dotnet command.
Running the ‘docker build’ command will create the image that is ready for production. In the next post, I’ll go over how to test it and deploy it to the host. You can see the website hosted in Heroku here or browse the sources at the project page.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.