Running Blazor Server on Oracle Cloud Infrastructure (OCI)
I recently worked on a side project (dotnetnewjob.com) using Blazor Server and Oracle Cloud Infrastructure (OCI). This was new territory for me. I was able to get my hands dirty setting up an Ubuntu server on a VM running in the cloud. My day job involves a lot of on-prem hosting so this involved a lot of trial and error.
OCI has some extremely generous free offerings:
Always Free cloud services
Services you can use for an unlimited time.
- Two Oracle Autonomous Databases with powerful tools like Oracle APEX and Oracle SQL Developer
- Two AMD Compute VMs
- Up to 4 instances of ARM Ampere A1 Compute with 3,000 OCPU hours and 18,000 GB hours per month
- Block, Object, and Archive Storage; Load Balancer and data egress; Monitoring and Notifications
- 2 AMD based Compute VMs with 1/8 OCPU** and 1 GB memory each
- Arm-based Ampere A1 cores and 24 GB of memory usable as 1 VM or up to 4 VMs with 3,000 OCPU hours and - 18,000 GB hours per month
- 2 Block Volumes Storage, 200 GB total
- 10 GB Object Storage – Standard
- 10 GB Object Storage – Infrequent Access
- 10 GB Archive Storage
- Resource Manager: managed Terraform
- 5 OCI Bastions
I'm able to run my Blazor Server app on a cloud hosted VM with 4 cores and 24 GB of RAM for free. Nice.
I documented my steps as I went through configuring Ubuntu to work with Blazor Server. Below are some of the steps.
Connect SSH
- You need to remove inherited permissions on the private key
- Set the current user to be the only user with permissions
- Backup your keys
{
"name": "foo ssh profile",
"acrylicOpacity": 0.8,
"colorScheme": "One Half Dark",
"commandline": "ssh -i C:\\keys\\foo.key ubuntu@xxx.xxx.xxx.xxx",
"experimental.retroTerminalEffect": false,
"fontFace": "Cascadia Code PL",
"fontSize": 11,
"fontWeight": "normal",
"icon": "ms-appx:///ProfileIcons/pwsh.png",
"useAcrylic": true
}
Install Dotnet
AMD
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install apt-transport-https
sudo apt-get install -y dotnet-sdk-6.0
Arm64
curl -SL -o dotnet.tar.gz https://dotnet.microsoft.com/en-us/download/dotnet
sudo mkdir -p /usr/share/dotnet
sudo tar -zxf dotnet.tar.gz -C /usr/share/dotnet
sudo ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
dotnet --version
run dotnet --version
to verify
Install Nginx
sudo apt update
sudo apt install nginx
sudo systemctl enable nginx
sudo systemctl start nginx
Configure Nginx
sudo nano /etc/nginx/conf.d/default.conf
Initial Nginx config
server
{
listen 80;
server_name xxx.xxx.xxx.xxx;
root /usr/share/nginx/html;
index index.html;
location /
{
}
}
Configure Uncomplicated Firewall (UFW)
sudo ufw enable
sudo ufw allow 'Nginx Full'
Reboot
sudo reboot
Verify setup/Nginx so far
Navigate to public IP and you should see the Welcome to nginx!
page.
Setup ssh profile for scp
Navigate to
C:\Users\<username>\.ssh\config
Add the following profile
Host foo-profile
HostName xxx.xxx.xxx.xxx
User ubuntu
IdentityFile "C:\\keys\\foo.key"
IdentitiesOnly yes
Port 22
ServerAliveInterval 60
Publish dotnet files to server
sudo mkdir /srv/FooProject
sudo chown ubuntu /srv/FooProject
dotnet publish -r linux-x64 --self-contained false
rm -r *
for deleting all files, directories, and sub-directories in current directory
scp -r C:\dev\FooProject\publish\* foo-profile:/srv/FooProject
Create/register the service for the Blazor app
sudo nano /etc/systemd/system/FooProject.service
[Unit]
Description=FooProject app
[Service]
Type=notify
ExecStart=dotnet /srv/FooProject/FooProject.dll
WorkingDirectory=/srv/FooProject
Restart=always
RestartSec=10
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
sudo systemctl enable FooProject.service
sudo systemctl start projectname.service
Reload service with sudo systemctl daemon-reload
Configure Nginx for Blazor Server
sudo nano /etc/nginx/conf.d/default.conf
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
listen 80;
server_name xxx.xxx.xxx.xxx;
root /srv/www/var/www;
location /
{
proxy_pass http://localhost:5000/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache off;
proxy_http_version 1.1;
proxy_read_timeout 100s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
#development#dotnet#blazor