Jotty on Ubuntu 24.04 on Azure User Guide
Overview
Jotty is a fast, private, self-hosted place for your notes, checklists and kanban boards. You write in Markdown, organise with categories and tags, search across everything, and keep it all on infrastructure you control. The cloudimg image runs the official Jotty container image ghcr.io/fccview/jotty:1.26.0 (managed by Docker with a restart policy), bound to the loopback port 127.0.0.1:3000 behind an nginx reverse proxy on port 80. Jotty's store is entirely file-based — notes and checklists are plain Markdown and JSON files, with no SQL database, no Redis and no external services — and it lives on a dedicated Azure data disk mounted at /var/lib/jotty.
Upstream Jotty ships un-bootstrapped: the very first visitor to a fresh instance is sent to /auth/setup to self-register as the administrator. On a public cloud VM that is a takeover risk, so this image closes it: a per-VM administrator account is seeded automatically on the first boot of every VM, which means /auth/setup is already satisfied and simply redirects to the sign-in page. You retrieve the generated password from a root-only file and sign in. Backed by 24/7 cloudimg support.
What is included:
- Jotty 1.26.0 running as the official container image, managed by Docker
- Docker Engine and nginx preinstalled and enabled
- The Jotty web UI on
:80, fronted by nginx with the WebSocket upgrade the editor uses - A unique administrator account seeded on first boot and recorded in a root-only file (username
admin) - First-visitor
/auth/setupself-registration closed — it redirects to the sign-in page - A dedicated Azure data disk at
/var/lib/jottyholding all notes, checklists and app state - The app bound to loopback only; nginx is the sole public surface, with
server_tokens off, an$http_hostallowlist and config paths returning 404 docker.service+jotty.service+nginx.serviceas systemd units, enabled and active- An unauthenticated
/api/healthendpoint for Azure Load Balancer health probes - 24/7 cloudimg support
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 for personal or small-team use; size up for many active users or very large note collections. NSG inbound: allow 22/tcp from your management network and 80/tcp. Jotty serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Jotty 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 jotty \
--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 jotty --port 80 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active docker.service jotty.service nginx.service
All three report active. Docker runs the Jotty container (bound to the loopback port 127.0.0.1:3000), and nginx fronts it on port 80. Jotty's notes, checklists and state live on the dedicated Azure data disk mounted at /var/lib/jotty.

Step 5 - Retrieve your administrator credential
The administrator account is seeded uniquely on the first boot of your VM. The generated password is written to a root-only file (the file holds only the plaintext password; the store itself keeps just a SHA-256 hash):
sudo cat /root/jotty-credentials.txt
You will see the sign-in URL, the username (admin) and the per-VM password. Keep this password safe — it is the administrator for your Jotty instance.

Step 6 - Verify the app is serving
Jotty exposes an unauthenticated health endpoint, and the image ships a self-test that proves the per-VM admin gate end to end:
curl -s http://127.0.0.1:3000/api/health; echo
sudo /usr/local/sbin/jotty-selftest
The health endpoint returns {"status":"healthy",...}, and the self-test confirms the app is serving, the per-VM password matches the seeded admin, common and blank default passwords are rejected, and first-admin self-registration is guarded.

Step 7 - Review the security posture
The image is locked down by default. The app port is loopback-only (nginx is the sole public surface), first-visitor /auth/setup self-registration is closed, and nginx refuses unknown Host headers and config paths:
curl -s -o /dev/null -w 'setup -> HTTP %{http_code} %{redirect_url}\n' http://127.0.0.1:3000/auth/setup
ss -lnt | grep -E ':3000|:80 '
curl -s -o /dev/null -w 'evil-host -> %{http_code}\n' -H 'Host: evil.example.com' http://127.0.0.1/auth/login
curl -s -o /dev/null -w '/users.json -> %{http_code}\n' -H 'Host: 127.0.0.1' http://127.0.0.1/users.json
/auth/setup returns a 307 redirect to /auth/login (self-registration guarded), port 3000 listens on 127.0.0.1 only, an unknown Host header gets a bare 404, and the config path returns 404.

Step 8 - Sign in to Jotty
In your browser, go to http://<vm-public-ip>/. You are taken straight to the Welcome back sign-in screen (not a setup form — the admin is already seeded). Sign in as admin with the password from Step 5.

Step 9 - Create your first note
Once signed in, click New Note, give it a title and click Create. Jotty opens the Markdown editor where you can write the note body; your note appears in the notes list immediately and opens with its content rendered.


Jotty also gives you task checklists and kanban boards alongside notes, so you can track to-dos in the same private workspace.

Add more users from Settings once signed in as the administrator — there is no open self-service registration, so new accounts are created only by an administrator.
Maintenance
Secure with HTTPS. For production, put your own domain in front of the VM and terminate TLS. Point a DNS record at the VM's public IP, then install a certificate (for example with Certbot) and add a TLS server block to nginx that proxies to http://127.0.0.1:3000, mirroring the shipped port-80 vhost. The nginx server_name allowlist already includes your VM's addresses; add your domain name to the server_name line so it is served.
Back up your notes. Everything Jotty stores is under /var/lib/jotty/data as plain Markdown and JSON. Snapshot the data disk from the Azure portal, or copy the directory:
sudo tar czf /var/tmp/jotty-data-backup.tgz -C /var/lib/jotty data
Grow the data disk. The notes store grows on the dedicated Azure data disk. Expand the disk in the Azure portal, then grow the filesystem online with sudo growpart + sudo resize2fs on the data-disk partition.
Update Jotty. New releases ship as new image tags. Pull the new tag, update the jotty.service unit to reference it, and restart:
sudo docker pull ghcr.io/fccview/jotty:<new-version>
sudo sed -i 's#ghcr.io/fccview/jotty:1.26.0#ghcr.io/fccview/jotty:<new-version>#' /etc/systemd/system/jotty.service
sudo systemctl daemon-reload && sudo systemctl restart jotty
Review the upstream release notes before upgrading, as some releases run a data migration — back up first.
Support
This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating Jotty on Azure, contact cloudimg support through the Azure Marketplace listing.
Jotty is an open source project (AGPL-3.0). This image packages unmodified upstream Jotty with cloudimg configuration and automation, and is not affiliated with or endorsed by the Jotty project.