Memos on Ubuntu 24.04 on Azure User Guide
Overview
Memos is the popular open source, self-hosted lightweight note and memo hub - a fast personal knowledge base for capturing quick notes, tasks and thoughts in Markdown, organised with tags and surfaced through a memo timeline and an explore view. The cloudimg image delivers Memos 0.29 fully installed and reverse-proxied with nginx: the Memos server is a single self-contained Go binary with an embedded SQLite datastore, running under systemd on the loopback interface, with nginx in front on port 80. The database and uploads live on a dedicated Azure data disk mounted at /var/lib/memos, separate from the OS disk and re-provisioned with every VM. Backed by 24/7 cloudimg support.
What is included:
- Memos 0.29 server (single Go binary) at
/usr/local/bin/memos, bound to loopback127.0.0.1:5230 - nginx reverse proxy on
:80in front of the Memos server (websocket aware) - A dedicated Azure data disk at
/var/lib/memosholding the SQLite database (memos_prod.db) and uploads - separate from the OS disk and independently resizable - Secure by default: no host account and no credentials ship in the image - you create the host (administrator) account from the built-in first-run sign-up form
memos.service+nginx.serviceas systemd units, enabled and active- 24/7 cloudimg support
Secure by default - you create the host account
Memos has no default administrator, and this image does not bake one in. The image ships at Memos' built-in first-run sign-up form. The very first time you browse to your VM you create your own host (administrator) account with your own username and password. No shared credentials, and no database rows, ship in the image - every VM starts as a clean slate that only you secure.

Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point; scale up for many users or large upload volumes. NSG inbound: allow 22/tcp from your management network and 80/tcp from wherever you browse Memos (front port 80 with TLS for public exposure - see Enabling HTTPS).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Memos 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). Review the dedicated data disk on the Disks tab, then Review + create → Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name memos \
--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 memos --port 80 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
The message of the day shows your VM's sign-up URL.
Step 4 - Confirm the services are running
Memos runs as two systemd units - the Go server and nginx:
systemctl is-active memos.service nginx.service
Both report active. The Memos server listens only on the loopback interface; nginx is the only service bound to a public port:
ss -tlnp | grep -E ':80 |:5230 '
LISTEN 0 4096 127.0.0.1:5230 0.0.0.0:* users:(("memos",pid=2800,fd=8))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=2811,fd=5),...)
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=2811,fd=6),...)
A health endpoint is served (and proxied by nginx) for monitoring:
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/healthz
200

Step 5 - Read the per-VM info file
The image ships no credentials. On first boot the VM writes a root-only info file with your VM's sign-up URL:
sudo cat /root/memos-credentials.txt
The MEMOS_URL value is where you create your host account.

Step 6 - First visit: create your host account
Open Memos in your browser:
http://<vm-public-ip>/
You are taken to the Create your account sign-up form. Enter a username, choose a strong password and click Sign up. Because the database is empty, this first account is automatically the Site Host (administrator).
That single step secures your VM. You are signed straight in, and the sign-up form never appears again for this VM - subsequent visits show the sign-in page.
Enable HTTPS before exposing the VM to the public internet (see the TLS section below). Until then, treat the password you set here as you would any credential sent over plain HTTP.
Capturing memos
From the home timeline, type into the editor at the top - Memos uses Markdown, so headings, bold, lists and task checklists all render. Add #tags inline to organise your notes; tags appear in the sidebar for quick filtering. Set each memo's visibility (Private, Protected or Public) and click Save.

Your memos appear in a reverse-chronological timeline with a calendar heat-map and a tag list. Use the search box to find memos by content, and the Explore view to browse memos you have marked Public.
Workspace settings
Open Settings from the user menu to manage your account, preferences, members, storage, notifications, SSO, webhooks and access tokens. The My Account page is where you change your password and create personal access tokens for the Memos API; the Admin sections let the Site Host tune the workspace.

Step 7 - Confirm the runtime
/usr/local/bin/memos version
0.29.1

The data disk
Memos' SQLite database (memos_prod.db), uploads and resources live on a dedicated Azure data disk mounted at /var/lib/memos, independently resizable and kept separate from the OS disk:
df -h /var/lib/memos
Filesystem Size Used Avail Use% Mounted on
/dev/sda 30G 1.1M 28G 1% /var/lib/memos
(The device letter can vary between boots - the mount is keyed by filesystem UUID, so /var/lib/memos is always the dedicated data disk.)
The disk is mounted by its filesystem UUID in /etc/fstab, so the mount is stable across reboots. To grow it, resize the data disk in the Azure portal, then extend the filesystem with sudo resize2fs against the device shown by lsblk. Snapshot the data disk in Azure to back up your notes.
Security updates
The image is captured fully patched (including Ubuntu phased updates) and unattended-upgrades remains enabled, so security patches keep flowing on your VM:
apt-mark showhold; systemctl is-enabled unattended-upgrades.service
enabled

Enabling HTTPS with Let's Encrypt
For production use, terminate TLS at nginx. Point a DNS A record at the VM's public IP, open 443/tcp in the NSG, then install certbot and follow its prompts (it edits the nginx site for you). Replace the placeholders with your own domain and email:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com -m you@example.com --agree-tos
certbot configures the HTTPS server block and sets up automatic renewal. After it completes, Memos is available at https://your-domain.example.com/. For the cleanest links, also set the Instance URL in Memos workspace settings to your HTTPS address.
Upgrading Memos
Memos is installed as a single Go binary at /usr/local/bin/memos. To upgrade within the 0.x line, download the new release's memos_<version>_linux_amd64.tar.gz from the official GitHub releases, replace the binary and restart the service. Always snapshot the data disk first, as the schema migrates on start. cloudimg support can assist with planning and performing upgrades.
Support
This image is backed by 24/7 cloudimg support covering deployment, upgrades, integrations, TLS termination and database administration. Contact us by email and chat.
Memos is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.