Every FreePBX UK instance starts from a maintained hardened snapshot. Nano² and the 7-day Free Trial share the Nano² snapshot; Micro⁴, Macro⁸, and Mega¹⁶ each have their own.
The most recent tested snapshot for each plan is used as the basis for the next. A fresh temporary droplet is created from it, brought fully up to date, checked, prepared, sanitised, and shut down cleanly before the replacement snapshot is captured. New snapshots are created at least monthly, and sooner when a defect is identified or developments in Debian, FreePBX, DigitalOcean, or the surrounding platform require it.
A customer order then triggers a separate automated provisioning template that personalises, hardens, validates, and cleans the new instance before customer access is released. The post-order provisioning process takes around seven minutes and requires no manual intervention.
bash -c 'PASS=0;FAIL=0; GREEN="\033[0;32m"; RED="\033[0;31m"; NC="\033[0m"; TAG="free""pbxUK"; DROP="my""-droplet"; PFX="provision""ing-"; AMI="${PFX}ami.sh"; REPORT="${PFX}report.sh"; CLEANUP="${PFX}cleanup.sh"; ONCE="${TAG}-once"; SCAN="/run/.prov_scan.$$"; PATFILE="/run/.prov_patterns.$$"; TAGFILE="/run/.prov_tag.$$"; umask 077; printf "%s\n" "$TAG" > "$TAGFILE"; printf "%s\n%s\n%s\n" "$TAG" "$DROP" "${PFX}(ami\.sh|report\.sh|cleanup\.sh)" > "$PATFILE"; trap '\''rm -f "$SCAN" "$PATFILE" "$TAGFILE"'\'' EXIT; p(){ echo -e "${GREEN}[OK]${NC} $1"; PASS=$((PASS+1)); }; f(){ echo -e "${RED}[ISSUE]${NC} $1"; FAIL=$((FAIL+1)); }; echo ""; echo "FreePBX Provisioning Verification"; echo "----------------------------------"; echo "This check verifies setup cleanup and core service health."; echo ""; echo "System cleanup:"; [ ! -f "/root/$AMI" ] && p "Setup scripts removed" || f "Setup script still present"; [ ! -f "/root/$REPORT" ] && p "Reporting scripts removed" || f "Reporting script still present"; [ ! -f "/root/$CLEANUP" ] && p "Cleanup process completed" || f "Cleanup script still present"; echo ""; echo "Background services:"; UNITS="$(systemctl list-unit-files 2>/dev/null)"; case "$UNITS" in *"$ONCE"*) f "Setup service still exists";; *) p "No setup services remain";; esac; case "$UNITS" in *"${PFX}report"*) f "Reporting service still exists";; *) p "No reporting services remain";; esac; echo ""; echo "Cloud provisioning data:"; [ ! -d /var/lib/cloud/instance ] && p "Instance data removed" || f "Instance data still present"; [ ! -d /var/tmp/cloud-init ] && p "Temporary cloud files removed" || f "Temporary cloud files still present"; echo ""; echo "Mail configuration:"; postconf relayhost 2>/dev/null | grep -qE "relayhost = *$" && p "Mail relay cleared" || f "Mail relay still configured"; [ ! -f /etc/postfix/sasl_passwd ] && p "No stored mail credentials remain" || f "Mail credentials file still exists"; echo ""; echo "Timezone:"; fwconsole setting PHPTIMEZONE 2>/dev/null | grep -q "Europe/London" && p "PHPTIMEZONE set to Europe/London" || f "PHPTIMEZONE not set correctly"; grep -q "date.timezone = \"Europe/London\"" /etc/php/*/apache2/php.ini 2>/dev/null && p "PHP ini timezone correct" || f "PHP ini timezone not set correctly"; timedatectl | grep -q "Europe/London" && p "OS timezone set to Europe/London" || f "OS timezone not set correctly"; echo ""; echo "Logs and traces:"; grep -qif "$TAGFILE" /var/log/cloud-init.log 2>/dev/null && f "Provisioning references found in cloud-init log" || p "No provisioning references in cloud-init log"; grep -qif "$TAGFILE" /var/log/cloud-init-output.log 2>/dev/null && f "Provisioning references found in cloud-init output log" || p "No provisioning references in cloud-init output log"; echo ""; echo "Filesystem scan (full disk):"; echo "Searching file contents for known provisioning identifiers"; SP="/-\\|"; i=0; (find / \( -path /proc -o -path /sys -o -path /dev -o -path /run -o -path /var/lib/apt/lists \) -prune -o -type f -print0 2>/dev/null | xargs -0 -r grep -IlEf "$PATFILE" 2>/dev/null > "$SCAN" & PID=$!; while kill -0 $PID 2>/dev/null; do i=$(( (i+1) %4 )); printf "\rScanning... %s" "${SP:$i:1}"; sleep 0.2; done; wait $PID); echo ""; if [ -s "$SCAN" ]; then f "Known provisioning identifiers found on disk"; head -n 10 "$SCAN"; else p "No known provisioning identifiers found on disk"; fi; echo ""; echo "Journal scan:"; journalctl 2>/dev/null | grep -qiEf "$PATFILE" && f "Provisioning references found in journal" || p "No provisioning references in journal"; echo ""; echo "Boot history:"; BOOT_COUNT=$(journalctl --list-boots 2>/dev/null | wc -l); [ "$BOOT_COUNT" -ge 2 ] && p "Multiple boot cycles detected ($BOOT_COUNT boots)" || f "Expected multiple boot cycles, found only $BOOT_COUNT"; echo ""; echo "Core services:"; asterisk -rx "core show version" >/dev/null 2>&1 && p "Asterisk running" || f "Asterisk not running"; systemctl is-active mariadb >/dev/null 2>&1 && p "MariaDB running" || f "MariaDB not running"; systemctl is-active apache2 >/dev/null 2>&1 && p "Web server running" || f "Web server not running"; systemctl is-active fail2ban >/dev/null 2>&1 && p "Fail2Ban active" || f "Fail2Ban not running"; echo ""; echo "----------------------------------"; if [ "$FAIL" -eq 0 ]; then echo -e "${GREEN}[OK] All checks passed. Setup cleanup and core services verified.${NC}"; else echo -e "${RED}[ISSUE] Some checks failed. Review the items above.${NC}"; fi; echo ""'
root@my-droplet:~# bash -c '...' FreePBX Provisioning Verification ---------------------------------- This check verifies setup cleanup and core service health. System cleanup: [OK] Setup scripts removed [OK] Reporting scripts removed [OK] Cleanup process completed Background services: [OK] No setup services remain [OK] No reporting services remain Cloud provisioning data: [OK] Instance data removed [OK] Temporary cloud files removed Mail configuration: [OK] Mail relay cleared [OK] No stored mail credentials remain Timezone: [OK] PHPTIMEZONE set to Europe/London [OK] PHP ini timezone correct [OK] OS timezone set to Europe/London Logs and traces: [OK] No provisioning references in cloud-init log [OK] No provisioning references in cloud-init output log Filesystem scan (full disk): Searching file contents for known provisioning identifiers [OK] No known provisioning identifiers found on disk Journal scan: [OK] No provisioning references in journal Boot history: [OK] Multiple boot cycles detected (2 boots) Core services: [OK] Asterisk running [OK] MariaDB running [OK] Web server running [OK] Fail2Ban active ---------------------------------- [OK] All checks passed. Setup cleanup and core services verified. root@my-droplet:~#