'How to deploy Blazor WebAssembly as static site in GitLab Pages
I can't find any guide on how to deploy a Blazor web assembly app to GitLab Pages as a static site. Has anyone managed to do so for .NET 6?
I have created a sample web assembly Blazor client application:
https://gitlab.com/sunnyatticsoftware/sasw-community/sasw-editor
The steps to create this simple web assembly are:
- Install .NET 6 SDK
- Create repo and clone it (e.g:
sasw-editor
) - Create the solution with web assembly Blazor project
dotnet new gitignore dotnet new blazorwasm --name Sasw.Editor.Web --output src/Sasw.Editor.Web --no-https dotnet new sln dotnet sln add src/Sasw.Editor.Web
- Compile and run it
dotnet build dotnet run --project src/Sasw.Editor.Web
That's a way to run the blazor app on the port defined at the launchsettings.json
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5291
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\src\sasw-editor\src\Sasw.Editor.Web
I stop it. It works fine when served with Kestrel.
Now, the process to publish a distribution folder would be like this
dotnet publish -c Release -o publish
All the artifacts and files are now under publish
folder. So, in theory, I can serve those things with a simple web server. I install a basic web server tool called local-web-server
(it requires NodeJs/npm but you can use any other web server)
npm install -g local-web-server
Now I navigate to the publish/wwwroot
folder where my index.html
is
And I start the web server there
ws
Listening on http://5CD013DP5L:8000, http://192.168.1.13:8000, http://127.0.0.1:8000, http://172.21.208.1:8000
If I open the browser on http://127.0.0.1:8000
, or any other of the above url, I can see my Blazor wasm app working perfectly.
I want to host that very same publish
folder in GitLab pages which, in theory, is capable of serving static files.
So I create a .gitlab-ci.yml
to compile, publish and copy contents to the public folder of GitLab pages.
image: mcr.microsoft.com/dotnet/sdk:6.0
variables:
GIT_DEPTH: 1000
PUBLISH_OUTPUT_DIR: publish
stages:
- build
- test
- publish
- delivery
build:
stage: build
script:
- dotnet restore --no-cache --force
- dotnet build --configuration Release --no-restore
artifacts:
paths:
- test
expire_in: 8 hour
rules:
- if: $CI_COMMIT_TAG
when: never
- when: always
test:
stage: test
script: dotnet test --blame --configuration Release
allow_failure: false
rules:
- if: $CI_COMMIT_TAG
when: never
- exists:
- test/**/*Tests.csproj
publish:
stage: publish
script:
- dotnet publish -c Release -o $PUBLISH_OUTPUT_DIR
artifacts:
paths:
- $PUBLISH_OUTPUT_DIR/
expire_in: 8 hour
rules:
- if: $CI_COMMIT_TAG
when: never
- when: on_success
pages:
stage: delivery
script:
- cp -a $PUBLISH_OUTPUT_DIR/ public
artifacts:
paths:
- public
only:
- main
The pipeline completes successfully. I can see the exact same structure I had locally within publish
folder, this time under public
folder in GitLab
But it fails to render the app https://sunnyatticsoftware.gitlab.io/-/sasw-community/sasw-editor/-/jobs/1846501612/artifacts/public/wwwroot/index.html
shows
Loading...
An unhandled error has occurred. Reload 🗙
I can see it's attempting to access https://sunnyatticsoftware.gitlab.io/
or https://sunnyatticsoftware.gitlab.io/favicon.ico
and returning 404
The favicon.ico
would exist on https://sunnyatticsoftware.gitlab.io/-/sasw-community/sasw-editor/-/jobs/1846501612/artifacts/public/wwwroot/favicon.ico
so it must be some kind of URL re-write problem, right?
Any help would be much appreciated.
Solution 1:[1]
The solution is simply to use the following
pages:
stage: delivery
script:
- cp -a $PUBLISH_OUTPUT_DIR/wwwroot public
artifacts:
paths:
- public
only:
- main
and to use the <base href="/sasw-community/sasw-editor/" />
in index.html
with the relative path.
I've recorded a quick tutorial on my Odysee channel https://odysee.com/@sunnyAtticSoftware:a/blazor-wasm-gitlab-pages:e
See https://gitlab.com/sunnyatticsoftware/training/blazorwasm-pages with a full sample
I still don't know of a good way to mix local development's base /
relative path with prod base /sasw-community/sasw-editor/
and change it dynamically (is it even possible?)
But the problem is solved.
Solution 2:[2]
Always keep it at base href="/"
and then in your ci change it to whatever you need. E.g. on gitlab you can use the CI_PROJECT_NAME
variable.
pages:
stage: deploy
variables:
SED_COMMAND: 's#<base\shref="\/"\s?\/>#<base href="\/$CI_PROJECT_NAME\/" \/>#g'
script:
- cp -a $PUBLISH_OUTPUT_DIR/wwwroot public
- sed -r -i "$SED_COMMAND" public/index.html
artifacts:
paths:
- public
only:
- main
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Alexander Schulz |