Linux VPS is a complicated method to get a live website, but it is also extremely effective and is one of cheapest method. In this tutorial, you will discover:
Thanks to Discord user Grimston#0001 at NPipes for sponsoring a VPS machine that used to make this tutorial. You can contribute to the community too.
Deploying the website API is not included in this tutorial. However, you can use the same VPS to host the website API.
To manage the Linux VPS, you need a tool to execute commands and a tool to transfer file between your computer and the VPS machine. Bitvise SSH Client is a recommended tool.
Before deploying your website to a Linux VPS, you need to publish your website to a folder first. Then we will make the website working and then set up a GitHub action for automated deployment later. To publishing your website to a folder:
When you bought a Linux VPS service, you will receive an IP, the username, and password to access the VPS. Use these information in Bitvise SSH Client to connect to the VPS machine.
sudo apt-get update && sudo apt-get install -y aspnetcore-runtime-6.0
:sudo apt install nginx
.sudo systemctl enable nginx
.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; }
For ssl_certificate
and ssl_certificate_key
you can get from an SSL certificate provider service. The same with server_name
, you can get from a domain provider service.
The first server block is to serve the website with the HTTPS protocol. The second server block redirects all HTTP request to HTTPS request.
location /images/ { root "<path_to_images_folder>"; }
See the sample file in GitHub
sudo systemctl reload nginx
.The following actions can help you to speed up the website you are hosting:
If you follow the tutorial, you need not worry about this. The second block of server in the example redirects all HTTP to HTTPS protocol.
Handle MIME type is just about telling which file extension belongs to which group. For example, any file that ends with .css
should be treated as text/css
. There are many MIME type out there, and they need to be recognized differently. You can see the full list of MIME type in IANA Media Types.
To check if all of your file is handled correctly, open the /etc/nginx/mime.types file in the VPS server. If the MIME type you are using is not there, you need to add it and reload the NGINX server.
Enabling gzip will help your website loads faster. Your website loads faster when it is lighter. When you are enabling gzip, NGINX will use some CPU to compress your website, then send it over to the browser. The browser then uncompress your website and display it accordingly. Because the process of compressing and uncompressing are cheaper than the transportation cost, so it will increase the website loading speed.
Gzip is also a razor blade, you can hurt yourself if you don't know what you are doing. To effectively gzip your website, you need to monitor and determine when to compress and when is not to. Gzip is enabled by default NGINX settings, you can find the setting in /etc/nginxnginx.conf. Look for the # Gzip Settings
. To turn on advanced settings, you need to uncomment all other settings. Your Gzip settings should look like:
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
is the list of MIME types which will be compressed to smaller size, you can add some more to this list.
The gzip_comp_level
is the level of compressing, ranging from 1 to 9 which 1 is least compressed and 9 is the most compressed. Higher compressing level compensate your CPU usage, and sometimes it becomes bigger than the original.
Some files, as mentioned above, after being compressed it becomes bigger. You need to add gzip_min_length X
to tell NGINX not to compress if the size is less than X
. There is no ideal number for this setting, you must monitor your website and give the decision.
To see the effectiveness and ineffectiveness of the gzip, open your website, turn on the Web Developer Tools by pressing F12. Open the Network tab, check the Disable Cache option and reload the website:
If the size before compressing is larger than the size after compressed, then you should compress the file. Otherwise, don't compress (either remove the gzip_types
or increase the gzip_min_length X
).
Up until this point, you have a healthy website up and running. The next step is to set up a deployment pipeline, so you don't have to manually deploy whenever the website updates. GitHub is a good way to set up the deployment pipeline.
name: Deploy to VPS on: push: branches: - master env: CONFIGURATION: Release DOTNET_CORE_VERSION: 6.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 }}
From the example, you need to change GITHUB_OUTPUT_DIRECTORY
, VPS_WEB_DIRECTORY
to your folder. The GITHUB_OUTPUT_DIRECTORY
can be anything, but the VPS_WEB_DIRECTORY
needs to be existed before running this workflow.
The on
key: decide when to deploy the website. In this example, it is deployed whenever a push on master branch.
You need to update the secret keys in the Copy web via ssh
job as well.
In this section, we have collected some common mistakes from the Blazor School Discord Community.
You should let Blazor handles all the errors. Otherwise, you will have an unprofessional error page, not to mention that your code to handle errors will never show up. This is an example of letting NGINX handles errors:
// DON'T DO THIS location / { try_files $uri $uri/ /index.html =404; }
index.html
as backupIf you make this mistake, your website is not accessible through sub URL and can only access by homepage. For example, when you access your website via https://208.115.245.90/product-list you will get an 404 error. This is an example of not serving index.html
as backup.
// DON'T DO THIS location / { try_files /index.html; }
By default, NGINX searches the files with case-sensitive enabled. For example, you are trying to access a picture from your website, the picture file name is wwwroot/Logo.png, and you type <your_website>.com/logo.png; You will get an 404 error because there is not a file name wwwroot/logo.png.
The wwwroot folder should contain static files only. It will make it easy when you want to deploy more website server. The backup process will be easier to maintain.