phpList podman quadlet + bootstrap (admin/admin default)
Find a file
2026-04-20 12:01:00 +02:00
.gitignore phpList quadlet + MariaDB + bootstrap.sh (admin/admin) 2026-04-20 10:53:23 +02:00
bootstrap.sh phpList quadlet + MariaDB + bootstrap.sh (admin/admin) 2026-04-20 10:53:23 +02:00
quadlet-phplist-db.container phpList quadlet + MariaDB + bootstrap.sh (admin/admin) 2026-04-20 10:53:23 +02:00
quadlet-phplist.container phpList quadlet + MariaDB + bootstrap.sh (admin/admin) 2026-04-20 10:53:23 +02:00
quadlet-phplist.network phpList quadlet + MariaDB + bootstrap.sh (admin/admin) 2026-04-20 10:53:23 +02:00
README.md route SMTP through host postfix (host.containers.internal:25) 2026-04-20 12:01:00 +02:00

phpList on ps1raf

Rootless-podman quadlet deployment of phpList 3.6.16 — open-source mailing-list / newsletter manager — on ps1raf.

Access

  • UI: http://localhost:8082/lists/admin/
  • Login: admin / admin
  • Admin email: admin@ps1raf.local (placeholder — change in Config → Manage administrators)
  • Outbound mail host: host.containers.internal (shared relay; see app.env)

Test install — replace admin with a strong password before putting this in front of real subscribers.

Layout

File Purpose
~/.config/containers/systemd/phplist.network Internal podman network phplist
~/.config/containers/systemd/phplist-db.container MariaDB 11 backend, data at data/db/
~/.config/containers/systemd/phplist.container phplist/phplist:3.6.16, published on host :8082, uploads at data/images/
db.env MariaDB root + app creds (mode 600, gitignored)
app.env phpList DB_HOST/NAME/USER/PASSWORD/MAILHOST (mode 600, gitignored)
bootstrap.sh Idempotent first-run helper: initialises tables via the web installer URL, then upserts the admin/admin row

Secrets master copy lives in ~/.env (keys PHPLIST_DB_PASSWORD, PHPLIST_DB_ROOT_PASSWORD). The *.env files in this directory are derived copies.

Bring-up from scratch

# 1. generate creds (if not already in ~/.env)
openssl rand -hex 16   # PHPLIST_DB_PASSWORD
openssl rand -hex 16   # PHPLIST_DB_ROOT_PASSWORD
# …append to ~/.env, then regenerate db.env / app.env (see below).

# 2. regenerate the container env files from ~/.env
cat > db.env  <<EOF
MARIADB_ROOT_PASSWORD=$(grep ^PHPLIST_DB_ROOT_PASSWORD= ~/.env | cut -d= -f2)
MARIADB_DATABASE=phplist
MARIADB_USER=phplist
MARIADB_PASSWORD=$(grep ^PHPLIST_DB_PASSWORD= ~/.env | cut -d= -f2)
EOF
cat > app.env <<EOF
DB_HOST=phplist-db
DB_NAME=phplist
DB_USER=phplist
DB_PASSWORD=$(grep ^PHPLIST_DB_PASSWORD= ~/.env | cut -d= -f2)
MAILHOST=host.containers.internal
EOF
chmod 600 db.env app.env

# 3. start the services
systemctl --user daemon-reload
systemctl --user start phplist-db.service
systemctl --user start phplist.service

# 4. first-run init (creates tables, sets admin/admin)
./bootstrap.sh

Why web-triggered init, not phplist CLI

The upstream entrypoint runs phplist -pinitialise but phpList issue #718 makes that a no-op. The web installer at ?page=initialise&firstinstall=1&tk=<csrf> is the only reliable path — bootstrap.sh scrapes the token from the landing page and GETs the URL.

The phplist_admin row seeded by the installer has empty password and email. Because config.php pins HASH_ALGO=sha256, we replace it via SQL with SHA256('admin') + a placeholder email + superuser=1.

Queue processing

Cron inside the container runs service cron start from the entrypoint. The image's default crontab invokes phplist -pprocessqueue periodically; no host-side timer is required for sending. Monitor with podman logs phplist.

Known caveats

  • The image hard-codes HASH_ALGO=sha256 in /etc/phplist/config.php; if a future phpList release deprecates sha256 the bootstrap password hash will need updating.
  • No SSL yet — Step-CA cert will be added when phpList is used for anything more than local testing.
  • MAILHOST is set to the LAN smarthost but no auth is passed; if the smarthost requires SMTP AUTH, extend app.env with PHPMAILERHOST / user / pass and rebuild config.php overrides.