Damselfly on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of Damselfly on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Damselfly is a self hosted, server based photograph management and de-duplication application. It is designed to index an extremely large collection of images and make them easy to search and retrieve using metadata such as IPTC keyword tags, folder names and file names, and it serves a modern browser interface for browsing, tagging and downloading, with optional on device object and face recognition.
The image runs the official Damselfly container (built on .NET, hosted Blazor WebAssembly) and pins the exact image digest, recorded in /opt/damselfly/VERSION. Damselfly runs under Docker managed by a systemd unit and is published to loopback only (127.0.0.1:6363). nginx is the sole network facing surface and terminates TLS on port 443, reverse proxying to Damselfly. Port 80 redirects to HTTPS. Your photos, the thumbnail cache and the search index live on a dedicated data disk mounted at /var/lib/damselfly, provisioned automatically with every VM.
Secure by default. Stock Damselfly ships with authentication turned off, which would leave every image open to anyone who can reach the server, and when authentication is enabled the first person to register becomes the administrator. This image turns authentication on, disables self registration, and generates a unique administrator credential on each virtual machine's first boot. Only a one way (PBKDF2) hash of the password is stored in Damselfly's database; the plain password is placed in a root only file for the administrator to read. There are no shared or default credentials, and nothing is baked into the image.
What is included:
-
The official Damselfly container image, digest pinned and recorded in
/opt/damselfly/VERSION, run under systemd via Docker -
Damselfly published to loopback only (
127.0.0.1:6363); it is never network exposed directly -
nginx terminating TLS on :443 and reverse proxying to Damselfly, with HSTS and sensible security headers
-
Port
:80returns a301redirect to HTTPS for every path except an unauthenticated/healthzendpoint (HTTP 200) for load balancer probes -
Authentication on by default with a unique admin credential generated per VM on first boot; self registration is disabled and only the one way hash is stored in the database, the plain password lands in a root only file
-
A dedicated data disk mounted at
/var/lib/damselflyholding your photos (pictures/), the search index and config (config/) and the thumbnail cache (thumbs/), captured into the image so every VM is provisioned with it -
A small set of sample photos so the gallery is populated the moment you sign in; replace them with your own
-
Optional object and face recognition, included in the image but off by default; enable it from the Config page when you want it
-
A self signed TLS certificate regenerated per VM on first boot (its Subject Alternative Names include the VM IP, hostname and
127.0.0.1); replace it with your own CA signed certificate for production -
A built in self test at
/usr/local/bin/damselfly-selftestthat proves the authenticated login end to end over TLS -
Ubuntu 24.04 LTS base with the latest security patches applied at build time
-
Azure Linux Agent for seamless cloud integration and SSH key injection
-
24/7 cloudimg support with a guaranteed 24 hour response SLA
Prerequisites
-
An Azure subscription with permission to deploy virtual machines
-
An SSH key pair for administrative access to the VM as the
azureuseraccount -
A Network Security Group allowing inbound TCP
443(HTTPS) and80(redirect) from the networks that should reach the gallery, and22(SSH) from your management network only -
A recommended size of Standard_B2s or larger (use a larger size such as Standard_D2s_v3 if you plan to enable object and face recognition)
Step 1: Deploy from the Azure Portal
-
Locate the Damselfly on Ubuntu 24.04 LTS image in the Azure Marketplace and select Create.
-
Choose your subscription, resource group and region.
-
Select a VM size (Standard_B2s or larger) and provide your SSH public key for the
azureuseraccount. -
On the Networking tab, allow inbound
443and80from your users, and restrict22to your management network. -
Review and create. When the VM is running, browse to
https://<your-public-ip>/.
Step 2: Deploy from the Azure CLI
Deploy the image from the command line, restricting SSH to your management network. Replace the placeholder values with your own before running:
az vm create \
--resource-group my-resource-group \
--name damselfly \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
# Allow the gallery from your users and SSH from your management network only
az vm open-port --resource-group my-resource-group --name damselfly --port 443 --priority 1001
az network nsg rule create --resource-group my-resource-group --nsg-name damselflyNSG \
--name allow-ssh --priority 1002 --destination-port-ranges 22 \
--source-address-prefixes <your-mgmt-cidr> --access Allow --protocol Tcp
When the VM is running, browse to https://<public-ip>/.
Step 3: Retrieve your per instance admin credential
Authentication is on by default. Each VM generates its own admin credential on first boot, written to a root only file. Read it over SSH:
ssh azureuser@<vm-ip> 'sudo cat /root/damselfly-credentials.txt'
The file contains the DAMSELFLY_USER, DAMSELFLY_EMAIL, DAMSELFLY_PASS and DAMSELFLY_URL for this specific VM. Keep it secret. Damselfly's database only ever stores a one way hash of the password, never the plain text.
Step 4: Sign in to Damselfly
Browse to https://<vm-ip>/. Because the certificate is self signed per VM, your browser will show a certificate warning the first time; accept it to proceed (or install the per VM certificate, or place a CA signed certificate in front, as covered in Step 10). Damselfly presents a login screen.

Sign in with the email address and password from Step 3 (the login uses the email, not the username). Damselfly opens on the gallery, showing the photos in your library as a responsive grid. The included sample photos are visible immediately, with the search bar and Basket, Keywords and Folders panels alongside them, and the signed in admin user shown in the status bar.

Step 5: View and browse your photos
Click a photo to open it in the full image view. The toolbar lets you move between images, download, rotate and zoom, and the side panels show the image keywords and any map data. Damselfly reads folder and file names, so subfolders of your library appear as browsable folders in the Folders panel.

Step 6: Add your own photos
Your library reads from /var/lib/damselfly/pictures on the dedicated data disk. Copy your own photos and videos into that folder (preserving any subfolder structure you want as folders), then rescan from the UI to index them:
# Copy your photos into the library folder (use sudo; the folder is on the data disk)
sudo cp -r ~/my-photos/. /var/lib/damselfly/pictures/
Damselfly indexes the library in the background and picks up new folders automatically; you can also trigger a rescan from the UI. Thumbnails are written to /var/lib/damselfly/thumbs, and the search index to /var/lib/damselfly/config, both on the same data disk. Because the data disk is captured with the image and re attached to every VM, your photos and index survive a redeploy of the OS disk.
Step 7: Manage settings and enable recognition
The signed in admin user can open the Config page to manage settings, users, image recognition and more. Object and face detection are included in the image but off by default so nothing runs until you turn it on; enable them under the Image Recognition tab when you want to search your library by its content. The User Management tab lets you add further users and roles.

Step 8: Verify the deployment
SSH to the VM as azureuser and confirm the services are running and Damselfly is published on loopback only:
systemctl is-active docker damselfly nginx
sudo ss -tlnp | grep 6363
All three services report active, and Damselfly is published on 127.0.0.1:6363 only. nginx is the only component exposed on :80 and :443.

Run the built in self test. It reads this VM's credential and proves the full round trip over TLS: authentication is enforced, a login with a wrong password is refused, and a login with the per VM credential returns a signed token:
sudo /usr/local/bin/damselfly-selftest

Step 9: TLS, authentication and the per instance certificate
nginx terminates TLS on port 443 and redirects plain HTTP on port 80 to HTTPS. Confirm the redirect and the unauthenticated health probe from the VM:
curl -s -o /dev/null -w 'port 80 -> HTTP %{http_code}\n' http://127.0.0.1/
curl -sk -o /dev/null -w 'healthz over TLS -> HTTP %{http_code}\n' https://127.0.0.1/healthz
Port 80 returns 301 and the health endpoint returns 200. A login carrying a wrong password is refused, while a login carrying this VM's credential returns a signed token, and the ForceLogin setting confirms authentication is enforced. The self signed certificate is regenerated per VM on first boot, with the VM IP and hostname in its Subject Alternative Names:

Step 10: Replace the certificate for production
The per VM certificate is self signed, so browsers warn on first use. For a public deployment, put a real certificate in front. The simplest path is to point a DNS name at the VM and obtain a free certificate with Certbot:
# Point https://<your-domain> at this VM first, then:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>
Alternatively, terminate TLS at an Azure Application Gateway or a load balancer in front of the VM and forward to port 443.
Step 11: Baked version and credential summary
The baked image digest and this VM's credential summary are recorded on the VM. The password line is redacted below; read the full value from the root only file in Step 3:

Security notes
-
No default login. Authentication is on by default, self registration is disabled and a unique admin credential is generated on each VM's first boot. Only a one way hash is stored in Damselfly's database; the plain password lives in the root only
/root/damselfly-credentials.txt. The stock no login default and first to register administrator are never shipped. -
Loopback only application. Damselfly is published on
127.0.0.1:6363and is only reachable through the nginx TLS reverse proxy on:443. Keep it that way and let nginx (or a load balancer) be the sole network facing surface. -
Data on a dedicated disk. Your photos, thumbnail cache and index live on the data disk at
/var/lib/damselfly, separate from the OS disk. Back up this disk to protect your library. -
Restrict access. Allow
443only from the networks that need it, keep22restricted to your management network, and replace the self signed certificate with a CA signed one for production. -
Recognition is opt in. Object and face detection run on device and are off by default. Enable them from the Config page when you want them; they use additional CPU, so size the VM accordingly.
Support
This image is backed by 24/7 cloudimg support with a guaranteed 24 hour response SLA. Contact support@cloudimg.co.uk for assistance. Damselfly is open source software distributed under the GNU General Public License v3.0 and is free; the cloudimg charge covers packaging, hardening, security patching, image maintenance and support.