Applications Azure

Animal Shelter Manager on Ubuntu 24.04 on Azure User Guide

| Product: Animal Shelter Manager on Ubuntu 24.04 LTS on Azure

Overview

Animal Shelter Manager (ASM3) is the long-established open-source management system used by animal shelters, rescues and sanctuaries to run their day-to-day operations from one web application. Staff and volunteers record every animal that arrives with its intake reason, species, breed and location on site, then follow it through fostering, reservation, adoption or return to owner. Alongside the animal record sit medical and vaccination schedules, diary entries and tasks, waiting lists, lost-and-found matching, and the people side of the shelter: adopters, fosterers, volunteers, donors and veterinary contacts. Built-in reports and shelter views turn that into the figures a shelter actually has to produce.

The cloudimg image installs ASM3 from the pinned upstream release, runs it as an unprivileged system user behind nginx, and bundles a tuned single-node PostgreSQL database on the same VM so the appliance is completely self-contained. Backed by 24/7 cloudimg support.

What is included:

  • Animal Shelter Manager 3, installed from the pinned upstream tag 51-1 (GPL-3.0), laid out where upstream's own Debian package puts it (/usr/lib/sheltermanager3, config /etc/asm3.conf)
  • A bundled PostgreSQL 16 database on the same VM, tuned for the VM size rather than left at stock defaults, listening on loopback only
  • The application bound to 127.0.0.1:5000 and fronted by nginx on port 80, with an unauthenticated /healthz for load-balancer probes
  • No usable default login. Upstream ASM3 seeds a documented user/letmein superuser and a guest/guest account. This image removes guest entirely and ships every account locked; a unique administrator password, database password and PostgreSQL superuser password are generated on the first boot of each VM
  • asm3-credential-audit.py and asm3-admin-password.py shipped as tools so you can prove no publicly known credential works, and rotate the admin password from the shell
  • Report and document generation via WeasyPrint, ReportLab and xhtml2pdf; XLSX export via openpyxl
  • Fully patched base with unattended security upgrades enabled
  • 24/7 cloudimg support

The Animal Shelter Manager sign-in page served by the cloudimg image

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is the recommended size and comfortably runs both the application and the bundled database for a typical shelter; choose a larger size if you have many concurrent staff users or a large media library. NSG inbound: allow 22/tcp from your management network and 80/tcp for the web interface. Nothing else needs to be open - the database and the application process are bound to loopback and are not reachable from the network.

The appliance serves plain HTTP on port 80 on the VM's own IP so you can evaluate it immediately. Add a real hostname and a TLS certificate before you store live animal, adopter or veterinary records - see "Set your own domain and TLS".

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Animal Shelter Manager by cloudimg, and select Create. On Basics 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) and HTTP (80). Then Review + create followed by Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name animal-shelter-manager \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open the web port on the VM's NSG:

az vm open-port --resource-group <your-rg> --name animal-shelter-manager --port 80 --priority 900

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

On first boot the image generates this VM's administrator password, its PostgreSQL role password and a password for the PostgreSQL superuser, points the application at the VM's own address, and starts the stack. Confirm all four services are active:

systemctl is-active postgresql memcached nginx asm3

Only port 80 is reachable from outside the VM. The application itself, the database and the cache are all bound to the loopback interface:

sudo ss -tlnp | grep -E ':80 |:5000 |:5432 |:11211 '

Animal Shelter Manager services active, with the application, PostgreSQL and memcached bound to loopback and only nginx on port 80

Step 5 - Check the health endpoint

The unauthenticated /healthz endpoint returns 200 and is intended for load-balancer and monitoring probes. It deliberately exposes nothing about the shelter:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz

The ASM3 login page itself should also return 200:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/login

Step 6 - Retrieve the per-VM administrator credentials

Every secret on this VM is generated on its first boot and written to a root-only file. Nothing is shared with any other deployment of this image:

sudo cat /root/asm3-credentials.txt

The file records the web URL, the administrator username and password, the ASM3 database name, username and password, and the PostgreSQL superuser password.

The per-VM credentials file with every secret masked, and the health and login endpoints both returning HTTP 200

Step 7 - Confirm the upstream default login does not work

This is the single most important difference between this image and a hand-rolled ASM3 install. Upstream ASM3 seeds two accounts into every new database and publishes both in its own manual: user with the password letmein, which is a superuser, and guest with the password guest.

On this image the guest account is deleted outright, and the user account ships with a password hash that cannot be satisfied by any input until first boot replaces it with a random per-VM password. Prove it for yourself - both of these return FAIL:

curl -s -X POST http://127.0.0.1/login --data-urlencode 'username=user' --data-urlencode 'password=letmein' --data-urlencode 'database='; echo
curl -s -X POST http://127.0.0.1/login --data-urlencode 'username=guest' --data-urlencode 'password=guest' --data-urlencode 'database='; echo

A shipped audit tool checks every account row against upstream's published defaults and the usual weak passwords, using ASM3's own password-verification code. Run it at any time:

sudo /usr/local/sbin/asm3-credential-audit.py

It prints CREDENTIAL_AUDIT_CLEAN and exits 0 when no publicly known credential works.

Both upstream default logins rejected with FAIL, no guest account row, and the credential audit reporting CREDENTIAL_AUDIT_CLEAN

Step 8 - Sign in to the web interface

Browse to http://<vm-public-ip>/ and sign in with the username and password from the credentials file. You land on the ASM3 main screen: quick links to the shelter and calendar views, a recently-changed strip, the shelter overview counters, alerts, your diary and a timeline of shelter activity.

The Animal Shelter Manager main screen showing the shelter overview counters, alerts, recently changed animals and the activity timeline

Important - ASM3 redirects to its configured address. ASM3 records its own base URL in /etc/asm3.conf and, if the address in your browser does not match it, redirects you there. First boot sets it to this VM's public IP, so browsing to the VM's IP works out of the box. If you put a DNS name, a load balancer or a reverse proxy in front of the VM, you must update base_url and service_url in /etc/asm3.conf and restart asm3.service, or the browser will be redirected back to the raw IP. This also means an SSH port-forward to localhost will not work until you change base_url to match.

Step 9 - Add your first animal

Choose ASM then Add an animal, give the animal a name, species, sex and an estimated age or date of birth, pick an entry reason and a location on the shelter, and select Save. ASM3 generates a shelter code automatically and opens the full animal record, with tabs for vaccinations, tests, medical treatment, clinic appointments, licences, diet, costs, payments, media, diary, transport and movements.

A saved animal record in Animal Shelter Manager, showing the generated shelter code, species, breed, location and the full set of record tabs

The shelter view groups every animal currently on the shelter by location, so you can see the whole shelter at a glance and drag animals between locations:

The Animal Shelter Manager shelter view listing the animals currently on the shelter grouped by location

Step 10 - The bundled PostgreSQL database

The database runs on this same VM and is bound to the loopback interface, so it is never exposed to the network. It is tuned for the VM size rather than left at PostgreSQL's stock defaults - the settings below are what the image ships:

sudo -u postgres psql -tAc "SELECT name || ' = ' || setting || COALESCE(unit,'') FROM pg_settings WHERE name IN ('listen_addresses','shared_buffers','effective_cache_size','work_mem','max_connections','random_page_cost') ORDER BY name"

Animal records live in the animal table of the asm database. You can read them directly, which is useful for reporting or for confirming a backup:

sudo -u postgres psql -d asm -c "SELECT ID, AnimalName, ShelterCode, DateBroughtIn::date AS entered FROM animal ORDER BY ID"

The bundled PostgreSQL tuning applied by the image, and the animal records held in the asm database

Step 11 - Back up the shelter database

The shelter database is the thing you cannot recreate. Take a compressed dump with the PostgreSQL superuser password from the credentials file, and copy it off the VM:

sudo -u postgres pg_dump -Fc asm > /var/tmp/asm-backup-$(date +%Y%m%d).dump && ls -lh /var/tmp/asm-backup-*.dump

Media such as animal photos and scanned paperwork is stored on the filesystem under /var/lib/sheltermanager3/media, which keeps the database small; back that directory up alongside the dump. Restore with pg_restore into an empty database.

Step 12 - Change the administrator password

Change the password from Settings then System user accounts in the web interface, or from the shell with the shipped tool. It hashes the password exactly as the web interface does and refuses to report success unless the new password then genuinely authenticates:

sudo /usr/local/sbin/asm3-admin-password.py user '<your new password>'

Create individual named accounts for your staff rather than sharing the administrator login, and give each one only the roles it needs.

Set your own domain and TLS

The appliance boots on plain HTTP on the VM's IP so you can evaluate it immediately. Before you enter real animal, adopter or veterinary records:

  1. Point a DNS record (for example shelter.example.org) at the VM's public IP.
  2. Install a certificate, for example with sudo apt-get install certbot python3-certbot-nginx and sudo certbot --nginx -d shelter.example.org. Certbot updates server_name in /etc/nginx/sites-available/asm3 and adds the TLS listener.
  3. Update /etc/asm3.conf so ASM3 knows its own address - set base_url = https://shelter.example.org and service_url = https://shelter.example.org/service, and set session_secure_cookie = true now that the site is HTTPS-only.
  4. Restart the application so the new configuration is loaded:
sudo systemctl restart asm3 nginx

Step 3 is not optional. ASM3 redirects any request whose address does not match base_url, so a certificate without the matching configuration change will bounce your browser back to the IP.

Maintenance and production notes

  • Logs: the application logs to /var/log/asm3/asm3.log, rotated weekly. Use journalctl -u asm3 for service-level start-up problems and journalctl -u asm3-firstboot to see what first boot did.
  • Scheduled tasks: ASM3's daily batch (animal figures, diary and waiting-list maintenance, publishing) runs from cron.py. Review /usr/lib/sheltermanager3/cron.py all if you want to schedule it, and set your organisation's details in Settings then Options first.
  • Email: no mail transport is configured in the image. Set smtp_server and from_address in /etc/asm3.conf before using the email, mail-merge or online-form features.
  • Updates: apply OS security updates with sudo apt update && sudo apt upgrade; unattended security upgrades are already enabled. ASM3 version upgrades follow upstream's release notes and require python3 cron.py maint_db_update from /usr/lib/sheltermanager3 after replacing the application tree.
  • Security: this image ships no usable default credential. Keep /root/asm3-credentials.txt protected, delete it once you have stored the passwords elsewhere, and re-run sudo asm3-credential-audit.py after any user administration to confirm nothing weak crept in.

Animal Shelter Manager is free software licensed under the GPL-3.0. This image is produced by cloudimg and is not affiliated with, sponsored by, or endorsed by the Animal Shelter Manager project or Sheltermanager Ltd.