Dockerizing Blazor WASM Application

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.
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3. https://go.microsoft.com/fwlink/?LinkID=208121.   
  4. -->  
  5. <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
  6.   <PropertyGroup>  
  7.     <DeleteExistingFiles>True</DeleteExistingFiles>  
  8.     <ExcludeApp_Data>False</ExcludeApp_Data>  
  9.     <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>  
  10.     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>  
  11.     <LastUsedPlatform>Any CPU</LastUsedPlatform>  
  12.     <PublishProvider>FileSystem</PublishProvider>  
  13.     <PublishUrl>..\publish\webapp</PublishUrl>  
  14.     <WebPublishMethod>FileSystem</WebPublishMethod>  
  15.     <SiteUrlToLaunchAfterPublish />  
  16.     <TargetFramework>netstandard2.1</TargetFramework>  
  17.     <ProjectGuid>4b380d47-7c05-4e5e-b5a4-b4c722dd8811</ProjectGuid>  
  18.   </PropertyGroup>  
  19. </Project> 
Api
 
Publish-Linux-Alpine, the published items will be saved in \publish\webapi folder.
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3. https://go.microsoft.com/fwlink/?LinkID=208121.   
  4. -->  
  5. <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
  6.   <PropertyGroup>  
  7.     <DeleteExistingFiles>True</DeleteExistingFiles>  
  8.     <ExcludeApp_Data>False</ExcludeApp_Data>  
  9.     <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>  
  10.     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>  
  11.     <LastUsedPlatform>Any CPU</LastUsedPlatform>  
  12.     <PublishProvider>FileSystem</PublishProvider>  
  13.     <PublishUrl>..\publish\webapi</PublishUrl>  
  14.     <WebPublishMethod>FileSystem</WebPublishMethod>  
  15.     <SiteUrlToLaunchAfterPublish />  
  16.     <TargetFramework>netcoreapp3.1</TargetFramework>  
  17.     <RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>  
  18.     <PublishSingleFile>True</PublishSingleFile>  
  19.     <PublishTrimmed>True</PublishTrimmed>  
  20.     <ProjectGuid>bc6309d1-ef07-4dd5-9780-a748c860b1e1</ProjectGuid>  
  21.     <SelfContained>true</SelfContained>  
  22.   </PropertyGroup>  
  23. </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
  1. # Specify the image that will be used  
  2. # This will be pulled from Docker Image Registry  
  3. FROM nginx:alpine  
  4. # Environment variable set for Blazor.  
  5. # The enviroment variable is used in nginx   
  6. # configuration file to set up the headers.  
  7. ENV BLAZOR_ENVIRONMENT=Production  
  8. # Set the working directory in the image  
  9. WORKDIR /usr/share/nginx/html  
  10. # Copy the publish application to the workdir in image  
  11. COPY /publish/webapp/wwwroot ./  
  12. # Copy the nginx configuration file  
  13. COPY nginx.conf /etc/nginx/nginx.conf  
  14. # Copy the start script  
  15. COPY start.sh ./  
  16. # This command is optional,   
  17. # it is just used to make sure all the EOL unix compliant  
  18. RUN sed -i -e "s/\r$//" start.sh  
  19. # The command that will be executed when the container starts  
  20. CMD /bin/sh ./start.sh 
Start Script
  1. #!/bin/sh  
  2.   
  3. # The script replaces some values in the nginx configuration file  
  4. # based upon environment values set for the container  
  5. # After completion of the replacement it starts the nginx server.  
  6. # Often containers are hosted with port mappings with the host.  
  7. # This is will replace the placeholder with PORT value enviroment variable set in the   
  8. # container in the nginx configuration file.  
  9. sed -i -E "s/TO_REPLACE_PORT/${PORT:-80}/" /etc/nginx/nginx.conf  
  10. # Below will replace the placeholder in the nginx congfiguration file  
  11. sed -i -e 's/TO_REPLACE_BLAZOR_ENVIRONMENT/'"$BLAZOR_ENVIRONMENT"'/g' /etc/nginx/nginx.conf   
  12. # Start nginx service in the container  
  13. nginx -g 'daemon off;' 
nginx Configuration
  1. events { }  
  2. http {  
  3.     include mime.types;  
  4.   
  5.     types {  
  6.         application/wasm wasm;  
  7.     }  
  8.   
  9.     server {  
  10.         # This defines the port that the server will bind to. Like 80 port  
  11.         listen TO_REPLACE_PORT;  
  12.           
  13.         # This will add the environment http header to the responses  
  14.         add_header Blazor-Environment TO_REPLACE_BLAZOR_ENVIRONMENT;  
  15.         location / {  
  16.             root /usr/share/nginx/html;  
  17.             try_files $uri $uri/ /index.html =404;  
  18.         }  
  19.     }  

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 (.)
  1. 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
  1. docker run --rm -it -p 5000:80 -e BLAZOR_ENVIRONMENT=Development --name webapp basics-got-webapp  
Dockerizing Blazor WASM Application
 
WebApi - Dockerfile
  1. # Specify the image that will be used  
  2. # This will be pulled from Docker Image Registry  
  3. FROM mcr.microsoft.com/dotnet/core/runtime-deps:3.1-alpine  
  4.   
  5. # Set the working directory in the image  
  6. WORKDIR /app  
  7.   
  8. # Copy the publish application to the workdir in image  
  9. COPY /publish/webapi ./  
  10.   
  11. 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 (.)
  1. 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
  1. 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.