The article is a continuation of my previous article
Blazor WASM Application, in which a Blazor application was created.
Publish Profiles
For Docker images, the below publish profiles are used.
BlazorWebApp
Publish-Release, the published items will be saved in \publish\webapp folder.
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- https:
- -->
- <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <DeleteExistingFiles>True</DeleteExistingFiles>
- <ExcludeApp_Data>False</ExcludeApp_Data>
- <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
- <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
- <LastUsedPlatform>Any CPU</LastUsedPlatform>
- <PublishProvider>FileSystem</PublishProvider>
- <PublishUrl>..\publish\webapp</PublishUrl>
- <WebPublishMethod>FileSystem</WebPublishMethod>
- <SiteUrlToLaunchAfterPublish />
- <TargetFramework>netstandard2.1</TargetFramework>
- <ProjectGuid>4b380d47-7c05-4e5e-b5a4-b4c722dd8811</ProjectGuid>
- </PropertyGroup>
- </Project>
Api
Publish-Linux-Alpine, the published items will be saved in \publish\webapi folder.
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- https:
- -->
- <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <DeleteExistingFiles>True</DeleteExistingFiles>
- <ExcludeApp_Data>False</ExcludeApp_Data>
- <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
- <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
- <LastUsedPlatform>Any CPU</LastUsedPlatform>
- <PublishProvider>FileSystem</PublishProvider>
- <PublishUrl>..\publish\webapi</PublishUrl>
- <WebPublishMethod>FileSystem</WebPublishMethod>
- <SiteUrlToLaunchAfterPublish />
- <TargetFramework>netcoreapp3.1</TargetFramework>
- <RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
- <PublishSingleFile>True</PublishSingleFile>
- <PublishTrimmed>True</PublishTrimmed>
- <ProjectGuid>bc6309d1-ef07-4dd5-9780-a748c860b1e1</ProjectGuid>
- <SelfContained>true</SelfContained>
- </PropertyGroup>
- </Project>
Before making the docker images, publish both projects with the publish profiles.
Docker Images
To run the applications in containers, Alpine Linux images are used. There will be two seperate images for the BlazorWebApp & Api.
BlazorWebApp
Since BlazorWebApp is a WebAssembly project, it can run under any HTTP Server. There is no dependency on any .Net Core Runtime on the server.
Nginx is used for serving the application. The base docker image used is nginx:alpine which is an Alpine linux image with Nginx dependency
Docker Hub.
Dockerfile
- # Specify the image that will be used
- # This will be pulled from Docker Image Registry
- FROM nginx:alpine
- # Environment variable set for Blazor.
- # The enviroment variable is used in nginx
- # configuration file to set up the headers.
- ENV BLAZOR_ENVIRONMENT=Production
- # Set the working directory in the image
- WORKDIR /usr/share/nginx/html
- # Copy the publish application to the workdir in image
- COPY /publish/webapp/wwwroot ./
- # Copy the nginx configuration file
- COPY nginx.conf /etc/nginx/nginx.conf
- # Copy the start script
- COPY start.sh ./
- # This command is optional,
- # it is just used to make sure all the EOL unix compliant
- RUN sed -i -e "s/\r$//" start.sh
- # The command that will be executed when the container starts
- CMD /bin/sh ./start.sh
Start Script
- #!/bin/sh
-
- # The script replaces some values in the nginx configuration file
- # based upon environment values set for the container
- # After completion of the replacement it starts the nginx server.
- # Often containers are hosted with port mappings with the host.
- # This is will replace the placeholder with PORT value enviroment variable set in the
- # container in the nginx configuration file.
- sed -i -E "s/TO_REPLACE_PORT/${PORT:-80}/" /etc/nginx/nginx.conf
- # Below will replace the placeholder in the nginx congfiguration file
- sed -i -e 's/TO_REPLACE_BLAZOR_ENVIRONMENT/'"$BLAZOR_ENVIRONMENT"'/g' /etc/nginx/nginx.conf
- # Start nginx service in the container
- nginx -g 'daemon off;'
nginx Configuration
- events { }
- http {
- include mime.types;
-
- types {
- application/wasm wasm;
- }
-
- server {
- # This defines the port that the server will bind to. Like 80 port
- listen TO_REPLACE_PORT;
-
- # This will add the environment http header to the responses
- add_header Blazor-Environment TO_REPLACE_BLAZOR_ENVIRONMENT;
- location / {
- root /usr/share/nginx/html;
- try_files $uri $uri/ /index.html =404;
- }
- }
- }
Docker Command
To create the docker image the following command is used.This will build an image tag as basics-got-webapp, and read docker config from Dockerfile.BlazorWebApp which is found in the current folder (.)
- docker build --pull -t basics-got-webapp -f Dockerfile.BlazorWebApp .
To test the image that is created, this will run the container on external 5000 port, so it can be accessed at http://localhost:5000
- docker run --rm -it -p 5000:80 -e BLAZOR_ENVIRONMENT=Development --name webapp basics-got-webapp
WebApi - Dockerfile
- # Specify the image that will be used
- # This will be pulled from Docker Image Registry
- FROM mcr.microsoft.com/dotnet/core/runtime-deps:3.1-alpine
-
- # Set the working directory in the image
- WORKDIR /app
-
- # Copy the publish application to the workdir in image
- COPY /publish/webapi ./
-
- ENTRYPOINT ["./Basics.GameOfThrones.Api"]
Docker Command
To create the docker image the following command is used.
This will build an image tag as basics-got-api, and read docker config
from Dockerfile.WebApi which is found in the current folder (.)
- docker build --pull -t basics-got-api -f Dockerfile.WebApi .
To test the image that is created, this will run the container on external 5010 port, so it can be accesed at http://localhost:5010
- docker run --rm -it -p 5010:80 -e ASPNETCORE_ENVIRONMENT=Development --name webapi basics-got-api
I hope the article helps in understanding how to dockerize an Blazor WASM Applications.
Source code is available on
GitHub.