🟥 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:
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.
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.
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:
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.
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:
sudo apt-get update && sudo apt-get install -y aspnetcore-runtime-7.0
./home/<your_website>
.sudo apt install nginx
.sudo systemctl enable nginx
./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
.
location /images/ { root "<path_to_images_folder>"; }
sudo systemctl reload nginx
in the terminal console.For a sample config file, please refer to the GitHub repository.
Here are some suggestions to speed up your website hosting:
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.
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.
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.
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
).
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:
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!
In this section, we've gathered some common mistakes that members of the Blazor School Discord community have encountered.
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; }
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; }
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.
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.