MemberMatters on Ubuntu 24.04 on Azure User Guide
Overview
MemberMatters is an open source membership, billing and access-control platform for makerspaces, hackerspaces and community groups. It handles member sign-up and a self-service member portal, recurring membership payments (via Stripe), and physical access control for doors, interlocks and tools, together with a full staff admin interface and a REST API. The cloudimg image runs the official MemberMatters production stack under Docker Compose, pinned to release v3.8.0: a Django backend serving the REST API, the pre-built Vue/Quasar single-page front end served by nginx, a PostgreSQL 15 database, a Redis cache and two Celery workers for background tasks. The whole stack is published on port 8000 by the built-in nginx. Every secret - the PostgreSQL password and the Django SECRET_KEY (which is also the JWT signing key) - is rotated on the first boot of every VM, and a fresh Django superuser plus an active demo member are seeded on a clean database so a new VM shows real portal content immediately. Backed by 24/7 cloudimg support.
What is included:
- The official MemberMatters
v3.8.0stack running under Docker Compose (webapp, Celery worker, Celery beat, PostgreSQL 15 and Redis 7), pinned so it never silently upgrades - The pre-built Vue/Quasar single-page front end and Django REST API, served by nginx on
:8000- no customer build toolchain required - JWT authentication (HS256) signed and verified server-side with the per-VM Django
SECRET_KEY; the shipped front end holds no signing or verification key - A per-VM Django superuser and an active demo member generated on first boot - unique passwords recorded in a root-only file - so every VM is secured independently
- All optional integrations (Stripe billing, email, SMS, door/tool controllers, OIDC SSO) are runtime configuration and are off by default, so the portal and admin work standalone
- The whole stack managed as one
membermatters.servicesystemd unit, plusdocker.service, both enabled - PostgreSQL and Redis bound to the internal Docker network only - just
22/tcp(SSH) and8000/tcp(MemberMatters) are exposed - 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 suitable starting size for evaluation and small spaces; scale up for larger memberships. NSG inbound: allow 22/tcp from your management network and 8000/tcp for the portal. MemberMatters serves plain HTTP on port 8000; for production, put it behind 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 MemberMatters 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 a custom 8000 rule. Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name membermatters \
--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 membermatters --port 8000 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the stack is running
The MemberMatters containers run as a Docker Compose stack managed by a single systemd unit. On first boot the stack rotates every secret, recreates itself on a fresh database, applies migrations and seeds the accounts; the multi-container stack can take a minute or two to become fully healthy after the VM is created.
systemctl is-active membermatters.service
cd /opt/membermatters && sudo docker compose ps
You should see active, and every service (mm-webapp, mm-postgres, mm-redis, mm-celery-worker, mm-celery-beat) reporting Up.

Step 5 - Retrieve your per-VM credentials
Every VM generates its own admin and demo-member passwords on first boot and records them in a root-only file. Read them with sudo:
sudo cat /root/membermatters-credentials.txt
The file lists the portal URL, the Django superuser (admin@cloudimg.local), the Django admin URL, and an active demo member (demo@cloudimg.local). Store these somewhere safe and change them after first sign-in.

Step 6 - How first-boot secret rotation works
A one-shot membermatters-firstboot.service runs once on the first boot of every VM. It generates a fresh PostgreSQL password and a fresh Django SECRET_KEY (which is also the JWT signing key), wipes the database volume so PostgreSQL initialises clean with the new password, applies migrations, and seeds the superuser and demo member. A sentinel file records that it has run.
systemctl is-active membermatters-firstboot.service
ls -l /var/lib/cloudimg/membermatters-firstboot.done
sudo ls -l /root/membermatters-credentials.txt

Step 7 - Sign in to the member portal
Browse to http://<vm-public-ip>:8000/. The MemberMatters portal presents a login page. Sign in with the admin email and password from Step 5 (or the demo member to see the member experience).

Step 8 - The member dashboard
After signing in, members land on the dashboard with quick cards - report an issue, view the events calendar, and any resource cards your space configures.

Step 9 - Manage your profile
Each member manages their own profile - name, screen name, contact details, digital ID and password - from the account area.

Step 10 - Admin: manage members
Signed in as the admin (staff) account, the Manage -> Members view lists every member with their subscription and membership status, and lets you export a CSV or copy the email list. The seeded demo member and the admin account are both visible here on a fresh VM.

Step 11 - Verify the REST API
MemberMatters issues a JWT via POST /api/token/obtain/ and accepts it as a Bearer token on protected endpoints such as /api/profile/. This round-trip proves end-to-end authentication with your per-VM credentials:
EMAIL=$(sudo grep '^membermatters.admin.email=' /root/membermatters-credentials.txt | cut -d= -f2-)
PASSWORD=$(sudo grep '^MEMBERMATTERS_ADMIN_PASSWORD=' /root/membermatters-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s -H 'Content-Type: application/json' \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" \
http://127.0.0.1:8000/api/token/obtain/ | python3 -c 'import sys,json;print(json.load(sys.stdin)["access"])')
curl -s -o /dev/null -w 'valid token -> HTTP %{http_code}\n' \
-H "Authorization: Bearer $TOKEN" http://127.0.0.1:8000/api/profile/
curl -s -o /dev/null -w 'bad token -> HTTP %{http_code}\n' \
-H 'Authorization: Bearer wrong.token.xyz' http://127.0.0.1:8000/api/profile/
A valid token returns HTTP 200; a bad token is correctly rejected with HTTP 401.

Step 12 - Configure integrations (optional)
MemberMatters runs standalone out of the box - no external services are required to sign in or manage members. When you are ready, enable optional integrations from the Admin Tools settings in the portal:
- Stripe - recurring membership payments and member-bucks top-ups
- Email (Sendgrid or Postmark) and SMS (Twilio) - member notifications
- Door / interlock / tool controllers - physical access control
- OIDC / SSO - MemberMatters can act as an identity provider for other apps
Each is configured at runtime and stored in the database; none is baked into the image.
Security notes
- Change the seeded
admin@cloudimg.localpassword immediately after first sign-in, and create your own named staff accounts. - The per-VM
SECRET_KEY, JWT signing key and PostgreSQL password are unique to each VM and are generated on first boot - no default credential ships in the image. - Only
22/tcpand8000/tcpare exposed; PostgreSQL and Redis are reachable only on the internal Docker network. - For production, terminate TLS at your own domain in front of port 8000, and restrict SSH to your management network.
Support
This image is maintained by cloudimg with 24/7 support. For help deploying or operating MemberMatters on Azure, contact cloudimg support.