Linux VPS hosting with deployment pipeline

🟥 Not applicable to Blazor Server

Using a Linux VPS is an effective and cost-efficient way to host a live website, although it may seem complicated at first. In this tutorial, we will guide you through the following steps:

  • Required tools
  • Publishing a Blazor WebAssembly website
  • Setting up a Linux VPS
  • Speeding up your Blazor WebAssembly website
  • Configuring a GitHub action
  • Common mistakes

We would like to extend our gratitude to Grimston#0001, a Discord user from NPipes who sponsored a VPS machine for creating this tutorial. You too can contribute to the community.

Please note that this tutorial does not cover deploying a website API, but you can use the same VPS to host your website API.


Required tools

In order to manage your Linux VPS, you will need two tools: one for executing commands and one for transferring files between your computer and the VPS machine. We recommend using Bitvise SSH Client, which is an all-in-one tool for these tasks.


Publishing a Blazor WebAssembly website

Before deploying your website to a Linux VPS, you will need to publish it to a folder. This will allow us to make the website functional and then set up a GitHub action for automated deployment later. To publish your website to a folder, follow these steps:

  1. Right-click on your Blazor WebAssembly project and select Publish...

publishing-blazor-webassembly-1.png

  1. In the next step, select Folder.

publishing-blazor-webassembly-2.png

  1. Choose the folder location where you want to publish the website.

publishing-blazor-webassembly-3.png

  1. Click Publish to start the publishing process.

publishing-blazor-webassembly-4.png

Once the website is published to the folder, you can test it out locally to ensure it is working as intended. If any changes are needed, make them and republish the website to the folder until you are satisfied with the results.


Setting up a Linux VPS

After purchasing a Linux VPS service, you will receive an IP address, username, and password to access the VPS. To connect to the VPS machine, follow these steps using Bitvise SSH Client:

  1. Launch Bitvise SSH Client and connect to the VPS machine.

set-up-linux-vps-1.png

  1. Click New terminal console to open a terminal console.

set-up-linux-vps-2.png

  1. Install the .NET runtime by running the following command in the terminal console: sudo apt-get update && sudo apt-get install -y aspnetcore-runtime-7.0.

set-up-linux-vps-3.png

  1. Switch back to the Bitvise SSH Client and click New SFTP window.

set-up-linux-vps-4.png

  1. Copy the wwwroot folder from the published folder to the VPS machine. We recommend placing it in the directory /home/<your_website>.

set-up-linux-vps-5.png

  1. Install NGINX by running the following command in the terminal console: sudo apt install nginx.

set-up-linux-vps-6.png

  1. Set NGINX to start automatically by running the command sudo systemctl enable nginx.

set-up-linux-vps-7.png

  1. In the SFTP window, rename the file /etc/nginx/sites-enabled/default and update its contents with the sample file provided on GitHub.
server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name <your_domain>;
	ssl_certificate '<your_path_to_pem_file>';
        ssl_certificate_key '<your_path_to_pem_file>';
	
	root "<path_to_wwwroot_folder>";
	
	location / {
             try_files $uri $uri/ /index.html;
	}
}

server {
	listen 80;
	listen [::]:80;
	server_name <your_domain>;
	
	return 301 https://$host$request_uri;
}

You can obtain ssl_certificate, ssl_certificate_key, and server_name from a service provider such as NPipes.

For server_name, enter your domain separated by a comma (,). For example: blazorschool.com, mywebsite.blazorschool.com.

  1. If your website has dynamic file data, such as user avatars or user-uploaded files, avoid placing them in the folder of the website. Instead, store them in a separate location and redirect them in the config file as follows:
location /images/ 
{
    root "<path_to_images_folder>"; 
}
  1. Whenever you change the configuration settings, reload NGINX to apply the changes. To do this, run the command sudo systemctl reload nginx in the terminal console.

set-up-linux-vps-8.png

For a sample config file, please refer to the GitHub repository.


Speeding up your Blazor WebAssembly website

Here are some suggestions to speed up your website hosting:

  • Redirect HTTP traffic to HTTPS and ensure that your SSL certificate is properly installed and configured.
  • Verify that MIME types are being handled correctly.
  • Activate gzip compression to reduce the size of your web pages and accelerate their loading time.

Redirect HTTP to HTTPS

To enable HTTP to HTTPS redirection, simply follow the tutorial provided. In the example, the second server block performs the redirection automatically, so there's no need to worry about it.

Verify that MIME types are being handled correctly

Handling MIME types is a matter of assigning file extensions to their respective categories. For instance, files ending with .css should be identified as text/css. Since there are numerous MIME types available, they must be recognized accurately. A comprehensive list of MIME types is available on IANA Media Types.

To ensure that all of your files are being processed appropriately, navigate to the /etc/nginx/mime.types file on your VPS server. If a particular MIME type is not listed, you must add it manually and reload the NGINX server.

Activate gzip compression

Enabling gzip compression can significantly improve your website's loading speed by reducing its weight. When you activate gzip, NGINX uses some CPU power to compress your website before sending it to the browser. The browser then decompresses the website for display. Since compressing and decompressing are less expensive than transportation costs, this technique can boost loading speed.

However, gzip can be tricky to use if you are unfamiliar with it. To apply it correctly, you must determine when to compress and when not to. Gzip is already enabled in NGINX by default settings. You can find these settings in /etc/nginx/nginx.conf by looking for the # Gzip Settings. To activate advanced settings, uncomment all other settings. Your Gzip settings should resemble the following:

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types
    text/plain
    text/css
    application/json
    application/javascript
    text/xml
    application/xml
    application/xml+rss
    text/javascript;

The gzip_types list specifies which MIME types to compress for a smaller size, and you can add more to it.

The gzip_comp_level determines the level of compression, ranging from 1 to 9, with 1 being the least compressed and 9 being the most compressed. Higher compression levels compensate for more CPU usage, but sometimes the output size can be bigger than the original.

As mentioned earlier, some files may become larger after being compressed. You can add gzip_min_length X to tell NGINX not to compress files smaller than X. There is no ideal number for this setting, so you must monitor your website and make informed decisions.

To see gzip's effectiveness, open your website, turn on the Web Developer Tools by pressing F12, and open the Network tab. Check the Disable Cache option and reload the website.

speed-up-blazor-webassembly-1.png

If the size before compression is larger than the size after compression, then you should compress the file. Otherwise, you should not compress it (either remove the gzip_types or increase the gzip_min_length X).


Configuring a GitHub action

Congratulations on having a healthy website up and running! To simplify the process of deploying website updates, the next step is to set up a deployment pipeline. GitHub is a great tool to help you do this.

To get started, follow these steps:

  1. In your GitHub repository, go to Settings > Secrets > Actions and click New repository secret.

set-up-github-action-1.png

  1. Create 3 secret keys for the host address, username, and password to log into your VPS machine.

set-up-github-action-2.png

  1. Switch to the Actions tab and click New workflow.

set-up-github-action-3.png

  1. Search for the ASP.NET workflow and select .NET by GitHub Actions.

set-up-github-action-4.png

  1. Update the YAML file with your information. Here's an example file:
name: Deploy to VPS
on:
  push:
    branches:
    - master
env:
  CONFIGURATION: Release
  DOTNET_CORE_VERSION: 7.x.x
  GITHUB_OUTPUT_DIRECTORY: blazorschool.<your_website>
  VPS_WEB_DIRECTORY: /home/blazor school.<your_website>
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.DOTNET_CORE_VERSION }}
    - name: Restore web
      run: dotnet restore
    - name: Build web
      run: dotnet build --configuration ${{ env.CONFIGURATION }} --no-restore
    - name: Test web
      run: dotnet test --no-build
    - name: Publish web
      run: dotnet publish --configuration ${{ env.CONFIGURATION }} --output "${{ env.GITHUB_OUTPUT_DIRECTORY }}"

    - name: Copy web via ssh
      uses: garygrossgarten/github-action-scp@master
      with:
        local: ${{ env.GITHUB_OUTPUT_DIRECTORY }}
        remote: ${{ env.VPS_WEB_DIRECTORY }}
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        password: ${{ secrets.PASSWORD }}

Remember to replace the placeholders with your own information. The GITHUB_OUTPUT_DIRECTORY can be anything, but the VPS_WEB_DIRECTORY needs to exist before running the workflow. The on key determines when to deploy the website, and in this example, it's set to deploy on every push to the master branch.

Don't forget to update the secret keys in the Copy web via ssh job as well. With this deployment pipeline in place, you'll be able to update your website more easily and efficiently!


Common mistakes

In this section, we've gathered some common mistakes that members of the Blazor School Discord community have encountered.

Mistake #1: Letting NGINX handle errors

Don't make the mistake of letting NGINX handle errors like 404. Instead, let Blazor handle all errors so that you have a professional-looking error page, and your error handling code will work correctly. Here's an example of what not to do:

// DON'T DO THIS
location / 
{ 
    try_files $uri $uri/ /index.html =404; 
}

Mistake #2: Not serving index.html as a backup

If you don't serve index.html as a backup, your website won't be accessible through sub-URLs and can only be accessed through the homepage. For example, if you access your website via https://208.115.245.90/product-list, you'll get a 404 error. Here's an example of what not to do:

// DON'T DO THIS
location / 
{ 
    try_files /index.html; 
}

Mistake #3: Case sensitivity with files

By default, NGINX is case-sensitive when searching for files. So if you're trying to access a file named wwwroot/Logo.png but you type <your_website>.com/logo.png, you'll get a 404 error because the file name should be wwwroot/Logo.png.

Mistake #4: Storing dynamic files in the wwwroot folder

Don't store dynamic files like user avatars or user-uploaded files in the wwwroot folder. The wwwroot folder should only contain static files. This makes it easier to deploy your website to multiple servers and maintain backups.

BLAZOR SCHOOL
Designed and built with care by our dedicated team, with contributions from a supportive community. We strive to provide the best learning experience for our users.
Docs licensed CC-BY-SA-4.0
Copyright © 2021-2024 Blazor School
An unhandled error has occurred. Reload 🗙