Iceshrimp.NET on Ubuntu 24.04 on Azure User Guide
Overview
Iceshrimp.NET is a decentralized, federated microblogging server that implements the ActivityPub standard, so your instance can interoperate with Mastodon and thousands of other servers across the fediverse. It is a from-scratch rewrite of Iceshrimp with an all-new backend built on .NET for speed and low resource use, an all-new web client built with Blazor WebAssembly, and a Mastodon-compatible client API so many existing mobile and web clients work against it too. The cloudimg image builds Iceshrimp.NET v2026.1.2-beta from source with the .NET 10 SDK, backs it with PostgreSQL, fronts it with nginx, and generates the administrator account and every per-VM secret uniquely on the first boot of each VM. Backed by 24/7 cloudimg support.
What is included:
- Iceshrimp.NET v2026.1.2-beta built from source (EUPL-1.2), on the .NET 10 / ASP.NET Core 10 runtime
- The Iceshrimp.NET application running as the unprivileged
iceshrimpuser, bound to127.0.0.1:3000only - PostgreSQL as the sole datastore (no Redis required), bound to loopback; nginx fronting the app with an unauthenticated
:80/healthzand the full web UI on:80and:443 - All per-VM state generated on first boot: the PostgreSQL password, the ASP.NET Data Protection keys and the administrator account - none are baked into the image
- Account registration closed by default (secure by default); a single administrator account recorded in a root-only credentials file, plus a per-VM self-signed TLS certificate
- 24/7 cloudimg support

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 comfortable size for a single-instance server. NSG inbound: allow 22/tcp from your management network, and 80/tcp + 443/tcp for the web interface. The appliance serves the web UI on port 80 and on port 443 with a per-VM self-signed certificate so the interface works immediately; for production you install your own certificate and domain (see "Set your own domain").
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Iceshrimp.NET by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2s); under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), HTTP (80) and HTTPS (443). Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name iceshrimp \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name iceshrimp --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name iceshrimp --port 443 --priority 1011
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
On first boot the image generates the per-VM secrets, sets the web domain to the VM public IP, creates the administrator account and starts the stack. Confirm the three services are active:
systemctl is-active postgresql nginx iceshrimp.service
The application (Kestrel) and PostgreSQL both listen on loopback only; nginx is the sole public listener:
sudo ss -tlnp | grep -E ':3000|:5432|:80 |:443 '


Step 5 - Check the health endpoint and the API
The unauthenticated :80/healthz returns 200 for load-balancer probes, and the web UI answers on /:
curl -s -o /dev/null -w 'healthz -> %{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w 'web UI -> %{http_code}\n' http://127.0.0.1/
You can prove the per-VM administrator password authenticates against the Mastodon-compatible web API. A wrong password is rejected with 403; the real password returns 200:
P=$(sudo grep '^ICESHRIMP_ADMIN_PASSWORD=' /root/iceshrimp-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'login -> %{http_code}\n' -X POST -H 'Content-Type: application/json' \
--data "{\"username\":\"admin\",\"password\":\"$P\"}" \
http://127.0.0.1/api/iceshrimp/auth/login

Step 6 - Retrieve the per-VM administrator credentials
The administrator username, password and URL are written to a root-only file on first boot. Read them over SSH:
sudo cat /root/iceshrimp-credentials.txt
The file records ICESHRIMP_ADMIN_USERNAME (admin), ICESHRIMP_ADMIN_PASSWORD (unique to your VM) and ICESHRIMP_URL. Store the password in your password manager; it is not recoverable from the file once you change it.
Step 7 - Sign in to the web interface
Open https://<vm-public-ip>/ (or http://<vm-public-ip>/) in your browser. Because the appliance ships a per-VM self-signed certificate, your browser will warn on the HTTPS URL the first time - accept it to proceed, or install your own certificate (see the next step). Sign in with the username admin and the password from the credentials file.

Once signed in you land on your timeline. Use the Note button to compose and publish a post, which appears immediately on your local timeline.

Account and instance options live under Settings.

Step 8 - Set your own domain before federating (important)
Iceshrimp.NET bakes the web and account domains at initial setup and cannot cleanly change them once content exists. The appliance boots with both set to the VM public IP as a working single-instance evaluation placeholder, so the local timeline, web UI, account login and API all work self-contained. To federate with the wider fediverse you need a real domain and a valid TLS certificate. Point a DNS record at the VM, then edit the configuration and restart the service:
sudo nano /srv/iceshrimp/app/configuration.ini
# set, under [Instance]:
# WebDomain = social.example.org
# AccountDomain = example.org
# install a real TLS certificate for nginx at /etc/ssl/iceshrimp/, then:
sudo systemctl restart iceshrimp.service
sudo systemctl reload nginx
Do this before creating real accounts or publishing content - changing the domain afterwards breaks federation.
Step 9 - Version and licence
Iceshrimp.NET is built from source at the pinned upstream tag under the EUPL-1.2 licence and runs on the .NET 10 shared runtime:
head -1 /srv/iceshrimp/app/LICENSE

Maintenance and security notes
- Registration is closed by default. Open it (invite-only or open) under
[Security] Registrationsinconfiguration.inionly when you intend to accept sign-ups, and restart the service. - Backups: the entire instance state lives in the PostgreSQL
iceshrimpdatabase and the media directory at/srv/iceshrimp/app/media. Back both up regularly (pg_dumpplus the media directory). - Object storage: for anything beyond a small instance, move media to S3-compatible object storage under
[Storage:ObjectStorage]inconfiguration.ini. - Updates: the OS receives unattended security updates. Application updates are delivered as new cloudimg image versions.
- TLS: replace the per-VM self-signed certificate with a CA-issued certificate (for example via a reverse proxy or certbot) for production use.
This image is not affiliated with or endorsed by the Iceshrimp project. Iceshrimp.NET is distributed under the EUPL-1.2 licence.