O1
Applications Azure

Oqtane on Ubuntu 24.04 on Azure User Guide

| Product: Oqtane 10 on Ubuntu 24.04 LTS on Azure

Overview

Oqtane is an open source content management system and modular application framework built on ASP.NET Core and Blazor. It gives you a full admin experience for building sites, pages and content from reusable modules and themes, and gives developers a modern .NET platform for building web, desktop and mobile applications. The cloudimg image ships Oqtane 10.2.3 on the .NET 10 runtime, running as an ASP.NET Core application under Kestrel behind nginx on a hardened, fully patched Ubuntu 24.04 LTS base. The appliance is self contained: it uses an embedded SQLite database, so there is no separate database server to run. A unique host administrator account is created on the first boot of every VM using a per VM secret, and the install wizard is completed automatically so the very first page a visitor sees is a real, rendered Oqtane site. Backed by 24/7 cloudimg support.

What is included:

  • Oqtane 10.2.3 (MIT licensed) on the .NET 10 runtime, run by Kestrel under systemd as oqtane.service
  • An embedded SQLite database, so the appliance is complete on its own with no external database server
  • nginx serving the site and admin on :80, with the Blazor Server realtime connection proxied through
  • A per VM host administrator account created on first boot and recorded in a root only credentials file
  • No shipped default login: the host account is created with a unique per VM secret, and no known or blank credential authenticates
  • A per VM ASP.NET Core DataProtection keyring, so authentication is never shared across customer VMs
  • Kestrel bound to 127.0.0.1:5000 only, never exposed to the network; nginx is the only public listener
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 cloudimg support

This image ships only the open source, MIT licensed Oqtane framework. It is not affiliated with or endorsed by the Oqtane project.

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up for larger or busier sites. NSG inbound: allow 22/tcp from your management network and 80/tcp for the site and admin. The embedded SQLite database is never exposed on the network, and Kestrel listens on 127.0.0.1 only.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Oqtane by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name oqtane \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open port 80:

az vm open-port --resource-group <your-rg> --name oqtane --port 80 --priority 900

Step 3 - Confirm the services are running

SSH in as azureuser and confirm the Oqtane (Kestrel) service, nginx and the first boot unit are all active. Kestrel listens only on 127.0.0.1:5000; nginx is the only public listener, serving :80. The unauthenticated /healthz endpoint answers 200 for load balancer probes.

systemctl is-active oqtane nginx oqtane-firstboot
ss -ltnH | grep -E ':(80|5000)' | awk '{print $4}' | sort -u
curl -s -o /dev/null -w '/healthz -> %{http_code}\n' http://127.0.0.1/healthz

The oqtane, nginx and oqtane-firstboot services active, with Kestrel bound to loopback 127.0.0.1:5000, nginx listening on port 80, and the healthz endpoint returning 200

First boot completes the Oqtane install automatically. Immediately after a reboot the .NET app performs a short just in time warm up, so allow around 30 seconds for the first page request before it responds.

Step 4 - Retrieve the per VM host administrator login

Every VM creates its own Oqtane host administrator on first boot and writes the username, the generated password and the site URL to a root only credentials file. Read it with sudo:

sudo cat /root/oqtane-credentials.txt

The per VM Oqtane credentials file, showing the host admin username, the generated password and the site URL, owned root only with 0600 permissions, alongside the first boot sentinel

You sign in with the OQTANE_ADMIN_USER (which is host) and the OQTANE_ADMIN_PASSWORD from this file.

Step 5 - Sign in

Browse to http://<vm-public-ip>/ and choose Login (top right), or go straight to http://<vm-public-ip>/login. Sign in with the username host and the password from Step 4.

The Oqtane User Login page with the Username and Password fields, the Stay Signed In option, and the Login button

Step 6 - The Admin Dashboard

Once signed in as the host user, open the Admin Dashboard (the gear icon in the top navigation, or http://<vm-public-ip>/admin). This is the control centre for the whole installation: Site Settings, Page Management, User and Role Management, Module and Theme Management, File Management, Scheduled Jobs, SQL Management and more.

The Oqtane Admin Dashboard showing the management tiles for Site Settings, Page Management, User Management, Role Management, Module Management, Theme Management, Scheduled Jobs and SQL Management

Step 7 - The public website

Your public site is served on http://<vm-public-ip>/. On a fresh install the silent installer has already provisioned the default site and theme, so Oqtane serves a real rendered welcome page immediately - you never see an install wizard. As you build and publish pages in the admin, they replace this starter content.

The rendered public Oqtane site showing the Welcome To Oqtane page with the Oqtane logo, the Join Our Community and Clone Our Repo actions, and the framework overview

Step 8 - Build pages with the control panel

When you are signed in, Oqtane shows a control panel in the top navigation (the pencil and gear icons) for adding and editing pages and modules directly on the site. Use it to add your first page, drop in modules, and publish content.

The Oqtane site while signed in as the host user, showing the control panel edit and settings icons and the additional Private menu in the top navigation

Step 9 - No known or default credentials

Oqtane ships no default login. The cloudimg image goes further: the captured image contains no database and no DataProtection keyring at all, and the host administrator is created with a unique per VM secret the first time the VM boots. You can prove that only the per VM secret works with the built in round trip check, which confirms the per VM host administrator authenticates through the sign in API while a blank password, common guesses and any build time value are all rejected:

sqlite3 /var/lib/oqtane/data/Oqtane.db 'SELECT Username FROM "User";'
sudo bash /usr/local/sbin/oqtane-cred-roundtrip.sh

The host user present in the Oqtane User table, and the round trip check confirming the per VM host admin authenticates while blank, known and build time guesses are rejected and the account is not locked

Step 10 - Verify the stack and where your data lives

Confirm the ASP.NET Core runtime and the Oqtane framework. The SQLite database, the ASP.NET Core DataProtection keyring and your uploaded content all live on this VM's disk, so your site persists across reboots and rides with the VM.

dotnet --list-runtimes | grep AspNetCore
ls /opt/oqtane/app/Oqtane.Server.dll

The ASP.NET Core 10 runtime present and the shipped Oqtane framework, confirming the MIT licensed Oqtane 10.2.3 appliance on .NET 10

Adding your own domain

The image serves the site on the VM's public IP out of the box. Oqtane routes requests using site aliases, and enforces a single canonical alias for the site. For production, add your own domain as an alias in Admin Dashboard -> Site Settings -> Aliases and make it the default, then point your DNS at the VM (or at an Azure Load Balancer or Application Gateway in front of it). For TLS, terminate HTTPS at a load balancer or Application Gateway, or place your own reverse proxy or certificate in front of nginx.

Security notes

  • The host administrator account is unique per VM and no known or blank credential authenticates. Keep /root/oqtane-credentials.txt protected, and change the password from within Oqtane if you share access.
  • The ASP.NET Core DataProtection keyring is generated per VM on first boot, so authentication cookies are never shared between customer VMs.
  • Kestrel listens on 127.0.0.1:5000 only and is never reachable from the network. nginx is the only public listener.
  • The SQLite database lives at /var/lib/oqtane/data/Oqtane.db on the VM.
  • Restrict inbound 80/tcp in your NSG to the networks that need the site, and front the site with your own TLS for production.

Support

This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating Oqtane on Azure, contact us at cloudimg.co.uk.