Storage Azure

Damselfly on Ubuntu 24.04 on Azure User Guide

| Product: Damselfly on Ubuntu 24.04 LTS on Azure

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 :80 returns a 301 redirect to HTTPS for every path except an unauthenticated /healthz endpoint (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/damselfly holding 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-selftest that 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 azureuser account

  • A Network Security Group allowing inbound TCP 443 (HTTPS) and 80 (redirect) from the networks that should reach the gallery, and 22 (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

  1. Locate the Damselfly on Ubuntu 24.04 LTS image in the Azure Marketplace and select Create.

  2. Choose your subscription, resource group and region.

  3. Select a VM size (Standard_B2s or larger) and provide your SSH public key for the azureuser account.

  4. On the Networking tab, allow inbound 443 and 80 from your users, and restrict 22 to your management network.

  5. 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.

The Damselfly login page showing the Damselfly logo, a Log in to Damselfly heading and a form with Email address and Password fields, a Remember Me checkbox and a Login button

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.

The Damselfly gallery after signing in as admin, showing four sample photos in a grid with the Basket, Image Keywords and Folders side panels, a pictures folder containing four images, a search bar, and the admin user and a Connected status in the 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.

A sample image opened in the Damselfly full image view, showing the photo large in the centre with a filename in the top right, an image toolbar for navigation, download and zoom, and Image Keywords and Map side panels on the left

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.

The Damselfly Configuration Settings page showing the User Settings, Image Recognition, Email Notifications, Wordpress, User Management and System Settings tabs, with a Theme selector, a Similarity Threshold of 75 and a Save Settings button

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.

systemctl reports docker, damselfly and nginx all active, and ss shows Damselfly published on 127.0.0.1:6363 loopback only with nginx listening on port 80 and port 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

The damselfly-selftest output reporting OK: authentication is enabled with ForceLogin, a wrong password is refused, and the per VM login returns a JWT, all over TLS

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:

curl shows port 80 returning a 301 redirect, a login with a wrong password refused, a login with the per VM credential returning a JWT, the ForceLogin setting reported as True, and openssl printing the per VM self signed certificate subject and 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:

The /opt/damselfly/VERSION file showing the baked Damselfly version and pinned image digest, a listing of the sample photos in the library folder, and the per VM damselfly-credentials.txt showing the admin username, email and URL with the password redacted

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:6363 and 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 443 only from the networks that need it, keep 22 restricted 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.