Plesk
This page is for hosting companies and administrators who run Exponential on servers managed by Plesk. Plesk is the panel the project itself uses: its development server is AlmaLinux 9 with Plesk, which makes Plesk on AlmaLinux 9 tier 1, tested every day (Tier 1). The page answers how Plesk's PHP and pools are laid out, how to set up a domain for Exponential, what to reload after a change, how certificates, logs and cron work there, and how Velocity runs beside Plesk.
Warning
.htaccess slows down every request. When .htaccess files are enabled (AllowOverride anything but None), let alone
used, Apache looks for them and reads and evaluates them on every request, in every directory of the path, and
page loading times go up drastically (measured). The only real fix is to switch the feature off for
the virtual host: AllowOverride None in the HTTPS virtual host, and the rules in the virtual host's own
configuration as mod_rewrite rules. That is far faster in production speed tests and well worth the time it takes
to optimize a production configuration. Switch over right away: copy the rules of the
example HTTPS virtual host into your virtual host (with the static cache, also
staticcache_offload.conf), set AllowOverride None, run apachectl configtest, reload Apache and
test the site. The same rules for other servers: nginx, LiteSpeed,
Caddy, IIS, Velocity (built in); where virtual host rules go in a control
panel: Plesk, cPanel, DirectAdmin, ISPConfig.
On LiteSpeed or OpenLiteSpeed, the server's own page cache can also answer anonymous visitors and crawlers without PHP: Page caching with LiteSpeed and OpenLiteSpeed.
Every Plesk detail on this page comes from the Exponential sources cited inline. For anything else in Plesk, check Plesk's documentation.
Contents
- What runs on the development server
- Plesk's PHP: versions, extensions, command line
- Setting up a domain
- PHP-FPM pools and the right service
- nginx in front of Apache
- Certificates
- Logs
- Cron
- Velocity beside Plesk
- Known effects of Plesk settings
- Checklist
What runs on the development server
"AlmaLinux 9 (x86_64, RHEL 9 family): The project's development server: Apache 2.4 with PHP-FPM 8.5 from the Plesk panel, and Exponential Velocity on the same installation; SQLite, MariaDB, MongoDB and Oracle (in a container) sites run there, and a PostgreSQL server is available" (Tier 1). Plesk hosts on the other tier 2 distributions are tier 2 (Tier 2).
Plesk's PHP: versions, extensions, command line
From Chapter 2, Plesk:
- "Plesk installs each PHP version under
/opt/plesk/php/<version>/(for example/opt/plesk/php/8.5/bin/php) next to the system's PHP. A domain uses the version chosen in its hosting settings; the command linephpis the system's. Run Composer and the console with the domain's PHP." - "The bundled extensions ship with Plesk's PHP and are switched on under Tools & Settings > PHP Settings; PECL
extensions are installed with
/opt/plesk/php/<version>/bin/pecl install <extension>."
/opt/plesk/php/8.5/bin/php -v
/opt/plesk/php/8.5/bin/php -m
/opt/plesk/php/8.5/bin/php bin/php/console exp:velocity ext checkWarning
The php on the PATH is the system's PHP, not the domain's. Composer run with the wrong PHP "picks package
versions the web PHP cannot run", and a missing extension then shows as a white page
(Command line and web PHP). Always call the domain's
PHP by its path for Composer, the console, the installers and cron.
Setting up a domain
From 8.5.3 Plesk: "Plesk generates the virtual host itself; do not edit its files. In Plesk:
- point the domain's document root at the installation root (the directory with
index.php); - choose 'FPM application served by Apache' in the PHP settings, and the PHP version;
- keep
.htaccess(copied from.htaccess_root); Plesk's Apache reads it; - install the certificate in Plesk (its Let's Encrypt extension or your own) and switch on the redirect to HTTPS."
cd /var/www/vhosts/<domain>/<docroot>
cp .htaccess_root .htaccessOr let the console do the copy, and put config.php into place the same way. In Plesk's SSH Terminal (or an SSH
login) as the subscription's system user, with the domain's PHP:
cd /var/www/vhosts/<domain>/<docroot>
/opt/plesk/php/<version>/bin/php bin/php/console exp:setup:status
/opt/plesk/php/<version>/bin/php bin/php/console exp:setup:htaccess --apply # .htaccess_root -> .htaccess
/opt/plesk/php/<version>/bin/php bin/php/console exp:setup:config --apply # config.php-RECOMMENDED -> config.phpThe files then belong to the subscription's user, as everything else in the docroot. Run as root, every command needs
--allow-root-user; a new file gets the template's owner (never root), and --owner=<subscription-user>:psacln sets
it explicitly. Nothing is written without --apply, and an existing file that differs is shown as a diff and kept
unless you add --force (the old one goes to var/backup/setup/<time>/ first). Plesk's File Manager can do the
plain copy too, but it does not keep the mode and shows no diff. All of it:
Setting up .htaccess and config.php from the console.
The PHP values the setup wizard checks (memory_limit 64M or more, max_execution_time 30 or more,
date.timezone, file_uploads, allow_url_fopen) are set in the domain's PHP settings
(2.5). The MongoDB porting notes set FPM directives such as
request_terminate_timeout in the domain's PHP settings, field Additional configuration directives
("Plesk → Domains → your domain → PHP Settings")
(MongoDB kernel support).
PHP-FPM pools and the right service
- "Each domain has its own PHP-FPM pool in
/opt/plesk/php/<version>/etc/php-fpm.d/<domain>.conf, run by the serviceplesk-php<XY>-fpm(for exampleplesk-php85-fpm), not byphp-fpm. After a PHP change, reload that one." (Chapter 2, Plesk) - "
systemctl restart php-fpmrestarts a different master that no Plesk site uses." (8.5.3)
ls /opt/plesk/php/*/etc/php-fpm.d/ | grep <domain> # which PHP version serves the domain
systemctl reload plesk-php85-fpm # graceful, no dropped requestsexp:velocity deploy finds the right service itself: settings/velocity.ini [DeploySettings] PhpFpmService=auto
recognizes "the pool configuration named after the installation's hosting domain (/var/www/vhosts/<domain>/..., as
Plesk names pools)"; --dry-run shows what was found and why (Velocity engines).
To fix it explicitly:
# settings/override/velocity.ini.append.php
[DeploySettings]
PhpFpmService=plesk-php85-fpmMore on pools: PHP selection and FPM pools.
nginx in front of Apache
"Plesk puts nginx in front of Apache and Apache's mod_remoteip (RemoteIPHeader X-Forwarded-For,
RemoteIPInternalProxy 127.0.0.1) sets REMOTE_ADDR to the visitor; nginx talks to Apache over HTTPS, so Apache
sets HTTPS=on. The kernel then sees the visitor as the peer and needs no forwarded header: nothing to configure, and
ClientIpByCustomHTTPHeader can stay false." (Trusted proxies)
Certificates
- Install the domain's certificate in Plesk (its Let's Encrypt extension or your own) and switch on the redirect to HTTPS (8.5.3).
- When Velocity or FrankenPHP serves the same domain on another port, they can use the certificate Plesk holds: the
FrankenPHP notes point
[HTTPSSettings] CertificateandKeyat a copy of "the Let's Encrypt cert Plesk holds for the host", exported from/usr/local/psa/var/certificates/outside the document root. - "Plesk renews the Let's Encrypt cert on its own schedule, writing a new file under a new name; the exported copy then goes stale." The export must be "repeated after each renewal", followed by a reload (FrankenPHP, Renewal). Velocity checks its certificate files every 60 seconds and swaps a changed, valid pair in live (8.3.9), but only if the path it reads gets the new file.
See TLS certificates in panels.
Logs
Exponential's own logs are under var/log and var/<site>/log. To show Plesk's web server logs in
Setup > Log files, name them in logviewer.ini (Log viewer):
# settings/override/logviewer.ini.append.php
[LogViewerSettings]
LogPath[webserver-access]=/var/www/vhosts/<domain>/logs/access_ssl_log
LogPath[webserver-error]=/var/www/vhosts/<domain>/logs/error_log"The web server's user must be able to read the file" (settings/logviewer.ini). The keys webserver-access and
webserver-error are in the shipped LogList[].
Cron
The cronjob page in the administration needs a command line PHP; "On a host with several PHP versions set
PhpCliPath to the one the site runs on, for example /opt/plesk/php/8.5/bin/php"
(Cronjobs, Before you start):
/opt/plesk/php/8.5/bin/php bin/php/console exp:ini set cronjob.ini/AdminSettings/PhpCliPath /opt/plesk/php/8.5/bin/php globalA crontab line with the domain's PHP, as the page proposes it:
17 * * * * cd /var/www/vhosts/<domain>/<docroot> && /opt/plesk/php/8.5/bin/php runcronjobs.php -s site infrequent >/dev/null 2>&1Install the lines in the crontab of the domain's system user, so the files the jobs write stay writable for the pool (Cron and shell access).
Velocity beside Plesk
The development server runs Velocity next to Plesk's Apache on the same installation. Points to settle:
- Ports. Plesk's Apache and nginx own 80 and 443; Velocity keeps its own ports (8088 and 8080 as shipped) or sits behind Plesk's nginx (8.3.5).
- Firewall. "Some Plesk installs drive firewalld or nftables through the Plesk Firewall extension. If a rule you
add with
firewall-cmddisappears on the next Plesk apply, add it in Plesk (Tools & Settings → Firewall) instead." (FrankenPHP) - One user. Velocity's workers run as the domain's system user (
[ServerSettings] User,Group), the same user as the Plesk pool (8.7.2). - Deploys.
exp:velocity deployreloadsplesk-php<XY>-fpmand restarts Velocity in one run.
Known effects of Plesk settings
| Symptom | Cause in the sources | What to do |
|---|---|---|
| Setup > System information says OPcache "statistics not available" | "Plesk can put opcache_get_status in disable_functions for a domain"; "The cache works; only its figures cannot be read from PHP" (System information) | nothing, or allow the function for the domain |
| A PHP change has no effect | the wrong master was reloaded (Chapter 12) | reload plesk-php<XY>-fpm |
A test fails in the browser but php -m looks fine | "the two PHPs differ: install the extension for the web PHP (on Plesk, the domain's PHP version)" | install it in the domain's PHP version and reload |
| ezupdate does not find a system Composer | "open_basedir (default Plesk) hides the system folders", so ezupdate searches below the installation root first (ezupdate settings) | set [ComposerSettings] Path/Binary, or let its Get Composer download a verified composer.phar into var/ezupdate/ |
| A long setup wizard step is cut off | the pool's request_terminate_timeout | raise it for the install, lower it afterwards |
Checklist
- To do: Domain's PHP version 8.0 or later (Velocity included); "FPM application served by Apache".
- To do: Document root = installation root;
.htaccesscopied from.htaccess_root(exp:setup:statussays so). - To do: With SOAP on:
index_soap.phplet through in Additional directives for HTTPS (or.htaccess), not only the oldsoap.php(the SOAP entry script is now index_soap.php). - To do: With WebDAV on:
index_webdav.phplet through in Additional directives for HTTPS and for HTTP (or.htaccess), not only the oldwebdav.php(the WebDAV entry script is now index_webdav.php). - To do: After changing the directives: tested over HTTPS with
curl(SOAP: a GET of/index_soap.php?wsdlanswers200; WebDAV: aPROPFINDof/index_webdav.php/answers207), not a404or a page of the site. - To do: Composer, console and cron use
/opt/plesk/php/<version>/bin/php. - To do:
PhpCliPathset; cron lines in the domain user's crontab. - To do: Reload
plesk-php<XY>-fpmafter PHP changes;PhpFpmServicecorrect inexp:velocity deploy --dry-run. - To do: Certificate in Plesk, redirect to HTTPS on; export renewed after each renewal if Velocity or FrankenPHP uses it.
- To do: Web server logs added to the log viewer.
A public demo on Plesk. Set EXP_DEMO_MODE=1 for the demo's subscription only: SetEnv EXP_DEMO_MODE 1 in its .htaccess (Apache or LiteSpeed) or its Additional Apache directives, or env[EXP_DEMO_MODE] = 1 through the domain's PHP-FPM settings, and a EXP_DEMO_MODE=1 line in its Scheduled Tasks. Plesk runs each PHP version with its own FPM master: reload the one of the domain's version. Step by step: Recipe: run a public demo on LiteSpeed and Plesk.
The LiteSpeed page cache on Plesk. With LiteSpeed as the web server, its page cache answers anonymous visitors and crawlers without PHP. Switch it on per site with the commented block of .htaccess_root, or paste litespeed-page-cache.conf into Additional directives for HTTPS. Never edit /var/www/vhosts/system/<domain>/conf/vhost_ssl.conf by hand: Plesk writes it again from the panel field whenever it regenerates the domain configuration. Step by step: Page caching with LiteSpeed and OpenLiteSpeed.
Related pages
- Control panels: overview
- Apache with PHP-FPM, Velocity beside Apache or nginx
- Chapter 8: Serving the site
- Setting up .htaccess and config.php from the console
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.