Applications Azure

Tendenci on Ubuntu 24.04 on Azure User Guide

| Product: Tendenci on Ubuntu 24.04 LTS on Azure

Overview

This image runs Tendenci 16.16, the open source Association Management System (AMS) and website platform, on Ubuntu 24.04 LTS. Tendenci is built for non-profits, associations and membership organisations: from one platform it manages members and memberships, events with online registration, donations and payments, a member directory, forms, newsletters, a photo and file gallery, and the full public facing website content.

cloudimg delivers Tendenci fully installed and reverse proxied behind nginx, with the gunicorn application server, PostgreSQL 16 with the PostGIS spatial extensions Tendenci requires, and the memcached cache already configured and managed by systemd, so a complete association platform is operational within minutes of launch.

What is included:

  • Tendenci 16.16 installed from the official package into a dedicated Python virtual environment at /opt/tendenci
  • PostgreSQL 16 + PostGIS 3 as the primary database and memcached as the cache backend
  • gunicorn serving the Django application on 127.0.0.1:8000, fronted by nginx on port 80
  • Four systemd units enabled and active: postgresql, memcached, tendenci and nginx
  • Secure by default: no administrator account and no shared secret ship in the image. On first boot a unique Django secret key, a unique site settings key, a unique database password and a unique administrator account are generated and written to a root only file
  • A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
  • 24/7 cloudimg support

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 for evaluation and small deployments; for larger sites choose a size with more memory. NSG inbound: allow 22/tcp from your management network and 80/tcp for the web interface. Tendenci serves plain HTTP on port 80; for production or shared access, terminate TLS in front of it with your own domain (see the final step).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Tendenci 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). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name tendenci \
  --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

# Open the HTTP port so you can reach the web interface
az vm open-port --resource-group <your-rg> --name tendenci --port 80 --priority 900

Step 3 - Retrieve the per VM administrator account

Nothing secret is baked into the image. On the very first boot, a one shot service (tendenci-firstboot.service) generates a fresh Django secret key, a fresh site settings key, a fresh database password and a unique administrator account, all unique to your instance. It writes them to /root/tendenci-credentials.txt, readable only by root. SSH in as azureuser and read them:

$ sudo cat /root/tendenci-credentials.txt
# Tendenci - generated on first boot by tendenci-firstboot.service.
# These credentials are unique to THIS VM. Store them somewhere safe.

tendenci.url=http://20.55.10.42/
tendenci.admin.user=admin
tendenci.admin.pass=Xq7pR2mK9wU4nZ8vB3hL6yD1

# Canonical keys consumed by the cloudimg smoke verifier + guide substitution:
TENDENCI_URL=http://20.55.10.42/
TENDENCI_ADMIN_PASSWORD=Xq7pR2mK9wU4nZ8vB3hL6yD1

The values above are an example; your instance will have its own unique administrator password.

The Tendenci version and the layout of the per VM credentials file written on first boot

Step 4 - Confirm the services are running

Check that PostgreSQL, memcached, the Tendenci application and nginx are all active:

sudo systemctl is-active postgresql memcached tendenci nginx

All four report active. gunicorn binds to loopback only (127.0.0.1:8000) and nginx publishes the interface on port 80:

sudo ss -tlnp | grep -E ':80 |:8000 '

The four Tendenci services reporting active and the listening ports, nginx on 80 and gunicorn on 127.0.0.1:8000

Step 5 - Confirm the web endpoints

The public homepage and the sign in page both return 200. The Django admin redirects an anonymous request to the login page, which is the secure default.

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

The public homepage and the login page each returning HTTP 200, and the admin redirecting an anonymous request

Step 6 - Sign in to the web UI

Browse to http://<vm-ip>/ to see the public website, served by the built in Tendenci theme.

The Tendenci public homepage served on port 80 with the built in theme

To sign in, go to http://<vm-ip>/accounts/login/ and enter admin with the password from /root/tendenci-credentials.txt.

The Tendenci sign in page

Step 7 - The member dashboard

After signing in you land on the member dashboard at /dashboard/, the control centre for the whole platform: members and memberships, events, articles and news, the member directory, forms, files, invoices and site settings.

The Tendenci member dashboard after signing in, showing the modules for members, events, articles, directories, forms and settings

Step 8 - The Django admin

The full Django administration site is available at /admin/ for low level management of every object in the platform, from announcements and articles to users, chapters and categories.

The Django administration site listing the Tendenci models available for management

Step 9 - First boot secret rotation

The one shot tendenci-firstboot.service is ordered before the application, so the web UI only ever starts once every per VM secret has been generated and a fresh empty database initialised. It is enabled in the shipped image and disables itself once it has run, leaving a sentinel behind. Confirm first boot completed:

test -f /var/lib/cloudimg/tendenci-firstboot.done && echo "first boot complete"

The tendenci first boot service enabled, and its script header describing the per VM secret rotation

Step 10 - Administration

The Tendenci manage.py command is wrapped for convenience: run sudo tendenci-manage <command>. For example, print the framework version, or add another administrator:

sudo tendenci-manage --version
$ sudo tendenci-manage createsuperuser

The application settings live in /opt/tendenci/mysite/conf/settings.py, and the application is managed with sudo systemctl restart tendenci.

Step 11 - Enable HTTPS and outbound email

Tendenci ships on plain HTTP on port 80 so it works immediately, and with a dummy email backend so nothing depends on a mail server. For production, point a DNS record at the VM's public IP, add the hostname to ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS in /opt/tendenci/mysite/conf/settings.py, and terminate TLS with a certificate (a common approach is certbot with an nginx reverse proxy, or Azure Application Gateway in front of the VM). To send newsletters and notifications, set a real EMAIL_BACKEND and SMTP host in the same settings file. Restart the application after editing the configuration:

$ sudo systemctl restart tendenci

Administration and support

This image is a repackaged open source software product with additional charges for cloudimg support services. Our engineers provide 24/7 support for deployment, upgrades, TLS termination, SMTP and payment gateway integration, theme customisation and scaling. Tendenci is a trademark of its respective owner; use of the name here is purely to identify the software this image packages.