P3
Applications Azure

phpList 3 Newsletter Manager on Ubuntu 24.04 on Azure User Guide

| Product: phpList 3 Newsletter Manager on Ubuntu 24.04 LTS on Azure

Overview

phpList is the open source newsletter and email campaign manager used by charities, publishers, businesses and community groups worldwide to manage subscriber lists and send bulk email. It provides subscriber list management, subscribe, confirm and unsubscribe pages, an HTML and plain text campaign editor, attribute based segmentation, and open, click and bounce tracking, all from one web console. The cloudimg image ships phpList 3 served by Apache and PHP 8.3 on a hardened, fully patched Ubuntu 24.04 LTS base, together with a bundled local MySQL server so the appliance is complete and useful on its own. The database is already initialised and the administrator account is created, so no browser install wizard is ever exposed. The bundled MySQL listens only on the loopback interface (127.0.0.1:3306). A unique administrator password is generated on the first boot of every VM. Backed by 24/7 cloudimg support.

What is included:

  • phpList 3 served by Apache and PHP 8.3, managed by systemd
  • A bundled MySQL server holding the phpList database, already installed and initialised
  • The database schema and admin account created at build time, so no web install wizard is ever exposed
  • A per VM administrator password generated on first boot and recorded in a root only file
  • No shipped default login: the administrator password ships rotated to a discarded random and the real per VM password is set on first boot
  • MySQL bound to 127.0.0.1 only, never exposed to the network, with root authenticated by the local socket
  • The subscriber pages at /lists/ and the admin console at /lists/admin/
  • apache2.service and mysql.service as enabled systemd units
  • 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 a sensible starting point; step up to a larger size for large lists or heavy send volumes. NSG inbound: allow 22/tcp from your management network, 80/tcp for the application and 443/tcp if you terminate TLS on the VM. The bundled MySQL is never exposed: it listens on 127.0.0.1 only, so port 3306 stays off the network.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for phpList 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), HTTP (80) and HTTPS (443). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

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

Then open ports 80 and 443:

az vm open-port --resource-group <your-rg> --name phplist --port 80,443

Step 3 - Confirm the services are running

SSH in as azureuser and confirm Apache and MySQL are active. Note that MySQL listens only on 127.0.0.1:3306 while Apache serves phpList on port 80.

systemctl is-active apache2 mysql
ss -tlnp | grep -E ':80 |:3306 ' | sed 's/  */ /g'

The apache2 and mysql services active, PHP 8.3 and the installed phpList version, with Apache on port 80 and MySQL bound to loopback 127.0.0.1:3306

Step 4 - Retrieve the per VM administrator password

Every VM generates its own phpList administrator password on first boot and writes it, along with the login user and the console URL, to a root only credentials file. Read it with sudo:

sudo cat /root/phplist-credentials.txt

The per VM phpList credentials file, showing the admin login user, the generated password masked, the console URL and the loopback MySQL details

You sign in to the phpList admin console as user admin with the PHPLIST_ADMIN_PASSWORD from this file. On the box itself you can also run sudo mysql to reach the database directly over the local socket without a password.

Step 5 - Sign in to the admin console

Browse to http://<vm-public-ip>/lists/admin/. You land on the phpList sign in page. Enter username admin and the password from Step 4.

The phpList admin sign in page showing the login and password fields

After signing in you land on the phpList dashboard, with the left navigation for Subscribers, Campaigns, Statistics, System and Config, and a Getting Started panel to import subscribers or start a campaign.

The phpList dashboard after signing in, showing the left navigation and the Getting Started, Last Campaign Results and Help panels

Step 6 - Manage subscriber lists

Open Subscribers then Subscriber lists to create and manage the lists your subscribers belong to. Each list can be public (offered on the subscribe page) or private, and subscribers can belong to several lists. Use Add a list to create a new one, and Import subscribers to bring existing contacts in from a CSV or a pasted list.

The phpList subscriber lists page showing the lists with their member counts, public flag and list IDs, and the Add a list control

Step 7 - Compose and send a campaign

Open Campaigns then Send a campaign to compose a new message, choose the lists to send it to, preview it, and schedule or send it. phpList keeps draft campaigns so you can work on a message over time before sending.

The phpList send a campaign page showing the draft campaigns table and the Start a new campaign control

Step 8 - Configure an SMTP relay to send mail

phpList composes and manages campaigns out of the box, but to actually deliver email you point it at your own SMTP relay (for example Azure Communication Services, SendGrid, Amazon SES, or your organisation's mail server). Edit the configuration file and set your relay, then enable sending:

sudo nano /var/www/html/phplist/public_html/lists/config/config.php

Set (or add) these lines with your relay's details, and change TEST to 0 when you are ready to send real mail:

define('PHPMAILERHOST', 'smtp.your-provider.example');
$phpmailer_smtpuser = 'your-smtp-username';
$phpmailer_smtppassword = 'your-smtp-password';
define('PHPMAILER_SECURE', 'tls');
define('TEST', 0);

phpList sends queued campaigns when the message queue is processed. Process it on a schedule with the bundled command line tool:

sudo -u www-data /usr/local/bin/phplist -pprocessqueue

Add that to a cron job (for example every five minutes) once your relay is configured.

Step 9 - No known or default credentials

The cloudimg image ships with the phpList administrator password rotated to a discarded random value, and the real per VM administrator password is generated with a unique random secret on the first boot of every VM. No known or blank credential authenticates. The admin account is the only phpList super user, and you can prove the model with the built in round trip check, which confirms the per VM administrator signs in through phpList's own login form while a blank password and common weak guesses are all rejected:

sudo mysql -uroot -N -e "SELECT CONCAT(loginname,'  (phpList super user)') FROM phplistdb.phplist_admin WHERE superuser=1"
sudo bash /usr/local/sbin/phplist-cred-roundtrip.sh

The admin account as the only phpList super user, the round trip check confirming the per VM admin authenticates via the login form while blank and weak guesses are rejected, and MySQL bound to loopback only

Step 10 - Verify the stack and the endpoint

Confirm the installed phpList release and that the admin console answers on port 80:

sudo mysql -uroot -N -e "SELECT CONCAT('phpList ',value) FROM phplistdb.phplist_config WHERE item='version'"
curl -sI http://127.0.0.1/lists/admin/ | head -1

The installed phpList version and the admin console returning HTTP 200 with the login form present

Adding your own domain and TLS

The appliance serves plain HTTP on port 80. For production, point a DNS record at your VM and obtain a certificate with Let's Encrypt:

sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d <your-domain>

phpList derives its page links from the request Host header, so once you reach the VM on your domain over HTTPS the subscribe and admin links render correctly with no further change.

Backing up

Your data is the phpList database. Dump it with mysqldump over the local socket and copy the archive off the VM:

sudo mysqldump --protocol=socket -uroot phplistdb > /tmp/phplist-backup.sql

To restore, load the SQL dump back into the phplistdb database. Uploaded campaign images live under the phpList tree at /var/www/html/phplist/public_html/lists/images; archive that directory too if you use it.

Security notes

  • phpList serves plain HTTP on port 80 out of the box. For anything beyond a trusted network, add your own domain and TLS as above, or front the VM with Azure Application Gateway.
  • The bundled MySQL listens on 127.0.0.1 only and is never reachable from the network. root is authenticated by the local socket, so administer it on the box with sudo mysql (no password required) and never expose port 3306.
  • The administrator password is unique per VM and no known or blank credential authenticates. Keep /root/phplist-credentials.txt protected. To rotate the web login password, sign in and change it under System, or from the box set a new one directly:
sudo mysql phplistdb -e "UPDATE phplist_admin SET password=SHA2('<new-password>',256), passwordchanged=NOW() WHERE loginname='admin'"
  • The phpList configuration directory is denied by Apache, so config.php is never web reachable.
  • Apply operating system updates regularly with sudo apt update && sudo apt upgrade; unattended security updates are enabled by default.
  • Restrict inbound 80/tcp and 443/tcp in your NSG to the networks that need access.

Trademark

phpList is an open source project distributed under the GNU Affero General Public License version 3. This image is an independent packaging of the open source phpList software by cloudimg and is not affiliated with, sponsored by, or endorsed by phpList Ltd.

Support

This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating phpList on Azure, contact us at cloudimg.co.uk.