Blazor Server as a Windows Service

Blazor Server as a Windows Service is very easy, but there are not many articles talking about this, so I decided to write this.

Install NuGet Package

Install Microsoft.Extensions.Hosting.WindowsServices from NuGet Package Manager.

Edit Program.cs

Add using Microsoft.Extensions.Hosting.WindowsServices;.

using Microsoft.Extensions.Hosting.WindowsServices;

Change var builder = WebApplication.CreateBuilder(args); to the following code. ContentRootPath is required for Windows Service, otherwise the service will fail to the start.

var builder = WebApplication.CreateBuilder(new WebApplicationOptions()
    ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default,
    Args = args

Add this before var app = builder.Build();.


Publish the app

Publish your app and click Open folder and grab your program exe path.

Create and start the Windows Service

Run cmd.exe as administrator.

Create a Service with the following command. The <BIN_PATH> should be your program exe path.

sc create <SERVICE_NAME> binPath="<BIN_PATH>"


sc create WindowsGSM binPath="D:\WindowsGSM\WindowsGSM\bin\Release\net6.0\publish\WindowsGSM.exe"

Start the Service with the following command.

net start <SERVICE_NAME>


net start WindowsGSM

Your app should be now started as Windows Service. ๐Ÿ‘
If your service fail to start, you may run Event Viewer program on Windows to see the service log. Good luck!

Blazor MudPasswordField

Just created a small razor script that works like this. It works basically the same as MudTextField but with an eye to toggle the mask. ๐Ÿ‘

The MudPasswordField.razor


<MudPasswordField Label="Game Server Login Token (GSLT)" />

Happy Blazor!

How to setup Remark42 with Docker


Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engine, which doesn't spy on users. It can be embedded into blogs, articles or any other place where readers add comments.

This tutorial will walk you through setting up Remark42 on Ubuntu with Apache2 and Docker.


  • Apache2
  • Docker

If you haven't install Docker

sudo snap install docker

Install Remark42 with Docker

Official Guide:

Copy provided docker-compose.yml and customize for your needs. You can create a folder first and paste the docker-compose.yml inside the folder. Source:

Here is my docker-compose.yml.

version: '2'

        build: .
        image: umputun/remark42:latest
        container_name: "remark42"
        restart: always

            driver: json-file
                max-size: "10m"
                max-file: "5"

          - "8888:8080"

            - REMARK_URL=
            - SITE=tatlead
            - SECRET=*******
            - STORE_BOLT_PATH=/srv/var/db
            - BACKUP_PATH=/srv/var/backup
            - DEBUG=true
            - AUTH_GOOGLE_CID
            - AUTH_GOOGLE_CSEC
            - AUTH_GITHUB_CID=*******
            - AUTH_GITHUB_CSEC=*******
            - AUTH_FACEBOOK_CID
            - AUTH_FACEBOOK_CSEC
            - AUTH_DISQUS_CID
            - AUTH_DISQUS_CSEC
            - ADMIN_SHARED_ID
            # - ADMIN_PASSWD=password
            - ./var:/srv/var

Pull the umputun/remark42:latest image from the DockerHub

docker-compose pull


docker-compose up -d

Your remark42 server is running on ๐Ÿ‘

Setup Apache2 reverse proxy

Goto /etc/apache2/sites-enabled/, create or edit a .conf file. We will create the file on this example.

sudo nano remark42.conf

My .conf settings

<VirtualHost *:443>

    ProxyRequests Off
    ProxyPreserveHost On

    <Proxy *>
        Order deny,allow
        Allow from all

    Header unset X-Frame-Options
    Header edit Set-Cookie ^(XSRF-TOKEN=.*);.?[h|H].+(;.*)$ "$1$2"

    ProxyPass /
    ProxyPassReverse /    

    SSLEngine on
    SSLProxyEngine On
    Include *******
    SSLCertificateFile *******
    SSLCertificateKeyFile *******

Header unset X-Frame-Options is set because X-Frame-Options is default to SAMEORIGIN. Unset the X-Frame-Options allows the remark42 widget iframe display on all sites. You should set the docker-compose.yml's ALLOWED_HOSTS environment variable to restrict the allowed hosts instead.

Header edit Set-Cookie ^(XSRF-TOKEN=.*);.?[h|H].+(;.*)$ "$1$2" is a line to remove the HttpOnly attribute on the XSRF-TOKEN cookie. In my case, XSRF-TOKEN cookie is always set to HttpOnly (not sure why), it causes remark42 cannot read the xsrf token properly and cause xsrf mismatch error. If you doesn't have this issue, you may remove this line.

ProxyPass and ProxyPassReverse should be point to the remark42 server which is in this example.

Restart Apache2

Restart apache2 to apply the changes

sudo service apache2 restart

Visit https://<your_remark42_domain>/web on your browser to check it works or not.
Working Example:

Setup remark42 on Hexo Aomori Theme (Bonus)

Base on

Edit the _config.yml, the site_id should be the same as the value on the docker-compose.yml's SITE environment variable.

  enable: true
  site_id: tatlead
  max_shown_comments: 10
  theme: light
  locale: en
  show_email_subscription: false
How to deploy Hexo to Cloudflare Pages

Hexo is a fast, simple and powerful blog framework. You can deploy Hexo to different static site hosts such as Github Pages, Cloudflare Pages, etc. This walkthrough will show you how to deploy Hexo to Cloudflare Pages.

1. Sign in to Cloudflare Pages

To begin, go to the Cloudflare Pages site and sign in with your Cloudflare account.

2. Selecting a GitHub repository

You will need to give Cloudflare access to your GitHub repositories if this is your first time setting up a Cloudflare Pages website.

3. Begin setup

Build command
npm run build

Build output directory

4. Deploy site

Success! ๐ŸŽ‰

How to add favicon on Hexo Aomori

My version of hexo-theme-aomori is v1.22.0.

1. Generate favicon

Visit to generate your favicon and download the favicon package.

2. Extract package

Extract the favicon package and paste to source folder

3. Edit head.ejs

Go to themes/hexo-theme-aomori/layout/_partial and edit head.ejs

Paste the code inside the <head> block. Notice: Use the code from

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="/favicon.ico">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="msapplication-config" content="/browserconfig.xml">
<meta name="theme-color" content="#ffffff">

4. Start Hexo server

Start the Hexo server to see the changes. ๐Ÿ‘

hexo server
Why I chose Hexo for my blog

I had tried to use some popular blog framework like WordPress, Ghost before. They provide a self-host option, and users can create posts or pages inside the web GUI panel.

As a developer, I think they are over-engineering in 2020s, it is too annoying for me since it requires a lot of button clicks and hard to find the correct buttons. When I discovered Hexo, I was impressed.

WordPress and Ghost requires a server to host the blog site, so users are requires to pay for the server hosting fee, but Hexo doesn't required.