This guide is for setting up WHMCS 9.0.6 with PHP 8.3 on Ubuntu 22.04 / 24.04 / 26.04 or Debian 12 / 13.
Important: If WHMCS 9.0.6 is already installed on your server or VPS with root access, you can review only Section 1.3, Section 4.1, and from Section 9 onwards.
Note: Shared hosting is not supported.
Follow the instructions for your operating system.
apt install -y curl software-properties-common ufw
add-apt-repository -y ppa:ondrej/php
apt install -y \
bzip2 certbot composer git net-tools unzip wget whois \
apache2 libapache2-mod-fcgid python3-certbot-apache \
php8.3-cli php8.3-common php8.3-curl php8.3-fpm \
php8.3-bcmath php8.3-bz2 php8.3-gd php8.3-gmp php8.3-imagick \
php8.3-imap php8.3-intl php8.3-mbstring php8.3-soap \
php8.3-swoole php8.3-xml php8.3-xmlrpc php8.3-yaml php8.3-zip \
php8.3-mysqlapt update
apt install -y ca-certificates curl gnupg lsb-release ufw
# PHP (SURY repo)
curl -fsSL https://packages.sury.org/php/apt.gpg \
| gpg --dearmor -o /usr/share/keyrings/sury-php.gpg
echo "deb [signed-by=/usr/share/keyrings/sury-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" \
> /etc/apt/sources.list.d/sury-php.list
apt update
apt install -y \
bzip2 certbot composer git net-tools unzip wget whois \
apache2 libapache2-mod-fcgid python3-certbot-apache \
php8.3-cli php8.3-common php8.3-curl php8.3-fpm \
php8.3-bcmath php8.3-bz2 php8.3-gd php8.3-gmp php8.3-imagick \
php8.3-imap php8.3-intl php8.3-mbstring php8.3-soap \
php8.3-swoole php8.3-xml php8.3-xmlrpc php8.3-yaml php8.3-zip \
php8.3-mysqlOpen the PHP-FPM configuration file:
nano /etc/php/8.3/fpm/php.iniAdd or uncomment the following session security settings:
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Strict"cd /tmp
wget https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xvfz ioncube_loaders_lin_x86-64.tar.gzDetermine the PHP extension directory where the ionCube loader files need to be placed. Run php -i | grep extension_dir and the command will output something like:
extension_dir => /usr/lib/php/20230831 => /usr/lib/php/20230831Make a note of the directory path (e.g., /usr/lib/php/20230831) and copy the appropriate ionCube loader for your PHP version to the PHP extensions directory by running cp /tmp/ioncube/ioncube_loader_lin_8.3.so /usr/lib/php/20230831/
You need to edit the PHP configuration files to include ionCube:
nano /etc/php/8.3/fpm/php.ini
nano /etc/php/8.3/cli/php.iniTo enable ionCube, add the following line at the top of each php.ini file:
zend_extension = /usr/lib/php/20230831/ioncube_loader_lin_8.3.soRestart PHP-FPM to apply the changes:
systemctl restart php8.3-fpmsystemctl enable apache2
systemctl start apache2
nano /etc/apache2/sites-available/whmcs.confAdd the following configuration, edit ServerAdmin and ServerName at least:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/whmcs
ServerName yourdomain.com
<Directory /var/www/whmcs/>
Options +FollowSymlinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/whmcs_error.log
CustomLog ${APACHE_LOG_DIR}/whmcs_access.log combined
</VirtualHost>Then configure Apache for RDAP:
nano /etc/apache2/sites-available/rdap.confAdd the following configuration, edit ServerName at least:
<VirtualHost *:443>
ServerName rdap.example.com
# Reverse Proxy to localhost:7500
ProxyPass / http://localhost:7500/
ProxyPassReverse / http://localhost:7500/
# Gzip Encoding
AddOutputFilterByType DEFLATE text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript
# Security Headers
Header always set Referrer-Policy "no-referrer"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set X-XSS-Protection "1; mode=block"
Header always set Content-Security-Policy "default-src 'none'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; img-src https:; font-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'none'; form-action 'self'; worker-src 'none'; frame-src 'none';"
Header unset Server
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type"
# Log configuration
CustomLog /var/log/apache2/rdap_access.log combined
ErrorLog /var/log/apache2/rdap_error.log
</VirtualHost>a2ensite whmcs.conf
a2ensite rdap.conf
a2enmod rewrite
a2enmod proxy
a2enmod proxy_http
a2enmod headers
a2enmod proxy_fcgi
a2enconf php8.3-fpm
echo 'opcache.enable=0' > /etc/php/8.3/fpm/conf.d/99-disable-opcache.ini
systemctl restart php8.3-fpm
systemctl restart apache2ufw enable
ufw allow 80/tcp
ufw allow 443/tcpmkdir -p /etc/apt/keyrings
curl -o /etc/apt/keyrings/mariadb-keyring.asc 'https://mariadb.org/mariadb_release_signing_key.pgp'Create /etc/apt/sources.list.d/mariadb.sources according to your system.
X-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.nextlayer.at/mariadb/repo/11.8/ubuntu
Suites: jammy
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.ascX-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.nextlayer.at/mariadb/repo/11.8/ubuntu
Suites: noble
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.ascX-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.nextlayer.at/mariadb/repo/11.8/ubuntu
Suites: resolute
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.ascX-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.nextlayer.at/mariadb/repo/11.8/debian
Suites: bookworm
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.ascX-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.nextlayer.at/mariadb/repo/11.8/debian
Suites: trixie
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.ascThen execute the following commands:
apt update
apt install -y mariadb-client mariadb-server php8.3-mysql
mariadb-secure-installation- Access MariaDB:
mariadb -u root -p- Execute the following queries:
CREATE DATABASE registrar;
CREATE USER 'registraruser'@'localhost' IDENTIFIED BY 'RANDOM_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON registrar.* TO 'registraruser'@'localhost';
FLUSH PRIVILEGES;Replace registraruser with your desired username and RANDOM_STRONG_PASSWORD with a secure password of your choice.
Download WHMCS from their official site. After downloading, upload it to your VPS via SFTP or SCP. Place the zip file in /var/www and extract:
cd /var/www
unzip whmcs.zip -d .
cd whmcs
mv configuration.sample.php configuration.phpcertbot --apache -d yourdomain.com
certbot --apache -d rdap.yourdomain.comIf you have a www subdomain, include it like this:
certbot --apache -d yourdomain.com -d www.yourdomain.comchown -R www-data:www-data /var/www/whmcs
chmod -R 755 /var/www/whmcswget "http://www.adminer.org/latest.php" -O /var/www/whmcs/adm.phpOpen your web browser and navigate to http://yourdomain.com/install to run the WHMCS installation wizard. Follow the on-screen instructions to complete the setup.
After completing the installation, remove the install directory:
rm -rf /var/www/whmcs/installcrontab -eAdd the following line to schedule the WHMCS cron job:
*/5 * * * * /usr/bin/php -q /var/www/whmcs/crons/cron.phpClone the repository to your system:
git clone --branch v1.2.3 --single-branch https://github.com/getnamingo/registrar /opt/registrar
mkdir /var/log/namingo
mkdir /opt/registrar/escrowcd /opt/registrar/whois
composer install
mv config.php.dist config.phpEdit the config.php with the appropriate database details and preferences as required.
Copy whois.service to /etc/systemd/system/. Change only User and Group lines to your user and group.
systemctl daemon-reload
systemctl start whois.service
systemctl enable whois.serviceAfter that you can manage WHOIS via systemctl as any other service.
cd /opt/registrar/rdap
composer install
mv config.php.dist config.phpEdit the config.php with the appropriate database details and preferences as required.
Copy rdap.service to /etc/systemd/system/. Change only User and Group lines to your user and group.
systemctl daemon-reload
systemctl start rdap.service
systemctl enable rdap.serviceAfter that you can manage RDAP via systemctl as any other service.
cd /opt/registrar/automation
composer install
mv config.php.dist config.phpDownload and initiate the escrow RDE client setup:
wget https://team-escrow.gitlab.io/escrow-rde-client/releases/escrow-rde-client-v2.4.0-linux_x86_64.tar.gz
tar -xzf escrow-rde-client-v2.4.0-linux_x86_64.tar.gz
mv escrow-rde-client-v2.4.0-linux_x86_64 escrow-rde-client
rm escrow-rde-client-v2.4.0-linux_x86_64.tar.gzReview and update config.php with the appropriate settings for your environment. Make sure you also complete all steps described in configuration.md before running the automation.
Once you have successfully configured all automation scripts, you are ready to initiate the automation system. Proceed by adding the following cron job to the system crontab using crontab -e:
* * * * * /usr/bin/php8.3 /opt/registrar/automation/cron.php 1>> /dev/null 2>&1git clone https://github.com/getnamingo/whmcs-namingo-registrar
mv whmcs-namingo-registrar/namingo_registrar /var/www/whmcs/modules/addons
chown -R www-data:www-data /var/www/whmcs/modules/addons/namingo_registrar
chmod -R 755 /var/www/whmcs/modules/addons/namingo_registrar-
Go to Settings > Apps & Integrations in the admin panel, search for "Namingo Registrar" and then activate it.
-
Add the following rules to the very top of your WHMCS
.htaccessfile (before the WHMCS-managed section):
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} ^/lookup [NC]
RewriteRule ^lookup$ ./index.php?m=namingo_registrar&page=whois [L,QSA]
RewriteCond %{REQUEST_URI} ^/claims [NC]
RewriteRule ^claims$ ./index.php?m=namingo_registrar&page=tmch [L,QSA]
</IfModule>git clone https://github.com/getnamingo/whmcs-contact-validation
mv whmcs-contact-validation/namingo_contact_validation /var/www/whmcs/modules/addons
chown -R www-data:www-data /var/www/whmcs/modules/addons/namingo_contact_validation
chmod -R 755 /var/www/whmcs/modules/addons/namingo_contact_validation- Go to Settings > Apps & Integrations in the admin panel, search for "Contact Validation" and then activate it.
For every registry backend your registrar wants to support, you need a separate installation of the WHMCS EPP Registrar module. Each module can handle one or more TLDs that share the same configuration details.
To configure a TLD using the Namingo WHMCS EPP module, follow these steps:
-
Generate a Customized Module. Use the module customizer to generate the appropriate EPP module for your target registry.
-
Download the generated .zip file and extract its contents to the following path
/var/www/whmcs/modules/registrars/NAME, replacing NAME with the module name. -
Copy the registry-specific
key.pemandcert.pemfiles into the same NAME directory:
cp /path/to/key.pem /var/www/whmcs/modules/registrars/NAME/
cp /path/to/cert.pem /var/www/whmcs/modules/registrars/NAME/- Set the correct permissions. Ensure the files and directory have the proper ownership and access rights:
chown -R www-data:www-data /var/www/whmcs/modules/registrars/NAME
chmod -R 755 /var/www/whmcs/modules/registrars/NAME-
Go to Settings > Apps & Integrations in the admin panel, search for [MODULE] and then activate.
-
Configure from Configuration -> System Settings -> Domain Registrars. If you are configuring a gTLD, enable both "gTLD Registry" and "Use Minimum Data Set" options.
-
Add a new TLD using Configuration -> System Settings -> Domain Pricing.
-
Create a
whois.jsonfile in/var/www/whmcs/resources/domainsand add the following:
[
{
"extensions": ".yourtld",
"uri": "socket://your.whois.url",
"available": "NOT FOUND" // or No match for for Verisign
}
]To execute the required OT&E tests by various registries, you can use our EPP client at https://github.com/getnamingo/epp-client
- Download the latest release archive of the module.
- Extract the archive on your local machine.
- Upload the
whmcs_dnsdirectory to your WHMCS installation so the final structure is:/modules/addons/whmcs_dns/ - Verify that the module files are readable by the web server user.
- Log in to the WHMCS Admin Area.
- Navigate to System Settings → Addons.
- Locate DNS Hosting in the list.
- Click Activate.
To use the BIND9 module, you must install the bind9-api-server on your master BIND server. This API server allows for seamless integration and management of your DNS zones via API.
Make sure to configure the API server according to your BIND installation parameters to ensure proper synchronization of your DNS zones.
After activating the addon, configure the module settings in WHMCS → System Settings → Addons:
-
DNS Provider
Identifier of the PlexDNS-supported provider
(e.g.Desec,PowerDNS,Cloudflare, etc.) -
API Key
API key for the selected DNS provider. -
SOA Email
Email address used in the SOA record (where applicable). -
Nameservers (NS1–NS5)
Nameservers that clients should point their domains to when using this DNS service.
Click Save Changes to apply the configuration.
- Clients access DNS management from their Domain Details page.
- A “DNS Manager” link appears in the domain sidebar.
- DNS zones are not created automatically.
- Clients must explicitly click “Enable DNS” to create a DNS zone.
- Once enabled, DNS records can be added, edited, or deleted.
- Clicking “Disable DNS” removes (deletes) the DNS zone from the provider.
-
Footer Compliance Links
Your website footer must include links to all required ICANN documents, as well as your own Terms and Conditions and Privacy Policy. -
Company Information on Contact Page
Your Contact page must clearly display your full company details, including:- Legal company name
- Registration number
- Registered address
- Name of the Chief Executive Officer (CEO)
-
ICANN Transfer Notifications
You must enable ICANN transfer notifications in accordance with the instructions provided in hooks.md. -
ICANN MoSAPI Monitoring
MoSAPI is ICANN’s official platform for monitoring registrar compliance and domain abuse reports.To enable MoSAPI support, install the Namingo MoSAPI Monitor module:
git clone https://github.com/getnamingo/whmcs-mosapi-monitor
mv whmcs-mosapi-monitor/mosapi_monitor /var/www/whmcs/modules/addons
chown -R www-data:www-data /var/www/whmcs/modules/addons/mosapi_monitor
chmod -R 755 /var/www/whmcs/modules/addons/mosapi_monitor- Go to Settings → Apps & Integrations in the WHMCS admin area, search for "ICANN MoSAPI", activate the module, and then configure it from its respective configuration menu.
- Backup
Update your database details in
automation/backup.json(in both required sections) and confirm that thecron.phpcronjob is active to automate backups.