Deployment guide

Iceshrimp

Overview

Iceshrimp.NET is a decentralized, federated microblogging server that implements the ActivityPub standard. Your instance can interoperate with Mastodon and thousands of other servers across the fediverse.

It is a from-scratch rewrite of Iceshrimp. It has 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 SecureAnyCloud image builds Iceshrimp.NET v2026.1.2-beta from source and generates the administrator account and every per-VM secret on the first boot of each VM.

What you get:

  • Iceshrimp.NET v2026.1.2-beta built from source (EUPL-1.2) with the .NET 10 SDK, running on the .NET 10 / ASP.NET Core 10 runtime
  • The Iceshrimp.NET application running as the unprivileged iceshrimp user, bound to 127.0.0.1:3000 only
  • PostgreSQL as the sole datastore (no Redis required), bound to loopback
  • nginx in front of the app, with an unauthenticated :80/healthz and the full web UI on :80 and :443
  • All per-VM state generated on first boot: the PostgreSQL password, the ASP.NET Data Protection keys and the administrator account. None of it is baked into the image
  • Account registration closed by default
  • A single administrator account recorded in a root-only credentials file, plus a per-VM self-signed TLS certificate
  • 24/7 SecureAnyCloud support

Prerequisites

  • An active Azure subscription, an SSH key pair, and a VNet and subnet in the target region
  • A VM size of Standard_B2s (2 vCPU / 4 GiB RAM), which is a comfortable size for a single-instance server
  • NSG inbound rules that allow 22/tcp from your management network, and 80/tcp and 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 a live instance, install your own certificate and domain (see Step 8).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Iceshrimp.NET by SecureAnyCloud, and select Create.

On the Basics tab, 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 select Review + create and Create.

Step 2 - Deploy from the Azure CLI

Accept the Marketplace terms once per subscription, create the VM, and open ports 80 and 443:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:iceshrimp-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name iceshrimp \
  --image sac1647283583153:iceshrimp-ubuntu-24-04:default:latest \
  --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

Connect over SSH as azureuser:

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 that 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 /. Check both:

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/

Verify that 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 the file 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. The appliance ships a per-VM self-signed certificate, so your browser warns on the HTTPS URL the first time. Accept the warning to proceed, or install your own certificate (see the next step).

Sign in with the username admin and the password from the credentials file.

After you sign in, you land on your timeline. Select the Note button to compose and publish a post. The post appears immediately on your local timeline.

Account and instance options live under Settings.

Step 8 - Set your own domain before federating (important)

Iceshrimp.NET fixes 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, so the local timeline, web UI, account login and API all work as a self-contained single instance.

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 you create real accounts or publish 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. Print the first line of the licence file:

head -1 /srv/iceshrimp/app/LICENSE

Maintenance and security notes

  • Registration is closed by default. Open it (invite-only or open) under [Security] Registrations in configuration.ini only when you intend to accept sign-ups, then restart the service.
  • Backups: the entire instance state lives in the PostgreSQL iceshrimp database and the media directory at /srv/iceshrimp/app/media. Back up both regularly (pg_dump plus the media directory).
  • Object storage: for anything beyond a small instance, move media to S3-compatible object storage under [Storage:ObjectStorage] in configuration.ini.
  • Updates: the OS receives unattended security updates. Application updates are delivered as new SecureAnyCloud image versions.
  • TLS: replace the per-VM self-signed certificate with a CA-issued certificate (for example via a reverse proxy or certbot) for a live instance.

This image is not affiliated with or endorsed by the Iceshrimp project. Iceshrimp.NET is distributed under the EUPL-1.2 licence.

Deploy on Azure

Launch Iceshrimp.NET on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure