This tutorial is about containerizing both an ASP.NET WebAPI and a client-side (Web Assembly) Blazor application. We will be using Visual Studio Code in this walkthrough. At the time of writing this post, the current .NET version is 5.0. Also, the client-side Blazor application will be hosted by the nginx web-server running inside a docker container.
Source code: https://github.com/medhatelmasry/BlazorWithAPI.git
Creating and running the applications
Start with creating a working directory named BlazorWithAPI and a solution file:
mkdir BlazorWithAPI
cd BlazorWithAPI
dotnet new sln
Next, create a WebAPI project without HTTPS and it to the solution file.
dotnet new webapi --no-https -o WeatherAPI
dotnet sln add WeatherAPI/WeatherAPI.csproj
Finally, create a client-side Blazor project without HTTPS and it to the same solution file.
dotnet new blazorwasm --no-https -o BlazorClient
dotnet sln add BlazorClient/BlazorClient.csproj
Let us run the WebAPI application.
cd WeatherAPI
dotnet run
If you point your browser to http://localhost:5000/Weatherforecast, you will see the default WeatherForecast service:
Before we start working on our client-side Blazor application, that will consume the API service, we need to make two changes to our WeatherAPI application:
- Stop the WeatherAPI application by hitting CTRL C in the terminal window
- Open the WeatherAPI project in VS Code.
- Edit Properties/launchSettings.json. Around line 25, change 5000 to 3000.
- Open Startup.cs in the editor.
- Add the following code to the ConfigureServices() method
services.AddCors(o => o.AddPolicy("CorsPolicy", builder => {
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
}));
- Add the following code to the Configure() method in Startup.cs just before app.UseAuthorization():
app.UseCors();
Open Controllers/WeatherForecastController.cs in the editor and add the following annotation to the class declaration just under [ApiController]:
[EnableCors("CorsPolicy")]
- Restart the WeatherAPI application with 'dotnet run'.
You will see that the port number is now 3000.
We will next focus on consuming our WeatherAPI service from a client-side Blazor application. Open the BlazorClient project in VS Code. Edit Pages/FetchData.razor. Around line 42 . . .
CHANGE:
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
TO:
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("http://localhost:3000/Weatherforecast");
We can start testing our client-side Blazor app to make sure that it is reading weather data from our service. Start the BlazorClient app by typing the following in a terminal window at the root of the project:
dotnet run
Note: The Blazor app listens on port 5000 and the API app listens on port 3000.
Point your browser to http://localhost:5000. When the Blazor app loads in the browser, click on 'Fetch data" on the left-side navigation. You should see data being read from the API service:
Docker-izing both applications
To docker-ize our applications, we will need to add a Dockerfile to each project. Let's start with the WeatherAPI project.
Dockerizing WeatherAPI application
Create a Dockerfile at the root of the WeatherAPI project and add to it the following code:
FROM mcr.microsoft.com/dotnet/core/aspnet:5.0-bionicCOPY WeatherAPI/dist /appWORKDIR /appEXPOSE 80/tcpEXPOSE 443/tcpENTRYPOINT ["dotnet", "WeatherAPI.dll"]
NOTE: Adjust the name WeatherAPI based on whatever you named your project.
Dockerizing BlazorClient application
We will be using the nginx web server to host the static client-side Blazor artifacts inside the container. Therefore, we will be using an nginx based docker container.
At the root of the BlazorClient project, create two files: one named nginx.conf and the other named Dockerfile.
This configuration file is used to set the nginx document root and also to enable the delivery of .wasm files. Add the following code to nginx.conf:
events { }http {include mime.types;types {application/wasm wasm;}server {listen 80;index index.html;location / {root /var/www/web;try_files $uri $uri/ /index.html =404;}}}
Add the following code to Dockerfile:
FROM nginx:alpineWORKDIR /var/www/webCOPY BlazorClient/dist/wwwroot .COPY BlazorClient/nginx.conf /etc/nginx/nginx.confEXPOSE 80
Make sure you stop all running applications.
Before we can containerize our applications, we must first publish the release version of each app separately. To facilitate this process, I created a batch file in the solution folder that publishes each application to a folder named dist. Therefore, inside the folder that contains the .sln file, create a file named pblsh.cmd in Windows. You can use the same ideas for other operating systems like macOS or Linux.
Content of pblsh.cmd on Windows
cd WeatherAPIrmdir /Q /S distdotnet publish -o distcd ..cd BlazorClientrmdir /Q /S distdotnet publish -o distcd ..
Content of pblsh.sh on mac
cd WeatherAPI
rm -rf dist
dotnet publish -o dist
cd ..
cd BlazorClient
rm -rf dist
dotnet publish -o dist
cd ..
NOTE: Adjust the project names WeatherAPI and BlazorClient to suit your own project names.
docker-compose.yml file
We can now orchestrate multi-container Docker applications with docker-compose.yml. In the same solution director, create a text file named docker-compose.yml and add to it the following content:
services:
webapi:
build:
context: .
dockerfile: WeatherAPI/Dockerfile
ports:
- "3000:80"
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=Development
wasm:
build:
context: .
dockerfile: BlazorClient/Dockerfile
depends_on:
- webapi
ports:
- 8888:80
Running pblsh.cmd & docker-compose-yml
At a terminal window inside the solution folder, run the following command to publish each application separately:
'pblsh.cmd' on Windows or 'bash ./pblst.sh' on mac
Next, run docker-compose by simply entering the following instruction in the same terminal window:
docker-compose up
Wait until the terminal window settles down. To view the containerized client-side Blazor application, point your browser to https://localhost:8888 then click on "Fetch data". You should see your container hosted app being displayed in your browser:
Cleanup
To cleanup your environment by stopping and removing the running containers, hit CTRL C in the terminal window. Thereafter, enter the following command:
docker-compose down
Conclusion
I hope you found what you are looking for in this short article about how to docker-ize a client-side Blazor application under the nginx web server.
No comments:
Post a Comment