🌐

vestacp

45 notes  •  Web Hosting

VestaCP Important File and Directory Paths

A quick reference for the most commonly needed file and directory paths in a VestaCP installation. Use these paths when editing configuration, troubleshooting, or automating tasks.

Key File Locations

ResourcePath
MySQL root password/usr/local/vesta/conf/mysql.conf
PHP ini (Apache, PHP 5)/etc/php5/apache2/php.ini
PHP ini (PHP 7, Ubuntu)/etc/php/7.x/apache2/php.ini
Hosts file/etc/hosts
Hostname (CentOS/RHEL)/etc/sysconfig/network
Hostname (Ubuntu)/etc/hostname
Apache error logs/var/log/apache2/domains/
Nginx error logs/var/log/nginx/domains/
Exim mail log/var/log/exim4/mainlog
VestaCP log/var/log/vesta/
VestaCP CLI binaries/usr/local/vesta/bin/
VestaCP global config/usr/local/vesta/conf/vesta.conf
User web config/usr/local/vesta/data/users/USERNAME/web.conf
User home / public web root/home/USERNAME/web/DOMAIN/public_html/
Per-domain web config/home/USERNAME/conf/web/
Per-domain mail config/home/USERNAME/conf/mail/
Nginx templates/usr/local/vesta/data/templates/web/nginx/
Apache templates/usr/local/vesta/data/templates/web/apache2/
SSL certificates (panel)/usr/local/vesta/ssl/

Apply Hostname Changes

After editing the hostname file, restart networking to apply the change:

service network restart    # CentOS/RHEL
hostname -F /etc/hostname  # Ubuntu/Debian

Notes

  • PHP ini paths vary by PHP version and distro. Use php --ini to confirm the active file.
  • All VestaCP CLI commands are prefixed with v- and live in /usr/local/vesta/bin/.

Change User or Admin Password in VestaCP

Use the VestaCP CLI to change any user's password, including the admin account, directly from the command line.

Steps

Run the following command as root, replacing USERNAME and NEWPASSWORD with the target values:

v-change-user-password USERNAME NEWPASSWORD

To change the admin password specifically:

v-change-user-password admin NEWPASSWORD

Verify

Log into the VestaCP panel at https://your-server:8083 with the new credentials to confirm the change took effect.

Notes

  • The command must be run as root.
  • This updates the password both in VestaCP and for the Linux system user.
  • Avoid special characters in the password on the command line; wrap in single quotes if needed: 'P@ssw0rd!'

Fix Cron Job Errors in VestaCP

Cron jobs in VestaCP can fail if the server hostname is not resolvable. The system cannot ping the hostname, causing cron execution to fail. Fix this by adding the hostname to /etc/hosts.

Steps

1. Find the server's IP address and hostname:

v-list-sys-ips
hostname

2. Edit /etc/hosts and add an entry mapping the IP to the hostname:

nano /etc/hosts

Add a line like:

173.192.110.166   nxt.vestacp.com nxt

3. Verify the hostname resolves:

ping -c 1 $(hostname)

4. Restart the cron service:

service vesta restart

Verify

Check that cron jobs run without errors by reviewing the VestaCP log:

tail -f /var/log/vesta/system.log

Notes

  • This is the most common cause of cron failures in VestaCP: an unresolvable hostname.
  • The hostname entry in /etc/hosts must match the output of the hostname command exactly.

Uninstall VestaCP from Server

To completely remove VestaCP from your server, stop the service, remove packages, delete the repository configuration, and clean up the data directory.

Steps

1. Stop the VestaCP service:

service vesta stop

2. Remove VestaCP packages and the software repository.

On RHEL/CentOS:

yum remove vesta*
rm -f /etc/yum.repos.d/vesta.repo

On Debian/Ubuntu:

apt-get remove vesta*
rm -f /etc/apt/sources.list.d/vesta.list

3. Delete the VestaCP data directory and cron entries:

rm -rf /usr/local/vesta

Verify

Confirm VestaCP is removed by checking that the binary directory no longer exists:

ls /usr/local/vesta

The command should return "No such file or directory".

Notes

  • This removes VestaCP itself but does not remove software it installed (Nginx, Apache, MySQL, Exim, Dovecot, etc.). Remove those separately if required.
  • User data under /home/ is preserved. Back up or delete manually as needed.
  • VestaCP cron entries in /etc/cron.d/ may need manual cleanup.

Install SSL Certificate on VestaCP Login Panel (Port 8083)

By default, VestaCP uses a self-signed certificate for its admin panel on port 8083. Replace it with your domain's existing SSL certificate by symlinking the certificate files.

Steps

1. Back up the existing self-signed certificate:

mv /usr/local/vesta/ssl/certificate.crt /usr/local/vesta/ssl/certificate.crt.backup
mv /usr/local/vesta/ssl/certificate.key /usr/local/vesta/ssl/certificate.key.backup

2. Create symlinks pointing to your domain's SSL certificate files (adjust the username and domain name):

ln -s /home/admin/conf/web/ssl.yourdomain.com.crt /usr/local/vesta/ssl/certificate.crt
ln -s /home/admin/conf/web/ssl.yourdomain.com.key /usr/local/vesta/ssl/certificate.key

3. Restart the VestaCP service to load the new certificate:

service vesta restart

Verify

Open a browser and navigate to https://your-server:8083. The browser should show a valid, trusted SSL certificate for your domain instead of the self-signed warning.

Notes

  • The certificate files must be readable by the VestaCP process (typically root-owned is fine).
  • If using Let's Encrypt, the certificate files are usually under /etc/letsencrypt/live/yourdomain.com/. Adjust the symlink target accordingly.
  • After Let's Encrypt renewal, the symlinks will automatically pick up the new certificate.

Change Server Hostname in VestaCP

Use the VestaCP CLI command to update the server hostname. This updates both the system hostname and VestaCP's internal records.

Steps

Run the following command as root, replacing newhost.example.com with the desired FQDN:

v-change-sys-hostname newhost.example.com

Update /etc/hosts to include the new hostname:

nano /etc/hosts

Add or update the line:

YOUR_SERVER_IP   newhost.example.com newhost

Verify

hostname
hostname -f

Both commands should return the new hostname.

Notes

  • The hostname should be a fully qualified domain name (FQDN), e.g. server1.example.com.
  • Mail servers use the hostname in SMTP banners — updating it helps with deliverability.
  • Some services (ProFTPd, Exim) may need a restart after a hostname change.

Update IP Address in VestaCP

When a server's IP address changes (e.g. after a cloud instance reboot or migration), VestaCP's configuration files must be updated to reflect the new IP. This guide covers creating a helper script and manually updating the key files.

Steps: Create the IP Change Script

1. Create and make the script executable:

touch /usr/local/vesta/bin/v-change-server-ip
chmod 0755 /usr/local/vesta/bin/v-change-server-ip

2. Add the following content to the script:

#!/bin/sh
# Script to update VestaCP configuration with a new server IP.
# Usage: v-change-server-ip OLD_IP NEW_IP

OLD_IP=$1
NEW_IP=$2
LOG=/var/log/vesta/system.log

if [ "$(id -u)" != "0" ]; then
    echo "Root access required." | tee -a $LOG
    exit 1
fi

if [ -z "$OLD_IP" ] || [ -z "$NEW_IP" ]; then
    echo "Usage: $0 OLD_IP NEW_IP" | tee -a $LOG
    exit 1
fi

echo "Replacing $OLD_IP with $NEW_IP" | tee -a $LOG

# Update VestaCP IP data files
mv /usr/local/vesta/data/ips/$OLD_IP /usr/local/vesta/data/ips/$NEW_IP 2>/dev/null
sed -i "s/$OLD_IP/$NEW_IP/g" /usr/local/vesta/data/users/admin/web.conf

# Update Apache and Nginx config files
sed -i "s/$OLD_IP/$NEW_IP/g" /etc/apache2/conf.d/$OLD_IP.conf 2>/dev/null
sed -i "s/$OLD_IP/$NEW_IP/g" /etc/nginx/conf.d/$OLD_IP.conf 2>/dev/null
mv /etc/apache2/conf.d/$OLD_IP.conf /etc/apache2/conf.d/$NEW_IP.conf 2>/dev/null
mv /etc/nginx/conf.d/$OLD_IP.conf /etc/nginx/conf.d/$NEW_IP.conf 2>/dev/null

# Update per-domain web configs
sed -i "s/$OLD_IP/$NEW_IP/g" /home/admin/conf/web/*.conf

service vesta restart
service nginx restart
service apache2 restart
echo "Done." | tee -a $LOG

3. Run the script:

v-change-server-ip OLD_IP NEW_IP

Verify

grep -r "OLD_IP" /usr/local/vesta/data/
grep -r "OLD_IP" /home/admin/conf/web/

No results should be returned.

Notes

  • Replace admin in the paths above with the relevant VestaCP username if accounts other than admin host domains.
  • Always back up configs before running bulk sed replacements.

Enable Gzip Compression in VestaCP (Nginx)

Enabling gzip compression in Nginx reduces the size of text-based responses (HTML, CSS, JS) sent to browsers, improving page load speed. In VestaCP, add gzip directives to the Nginx configuration template or the server-level config.

Steps

1. Edit the main Nginx configuration file:

nano /etc/nginx/nginx.conf

2. Add or confirm the following gzip settings inside the http {} block:

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
    text/plain
    text/css
    text/xml
    application/json
    application/javascript
    application/xml+rss
    application/atom+xml
    image/svg+xml;

3. Test the configuration and reload Nginx:

nginx -t
service nginx reload

Verify

Use curl to confirm gzip is active:

curl -H "Accept-Encoding: gzip" -I https://yourdomain.com

Look for Content-Encoding: gzip in the response headers.

Notes

  • To persist settings across VestaCP template rebuilds, add the directives to the relevant Nginx template in /usr/local/vesta/data/templates/web/nginx/.
  • Avoid compressing already-compressed formats (JPEG, PNG, ZIP, PDF) — this wastes CPU without benefit.

Set PHP ini Values Per-Domain in VestaCP

In VestaCP, PHP settings can be customized per domain by editing the web template used by that domain. This avoids changing the global php.ini and allows different domains to have different PHP configurations.

Steps

1. Find which template (package) the domain uses. Check in the VestaCP panel under Web, or inspect:

cat /usr/local/vesta/data/users/USERNAME/web.conf | grep DOMAIN

2. Navigate to the Apache (httpd) templates directory:

ls /usr/local/vesta/data/templates/web/apache2/

3. Edit the .tpl or .stpl file for your template (e.g. hosting.tpl):

nano /usr/local/vesta/data/templates/web/apache2/hosting.tpl

4. Add php_admin_value or php_value directives inside the <Directory> block, for example:

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value memory_limit 256M

5. Rebuild the web configuration to apply the template:

v-rebuild-web-domains USERNAME

Verify

Create a phpinfo.php file in the domain's public_html and open it in a browser. Confirm the values are reflected. Remove the file after checking.

Notes

  • For PHP-FPM setups, settings must instead be placed in the pool config under /etc/php/7.x/fpm/pool.d/.
  • Use php_admin_value to prevent the application from overriding the setting.

Fix ProFTPd Start Failure in VestaCP

ProFTPd fails to start when it cannot resolve the server's hostname. Adding the hostname to /etc/hosts resolves this.

Steps

1. Find the server's IP and hostname:

hostname
ip addr show

2. Edit /etc/hosts and add a mapping:

nano /etc/hosts

Add:

192.168.0.10   myhostname.example.com myhostname

3. Restart the network and start ProFTPd:

service network restart
service proftpd start

Verify

service proftpd status

The service should show as active/running. Test an FTP connection to confirm.

Notes

  • ProFTPd performs a reverse DNS lookup on startup — if it cannot resolve the server's own hostname, it fails to bind.
  • On Ubuntu/Debian, use systemctl restart proftpd.
  • Check ProFTPd logs at /var/log/proftpd/proftpd.log for further diagnostics.

Install Let's Encrypt SSL in VestaCP

Let's Encrypt provides free, automatically renewable SSL certificates. VestaCP has built-in support for Let's Encrypt, making installation straightforward.

Steps: Using the VestaCP Built-in Method

1. Log into the VestaCP panel at https://your-server:8083.

2. Navigate to Web, click on the domain you want to secure.

3. Check the SSL Support checkbox, then check Let's Encrypt SSL.

4. Click Save.

Steps: Using the CLI

To add a Let's Encrypt certificate via command line:

v-add-letsencrypt-domain USERNAME DOMAIN [ALIASES] [MAIL]

Example:

v-add-letsencrypt-domain admin example.com www.example.com

Steps: Manual Installation (Certbot)

1. Install Certbot:

# Ubuntu/Debian
apt-get install certbot

# CentOS/RHEL
yum install certbot

2. Obtain a certificate (webroot method):

certbot certonly --webroot -w /home/USERNAME/web/DOMAIN/public_html   -d DOMAIN -d www.DOMAIN

3. Copy the certificates to the VestaCP web config directory:

cp /etc/letsencrypt/live/DOMAIN/fullchain.pem /home/USERNAME/conf/web/ssl.DOMAIN.crt
cp /etc/letsencrypt/live/DOMAIN/privkey.pem /home/USERNAME/conf/web/ssl.DOMAIN.key

4. Restart web services:

service nginx restart
service apache2 restart

Verify

Visit https://DOMAIN in a browser. A padlock icon should appear. You can also check with:

curl -vI https://DOMAIN 2>&1 | grep -E "SSL|certificate|expire"

Notes

  • Let's Encrypt certificates expire every 90 days. VestaCP's built-in integration handles auto-renewal via cron.
  • If using the manual method, set up a cron job to run certbot renew twice daily.
  • Both the domain and any www alias must point to the server's IP before requesting the certificate.

Fix phpMyAdmin Configuration Storage in VestaCP

After a fresh VestaCP install, phpMyAdmin often shows the warning "The phpMyAdmin configuration storage is not completely configured, some extended features have been deactivated." This guide sets up the required configuration storage database.

Steps

1. Log into MySQL as root. Retrieve the root password first:

cat /usr/local/vesta/conf/mysql.conf

2. Create the phpMyAdmin configuration database:

mysql -u root -p <<EOF
CREATE DATABASE IF NOT EXISTS phpmyadmin;
GRANT ALL PRIVILEGES ON phpmyadmin.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapassword';
FLUSH PRIVILEGES;
EOF

3. Import the phpMyAdmin SQL schema:

mysql -u root -p phpmyadmin < /usr/share/doc/phpmyadmin/examples/create_tables.sql.gz

Or if uncompressed:

mysql -u root -p phpmyadmin < /usr/share/phpmyadmin/sql/create_tables.sql

4. Edit the phpMyAdmin configuration to add the pma credentials:

nano /etc/phpmyadmin/config.inc.php

Add or update:

$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'pmapassword';
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';

Verify

Log into phpMyAdmin. The configuration storage warning should no longer appear. The "Tracking" and "Bookmarks" features should be active.

Notes

  • Use a strong password for the pma user in production — the example above is illustrative.
  • The schema file path differs between distros and phpMyAdmin versions; locate it with find / -name "create_tables.sql" 2>/dev/null.

Upgrade PHP and MySQL Versions in VestaCP (CentOS)

VestaCP ships with the distro default versions of PHP and MySQL. This guide covers upgrading both to newer versions on CentOS using RPM repositories.

Steps: Upgrade PHP

1. Add the Remi repository:

rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install yum-utils
yum-config-manager --enable remi-php72

2. Upgrade PHP:

yum update php php-cli php-fpm php-mysql php-gd php-mbstring php-xml

3. Restart web services:

service nginx restart
service httpd restart
service php-fpm restart

Steps: Upgrade MySQL

1. Back up all databases before upgrading:

mysqldump -u root -p --all-databases > /root/all_databases_backup.sql

2. Add the MySQL community repository and upgrade:

rpm -Uvh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
yum update mysql-server

3. Start MySQL and run the upgrade:

service mysqld start
mysql_upgrade -u root -p

Verify

php -v
mysql --version

Notes

  • Always back up databases and site files before upgrading MySQL.
  • Test PHP applications for compatibility before upgrading — deprecated functions differ between PHP versions.
  • If VestaCP templates reference old PHP settings, rebuild domain configs after: v-rebuild-web-domains admin

Fix FTP Passive Mode on Amazon EC2 with VestaCP

On Amazon EC2, FTP passive mode fails by default because the server returns an internal (private) IP address in the PASV response. Clients receive a private address they cannot reach, causing the connection to hang. The fix is to configure VSFTPD to advertise the public IP and open the passive port range in the EC2 security group.

Steps

1. Edit the VSFTPD configuration:

nano /etc/vsftpd/vsftpd.conf

2. Add or update the following lines (replace YOUR_PUBLIC_IP with the instance's Elastic IP):

pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
pasv_address=YOUR_PUBLIC_IP

3. Restart VSFTPD:

service vsftpd restart

4. Open the passive port range in the EC2 Security Group. In the AWS console, add an inbound rule:

  • Type: Custom TCP
  • Port range: 40000–40100
  • Source: 0.0.0.0/0 (or restrict to known IPs)

5. If using VestaCP's built-in firewall, add the rule:

v-add-firewall-rule ACCEPT TCP 40000-40100

Verify

Connect using an FTP client (e.g. FileZilla) in passive mode. The connection should complete successfully and directory listings should load.

Notes

  • If the server does not have a static/Elastic IP, the pasv_address workaround breaks when the IP changes. Use an Elastic IP for FTP servers.
  • Consider using SFTP (SSH) instead of FTP for better security — it requires no additional firewall rules beyond port 22.

Fix "No Virtual Hosts Found" Apache Warning on CentOS

Apache logs the warning NameVirtualHost X.X.X.X:8443 has no VirtualHosts on CentOS/VestaCP servers when a VirtualHost listener is configured but no domains are assigned SSL on that IP and port. This is harmless in most cases, but can be silenced by removing unused listeners.

Cause

VestaCP creates Apache configuration for HTTPS (port 8443) even when no SSL-enabled virtual hosts are assigned to that port. Apache emits a warning because the listener has nothing to serve.

Steps

1. Identify the configuration file generating the warning:

grep -r "NameVirtualHost" /etc/httpd/conf.d/
grep -r "8443" /etc/httpd/conf.d/

2. If no SSL sites are hosted on port 8443, remove or comment out the offending directive in the config file shown above:

nano /etc/httpd/conf.d/YOUR_IP.conf

Comment out the line:

# NameVirtualHost YOUR_IP:8443

3. Test the Apache configuration and restart:

httpd -t
service httpd restart

Verify

Restart Apache and check that the warning is gone:

service httpd restart 2>&1 | grep -i warn

Notes

  • This warning does not affect website operation — it is purely informational.
  • If you later add SSL domains through VestaCP, it will rebuild the config and re-add the listener automatically.

Fix VestaCP Parsing Error After IP Change

After changing a server's IP address, the VestaCP web domain edit panel may show a "Parsing Error." This occurs because the web configuration files still reference the old IP. Updating those files resolves the error.

Steps

1. Identify the user whose domain shows the error (replace USERNAME accordingly):

cat /usr/local/vesta/data/users/USERNAME/web.conf

2. Replace all occurrences of the old IP with the new IP in the user's web config:

sed -i 's/OLD_IP/NEW_IP/g' /usr/local/vesta/data/users/USERNAME/web.conf

3. Update per-domain Apache and Nginx SSL configs:

sed -i 's/OLD_IP/NEW_IP/g' /home/USERNAME/conf/web/*.conf

4. Rebuild web domains to regenerate all configuration:

v-rebuild-web-domains USERNAME

5. Restart web services:

service nginx restart
service apache2 restart  # or: service httpd restart

Verify

Log into the VestaCP panel and open the domain's edit page. The parsing error should be gone and settings should display correctly.

Notes

  • Repeat the sed steps for every user that hosts domains on the server.
  • Always verify no old IP references remain: grep -r "OLD_IP" /usr/local/vesta/data/users/

Change the Main IP Address in VestaCP

When a server's primary IP address changes, multiple VestaCP configuration files must be updated. This guide covers all the files that need to be modified.

Steps

1. Update the VestaCP IP data directory:

mv /usr/local/vesta/data/ips/OLD_IP /usr/local/vesta/data/ips/NEW_IP

2. Update the IP inside the new file:

sed -i 's/OLD_IP/NEW_IP/g' /usr/local/vesta/data/ips/NEW_IP

3. Update the admin user web config:

sed -i 's/OLD_IP/NEW_IP/g' /usr/local/vesta/data/users/admin/web.conf

4. Update per-domain web configuration files:

sed -i 's/OLD_IP/NEW_IP/g' /home/admin/conf/web/*.conf

5. Update Apache and Nginx IP-based config files:

sed -i 's/OLD_IP/NEW_IP/g' /etc/apache2/conf.d/OLD_IP.conf
sed -i 's/OLD_IP/NEW_IP/g' /etc/nginx/conf.d/OLD_IP.conf
mv /etc/apache2/conf.d/OLD_IP.conf /etc/apache2/conf.d/NEW_IP.conf
mv /etc/nginx/conf.d/OLD_IP.conf /etc/nginx/conf.d/NEW_IP.conf

6. Rebuild web domains and restart services:

v-rebuild-web-domains admin
service nginx restart
service apache2 restart
service vesta restart

Verify

grep -r "OLD_IP" /usr/local/vesta/data/
grep -r "OLD_IP" /home/admin/conf/web/

No results should be returned.

Notes

  • If multiple users host domains, repeat the user-specific steps for each account.
  • Update DNS records for all hosted domains to point to the new IP.

Remove open_basedir Restriction in VestaCP

VestaCP sets open_basedir in Apache's per-domain configuration, which restricts PHP to reading files only within the domain's directory. If an application requires access to files outside this path, disable the restriction for that domain.

Steps

1. Open the domain's Apache configuration file:

nano /home/USERNAME/conf/web/apache2.conf

2. Locate the php_admin_value open_basedir line for the relevant domain and comment it out:

# php_admin_value open_basedir "/home/USERNAME/web/DOMAIN/public_html:/tmp"

Alternatively, expand the path to include additional directories:

php_admin_value open_basedir "/home/USERNAME/web/DOMAIN/public_html:/tmp:/path/to/other/dir"

3. Restart Apache to apply:

service apache2 restart  # or: service httpd restart

Verify

Test the application that was previously blocked. For a quick check, create a PHP file that accesses the formerly restricted path and confirm it works.

Notes

  • Removing open_basedir reduces PHP security isolation. Only do this for trusted applications.
  • VestaCP rebuilds Apache configs when you modify domain settings in the panel — any manual edits to apache2.conf may be overwritten. To make permanent changes, edit the domain's Apache template instead: /usr/local/vesta/data/templates/web/apache2/

Let's Encrypt SSL on VestaCP (Certbot Method)

This guide installs Let's Encrypt SSL certificates using the Certbot and letsencrypt-vesta integration, which automates certificate issuance and renewal for VestaCP-managed domains.

Steps

1. Clone Certbot and the letsencrypt-vesta integration:

cd /usr/local
git clone https://github.com/certbot/certbot.git
git clone https://github.com/interbrite/letsencrypt-vesta.git

2. Create the webroot directory and set up symlinks:

mkdir -p /etc/letsencrypt/webroot
ln -s /usr/local/certbot/certbot-auto /usr/local/bin/certbot-auto
ln -s /usr/local/letsencrypt-vesta/letsencrypt-vesta /usr/local/bin/letsencrypt-vesta
ln -s /usr/local/letsencrypt-vesta/letsencrypt.conf /etc/apache2/conf.d/letsencrypt.conf

3. Reload Apache to pick up the new config:

service apache2 reload

4. Issue a certificate for a domain:

letsencrypt-vesta USERNAME DOMAIN

Example:

letsencrypt-vesta admin example.com

Automated Renewal

Add a cron job to renew certificates automatically:

echo "0 3 * * * root /usr/local/bin/certbot-auto renew --quiet" > /etc/cron.d/letsencrypt

Verify

Visit https://DOMAIN and confirm the browser shows a valid Let's Encrypt certificate.

Notes

  • The domain must have a DNS A record pointing to the server before running the command.
  • Certificates are valid for 90 days; the cron renewal handles rotation automatically.

Install Let's Encrypt SSL on VestaCP Panel (Port 8083)

The VestaCP admin panel on port 8083 uses a self-signed certificate by default. Replace it with a trusted Let's Encrypt certificate to eliminate browser security warnings.

Steps

1. Obtain a Let's Encrypt certificate for the server's hostname or a dedicated panel subdomain (e.g. panel.example.com). The domain must resolve to this server:

certbot certonly --standalone -d panel.example.com --pre-hook "service nginx stop" --post-hook "service nginx start"

2. Back up the existing VestaCP SSL files:

cp /usr/local/vesta/ssl/certificate.crt /usr/local/vesta/ssl/certificate.crt.bak
cp /usr/local/vesta/ssl/certificate.key /usr/local/vesta/ssl/certificate.key.bak

3. Replace the VestaCP certificate files with symlinks to the Let's Encrypt certificate:

rm /usr/local/vesta/ssl/certificate.crt
rm /usr/local/vesta/ssl/certificate.key
ln -s /etc/letsencrypt/live/panel.example.com/fullchain.pem /usr/local/vesta/ssl/certificate.crt
ln -s /etc/letsencrypt/live/panel.example.com/privkey.pem /usr/local/vesta/ssl/certificate.key

4. Restart VestaCP:

service vesta restart

Automated Renewal Hook

Create a renewal hook to restart VestaCP after certificate renewal:

echo '#!/bin/bash
service vesta restart' > /etc/letsencrypt/renewal-hooks/deploy/vesta.sh
chmod +x /etc/letsencrypt/renewal-hooks/deploy/vesta.sh

Verify

Open https://panel.example.com:8083 in a browser. The connection should be secured with a trusted Let's Encrypt certificate — no warnings should appear.

Notes

  • Using --standalone mode requires temporarily stopping the web server. An alternative is the --webroot method if a domain is already hosted on this server.
  • Symlinks ensure that certbot auto-renewal automatically updates the panel certificate without manual intervention.

Upgrade VestaCP to PHP 7 on CentOS

This guide covers installing PHP 7 on a VestaCP server running CentOS, alongside the existing PHP version, and configuring VestaCP to use it.

Steps

1. Install the required repositories:

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install yum-utils

2. Enable the PHP 7 Remi repository and install PHP 7:

yum-config-manager --enable remi-php70
yum install php php-cli php-fpm php-mysql php-gd php-mbstring php-xml php-mcrypt php-soap

3. Verify the PHP version:

php -v

4. Update the PHP-FPM configuration if needed and restart services:

service php-fpm restart
service nginx restart
service httpd restart

5. Rebuild VestaCP web domains to apply PHP changes:

v-rebuild-web-domains admin

Verify

Create a test file at a domain's public root:

echo " /home/admin/web/DOMAIN/public_html/info.php

Visit http://DOMAIN/info.php and confirm PHP 7 is shown. Remove the file afterwards.

Notes

  • PHP 7.0 reached end-of-life. Consider installing PHP 7.4 or PHP 8.x using the matching Remi repository.
  • WordPress and most modern PHP frameworks are compatible with PHP 7+, but custom applications may need code updates.
  • Back up all application code and databases before upgrading.

Change SSH Port in VestaCP

Changing the default SSH port (22) reduces exposure to automated scanners. In VestaCP, you must also update the firewall rules to allow the new port and block the old one.

Steps

1. Edit the SSH daemon configuration:

nano /etc/ssh/sshd_config

Find and change the port line:

Port 2222

2. Before restarting SSH, add a firewall rule in VestaCP to allow the new port:

v-add-firewall-rule ACCEPT TCP 2222

3. Restart the SSH service:

service sshd restart

4. Open a new terminal session and verify you can connect on the new port before closing the existing session:

ssh -p 2222 user@your-server

5. Once confirmed, remove the old port 22 rule from VestaCP's firewall (optional — only if you want to block port 22 entirely):

v-delete-firewall-rule RULE_ID

Verify

List active firewall rules to confirm the new port is allowed:

v-list-firewall

Notes

  • Do not close your existing SSH session until you have confirmed connectivity on the new port — failure to verify first can lock you out.
  • Update any SSH config files or deployment scripts that reference port 22.
  • If the server is behind an external firewall or security group (e.g. AWS), allow the new port there as well.

Add Firewall Rules via VestaCP CLI

VestaCP includes a built-in firewall manager accessible via both the panel and CLI. Use the v-add-firewall-rule command to open ports or restrict access without touching iptables directly.

Command Syntax

v-add-firewall-rule ACTION PROTOCOL PORT [IP] [COMMENT]

Steps: Common Examples

Allow HTTP and HTTPS traffic:

v-add-firewall-rule ACCEPT TCP 80
v-add-firewall-rule ACCEPT TCP 443

Allow SSH on a custom port:

v-add-firewall-rule ACCEPT TCP 2222

Allow a specific IP to access MySQL:

v-add-firewall-rule ACCEPT TCP 3306 1.2.3.4

Block an IP address:

v-add-firewall-rule DROP ALL 0 1.2.3.4 "Blocked attacker"

Open a port range (e.g. FTP passive):

v-add-firewall-rule ACCEPT TCP 40000-40100

List and Delete Rules

# List all rules with their IDs
v-list-firewall

# Delete a rule by its ID
v-delete-firewall-rule RULE_ID

Verify

After adding a rule, check iptables to confirm it was applied:

iptables -L INPUT -n --line-numbers

Notes

  • VestaCP firewall rules are applied on top of iptables. Manual iptables edits may conflict — prefer using the VestaCP CLI for consistency.
  • Rules are persistent across reboots when managed through VestaCP.

Check and Manage Disk Space in VestaCP

Disk space can fill up quickly on web hosting servers due to log files, email, backups, and cached data. This guide covers how to identify and reclaim disk space on a VestaCP server.

Check Overall Disk Usage

df -h

Find Large Files and Directories

Find the top disk consumers under /var (common culprit for log growth):

du -sh /var/* | sort -rh | head -20

Find files larger than 100MB across the filesystem:

find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null

Common Space Hogs and Fixes

Clear old Apache and Nginx domain logs:

find /var/log/apache2/domains/ -name "*.log" -mtime +30 -delete
find /var/log/nginx/domains/ -name "*.log" -mtime +30 -delete

Clear Exim mail queue:

exim -bp | wc -l          # count queued messages
exim -bp | exiqgrep -i | xargs exim -Mrm  # remove all queued

Remove old VestaCP backups:

ls -lh /backup/
rm /backup/OLDUSER.YYYY-MM-DD_HH-MM-SS.tar

Clear apt/yum cache:

apt-get clean          # Ubuntu/Debian
yum clean all          # CentOS/RHEL

Verify

df -h

Notes

  • Set up log rotation (logrotate) to prevent log files from growing unbounded.
  • VestaCP's backup directory defaults to /backup/ — configure retention limits in the panel under Settings > Backup.

Find DKIM Key for a Domain in VestaCP

DKIM (DomainKeys Identified Mail) is used to cryptographically sign outgoing email. VestaCP generates DKIM keys automatically when a mail domain is created. Use the following command to retrieve the DNS records needed to publish the public key.

Steps

Run the VestaCP CLI command to list the DKIM DNS records for a domain:

v-list-mail-domain-dkim-dns USERNAME DOMAIN

Example:

v-list-mail-domain-dkim-dns admin example.com

Sample output:

RECORD            TTL         TYPE      VALUE
------            ---         ----      -----
_domainkey        3600   IN   TXT      "t=y; o=~;"
mail._domainkey   3600   IN   TXT      "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUA..."

Add DKIM to DNS

Add the two TXT records shown in the output to your domain's DNS zone:

  • _domainkey.example.com — policy record
  • mail._domainkey.example.com — public key record

Verify

After DNS propagation (up to 24 hours), verify the DKIM record is published:

dig TXT mail._domainkey.example.com

Or use an online DKIM checker tool.

Notes

  • The private DKIM key is stored at /home/USERNAME/conf/mail/DOMAIN/dkim.key.
  • VestaCP also sets up SPF automatically. Verify both SPF and DKIM for best email deliverability.

Find MySQL Root Password in VestaCP

VestaCP stores the MySQL root password in a plain-text configuration file during installation. Retrieve it from there rather than performing a password reset.

Steps

Read the MySQL configuration file:

cat /usr/local/vesta/conf/mysql.conf

Look for the PASSWORD field in the output. Use that value to connect:

mysql -u root -p'PASSWORD_FROM_FILE'

Change the MySQL Root Password

To set a new root password (MySQL 5.7+):

mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword';
FLUSH PRIVILEGES;
EXIT;

After changing the password, update the VestaCP config file to match:

nano /usr/local/vesta/conf/mysql.conf

Verify

mysql -u root -p'NewStrongPassword' -e "SELECT 1;"

Notes

  • The file at /usr/local/vesta/conf/mysql.conf is readable only by root — keep it protected.
  • VestaCP uses this stored password to manage MySQL databases through the panel. If you change the password without updating this file, the panel's database management will break.

Migrate Email from VestaCP to cPanel

Migrating email accounts from VestaCP to cPanel involves recreating the accounts on the destination server and transferring the mailbox data using scp or rsync.

Steps

1. On the cPanel server, create all email accounts that exist on the VestaCP server. This can be done through WHM or the cPanel interface.

2. Transfer the mailbox directories from VestaCP to cPanel using rsync:

rsync -avz --progress   /home/USERNAME/mail/DOMAIN/   root@CPANEL_SERVER:/home/CPANEL_USER/mail/DOMAIN/

Or use scp:

scp -r /home/USERNAME/mail/DOMAIN/ root@CPANEL_SERVER:/home/CPANEL_USER/mail/DOMAIN/

3. On the cPanel server, fix mailbox permissions via WHM:

  • Go to WHM > Email > Repair Mailbox Permissions
  • Select the affected domain and run the repair

Or fix from the command line:

/scripts/mailperm CPANEL_USER

Verify

Log into RoundCube or another mail client on the cPanel server and confirm that old emails are present in the migrated accounts.

Notes

  • VestaCP stores mail in Maildir format under /home/USERNAME/mail/DOMAIN/ACCOUNT/. cPanel also uses Maildir, so the format is compatible.
  • Update MX records to point to the cPanel server only after confirming the migration is complete.
  • Allow time for DNS propagation before switching MX records.

Enable TLS/SSL for VSFTPD in VestaCP

By default, VSFTPD in VestaCP does not require TLS, transmitting credentials in plaintext. Enable TLS to encrypt FTP connections.

Steps

1. Copy the VestaCP SSL certificate files to /etc/ssl/certs/:

cp /usr/local/vesta/ssl/certificate.crt /etc/ssl/certs/vsftpd.crt
cp /usr/local/vesta/ssl/certificate.key /etc/ssl/certs/vsftpd.key
chmod 600 /etc/ssl/certs/vsftpd.key

2. Edit the VSFTPD configuration file:

nano /etc/vsftpd/vsftpd.conf

3. Add or update the following SSL/TLS settings:

ssl_enable=YES
rsa_cert_file=/etc/ssl/certs/vsftpd.crt
rsa_private_key_file=/etc/ssl/certs/vsftpd.key
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

Set force_local_data_ssl=YES and force_local_logins_ssl=YES to require TLS for all connections.

4. Restart VSFTPD:

service vsftpd restart

Verify

Connect with an FTP client that supports FTPS (e.g. FileZilla) using "Require explicit FTP over TLS" or "FTPS". The connection should succeed with TLS enabled.

Notes

  • Use your domain's Let's Encrypt certificate instead of the self-signed VestaCP cert for better compatibility.
  • Some FTP clients do not support FTPS — consider migrating users to SFTP (SSH-based) for broader compatibility and stronger security.

Fix "Connection to Storage Server Failed" in RoundCube/Dovecot

When logging into RoundCube, the error "Connection to storage server failed" indicates that RoundCube cannot connect to the Dovecot IMAP server. This is commonly caused by a conflicting Dovecot configuration file.

Steps

1. Remove the problematic Dovecot mailbox configuration file:

rm /etc/dovecot/conf.d/15-mailboxes.conf

2. Restart Dovecot — do this from the VestaCP panel or via CLI:

service dovecot restart

Verify

Log into RoundCube again. The login should succeed and the inbox should load without errors.

Notes

  • The file 15-mailboxes.conf can conflict with VestaCP's Dovecot configuration, particularly after package upgrades that restore defaults.
  • If the error persists after removing the file, check Dovecot logs for further details: tail -f /var/log/dovecot.log
  • Also verify Dovecot is listening on the correct ports: netstat -tlnp | grep dovecot

Optimize Nginx and PHP-FPM in VestaCP

Tuning Nginx and PHP-FPM for your server's workload improves response times, throughput, and stability under load. The key parameters are worker processes, connection limits, and PHP-FPM pool settings.

Nginx Optimization

Edit the main Nginx config:

nano /etc/nginx/nginx.conf

Key settings to tune:

worker_processes auto;           # match CPU cores
worker_rlimit_nofile 65535;

events {
    worker_connections 1024;     # increase for high traffic (up to worker_rlimit_nofile)
    use epoll;
    multi_accept on;
}

http {
    keepalive_timeout 15;
    keepalive_requests 100;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    client_max_body_size 64m;
    server_tokens off;
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
}

PHP-FPM Pool Optimization

Edit the default pool config (adjust path for your PHP version):

nano /etc/php/7.4/fpm/pool.d/www.conf

Key settings:

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500

Rule of thumb: pm.max_children = available_RAM_MB / average_PHP_process_size_MB

Restart services:

nginx -t && service nginx reload
service php7.4-fpm restart

Verify

Monitor PHP-FPM status and error logs:

tail -f /var/log/php7.4-fpm.log

Check Nginx performance with:

ab -n 1000 -c 100 http://DOMAIN/

Notes

  • Start with conservative values and increase gradually while monitoring memory usage with free -m and top.
  • Enable the PHP-FPM status page to monitor pool utilization in real time.

Fix 502 Bad Gateway in VestaCP (Nginx + PHP-FPM)

A 502 Bad Gateway error in VestaCP's Nginx + PHP-FPM stack typically means Nginx cannot communicate with the PHP-FPM backend. A corrupted or missing PHP-FPM configuration is a common cause.

Steps

1. Download and restore the default PHP-FPM configuration for VestaCP:

wget http://c.vestacp.com/tmp/php-fpm.conf -O /usr/local/vesta/php/etc/php-fpm.conf

2. Restart VestaCP to reload PHP-FPM:

service vesta restart

3. Check that PHP-FPM is running and listening on the correct socket or port:

ps aux | grep php-fpm
netstat -tlnp | grep php

Additional Diagnostics

Check Nginx error log for specific socket/connection errors:

tail -50 /var/log/nginx/error.log

Check PHP-FPM log:

tail -50 /var/log/php-fpm.log

Ensure Nginx is configured to pass requests to the correct PHP-FPM socket:

grep -r "fastcgi_pass" /home/*/conf/web/*.nginx.conf | head -5

Verify

Reload the affected website. The 502 error should be gone and the page should load normally.

Notes

  • 502 errors can also occur if PHP-FPM has exhausted its max_children limit. Monitor with top and increase pm.max_children if needed.
  • After a VestaCP update, PHP-FPM configurations may be overwritten — run v-rebuild-web-domains admin to regenerate them.

Find MySQL Root Password Stored by VestaCP

VestaCP generates a random MySQL root password during installation and stores it in a configuration file. This guide shows how to retrieve it and safely change it if needed.

Find the Password

cat /usr/local/vesta/conf/mysql.conf

The file contains a line similar to:

HOST='localhost' USER='root' PASSWORD='abc123xyz' MAX_DB='500'

Use the value from PASSWORD to log in:

mysql -u root -p'abc123xyz'

Change the MySQL Root Password

1. Log into MySQL:

mysql -u root -p

2. Update the password (MySQL 5.7+):

ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewSecurePassword';
FLUSH PRIVILEGES;
EXIT;

3. Update the VestaCP config file to reflect the new password:

nano /usr/local/vesta/conf/mysql.conf

Change the PASSWORD value to NewSecurePassword.

Verify

mysql -u root -p'NewSecurePassword' -e "SHOW DATABASES;"

Confirm that the VestaCP panel can still manage databases by creating a test database through the panel interface.

Notes

  • The file permissions on /usr/local/vesta/conf/mysql.conf should be 600 and owned by root.
  • If the password in VestaCP's config does not match MySQL's actual password, the panel will fail to create or delete databases.

Fix SMTP Error 550: Failed to Set Sender in RoundCube

The SMTP error "550: Failed to set sender" in RoundCube typically occurs when Exim rejects the HELO/EHLO hostname. Setting a valid smtp_helo_host in RoundCube's configuration resolves this.

Steps

1. Open the RoundCube configuration file:

nano /etc/roundcubemail/config.inc.php

2. Add the following line to set the SMTP HELO hostname:

$config['smtp_helo_host'] = 'localhost';

3. Save the file and reload the mail services:

service exim4 restart    # Ubuntu/Debian
service exim restart     # CentOS/RHEL
service dovecot restart
service spamassassin restart 2>/dev/null
service clamav-daemon restart 2>/dev/null

Verify

Log into RoundCube and send a test email. The 550 error should no longer appear.

Notes

  • If the error persists, check Exim's main log for details: tail -f /var/log/exim4/mainlog
  • The smtp_helo_host value should match what Exim expects — usually the server's FQDN or localhost.
  • Also verify that the sender's email domain has valid SPF and DKIM records, as misconfigured records can trigger 550 rejections.

Fix RoundCube Database Connection Failed Error

The error "DATABASE ERROR: CONNECTION FAILED!" in RoundCube means the application cannot connect to its MySQL database, usually because the database password in one configuration file does not match the actual MySQL password.

Steps

1. Check the password in the Debian RoundCube config file:

grep dbpass /etc/roundcube/debian-db.php

2. Check the password in the RoundCube database config:

grep db_dsnw /var/lib/roundcube/config/db.inc.php

The DSN format is: mysql://roundcube:PASSWORD@localhost/roundcube

3. If the passwords differ, update them to match. Retrieve the actual MySQL password for the roundcube user:

mysql -u root -p -e "SELECT user, host FROM mysql.user WHERE user='roundcube';"

Reset the roundcube MySQL user password if needed:

mysql -u root -p <<EOF
ALTER USER 'roundcube'@'localhost' IDENTIFIED BY 'NewRoundcubePass';
FLUSH PRIVILEGES;
EOF

4. Update both config files with the new password and restart Apache:

service apache2 restart

Verify

Open RoundCube in a browser. The database connection error should be gone and the login page should load.

Notes

  • The secure webmail URL can be configured in VestaCP under Server > Domain > Mail.
  • Config file paths may vary by distro: on newer Ubuntu, check /etc/roundcube/ and /usr/share/roundcube/config/.

Fix RoundCube Internal Server Error in VestaCP

RoundCube shows "STATUS: Internal error occurred. Refer to server log for more information" after VestaCP or Dovecot updates. The most common fix is removing a conflicting Dovecot configuration file.

Steps

1. Remove the conflicting Dovecot mailbox config:

rm /etc/dovecot/conf.d/15-mailboxes.conf

2. Restart Dovecot:

service dovecot restart

Additional Checks

If the error persists, check the Dovecot and RoundCube logs:

tail -50 /var/log/dovecot.log
tail -50 /var/log/roundcube/errors

Verify Dovecot is listening correctly:

netstat -tlnp | grep dovecot

Check that RoundCube's IMAP host setting points to localhost:

grep imap_host /etc/roundcubemail/config.inc.php

It should read:

$config['default_host'] = 'localhost';

Verify

Log into RoundCube. The inbox should load without the internal error.

Notes

  • This error commonly appears after Ubuntu 18.04 + VestaCP installations due to Dovecot package conflicts.
  • The 15-mailboxes.conf file conflicts with VestaCP's own Dovecot namespace configuration.

Fix SMTP Error 454 TLS Currently Unavailable

The SMTP error "454 TLS currently unavailable" indicates that Exim cannot initialize TLS, usually due to a certificate file permission error or a misconfigured TLS setup. Check the Exim log and fix the underlying certificate issue.

Steps

1. Check the Exim mail log for the specific error:

tail -100 /var/log/exim4/mainlog | grep -i "tls\|cert\|key\|permission"

2. Identify the certificate and key files Exim is using:

grep -E "tls_certificate|tls_privatekey" /etc/exim4/exim4.conf.template 2>/dev/null
grep -E "tls_certificate|tls_privatekey" /etc/exim4/exim4.conf.localmacros 2>/dev/null

3. Fix permissions on the certificate files so Exim can read them (Exim typically runs as the Debian-exim or exim user):

chmod 644 /path/to/certificate.crt
chmod 640 /path/to/certificate.key
chown root:Debian-exim /path/to/certificate.key

4. If using Let's Encrypt across multiple domains, ensure the certificate pointed to by Exim covers all sending domains or use the server's main certificate.

5. Restart Exim:

service exim4 restart   # Ubuntu/Debian
service exim restart    # CentOS/RHEL

Verify

Test SMTP TLS from the command line:

openssl s_client -connect localhost:25 -starttls smtp

A successful TLS handshake will display certificate details. Check the Exim log for any remaining TLS errors.

Notes

  • The Exim user name varies by distro: Debian-exim on Debian/Ubuntu, exim on CentOS/RHEL.
  • After Let's Encrypt certificate renewal, Exim may need a restart to load the new certificate files.

Remove SpamAssassin Without Breaking Email in VestaCP

To safely disable SpamAssassin in VestaCP without breaking the mail stack, update the VestaCP global configuration to remove SpamAssassin references, then uninstall the package.

Steps

1. Edit the VestaCP configuration file:

nano /usr/local/vesta/conf/vesta.conf

2. Find and update the ANTISPAM_SYSTEM line. Change:

ANTISPAM_SYSTEM='spamassassin'

To:

ANTISPAM_SYSTEM=''

3. Rebuild the mail configuration for all users to remove SpamAssassin hooks from Exim:

for user in $(v-list-users plain | cut -f1); do
    v-rebuild-mail-domains $user
done

4. Stop and disable SpamAssassin:

service spamassassin stop
systemctl disable spamassassin

5. Uninstall the package:

apt-get remove spamassassin spamc   # Ubuntu/Debian
yum remove spamassassin             # CentOS/RHEL

Verify

Send a test email and confirm it is delivered correctly. Check that Exim is not trying to invoke SpamAssassin:

grep -i spam /etc/exim4/exim4.conf.template

Notes

  • If ClamAV is also unwanted, repeat the same steps but set ANTIVIRUS_SYSTEM='' and remove clamav-daemon.
  • Removing spam filtering increases exposure to spam. Consider a lightweight alternative such as rspamd.

Change Web Root Folder in VestaCP

VestaCP sets the web root to /home/USERNAME/web/DOMAIN/public_html/ by default. To point the web root to a subdirectory (e.g. public_html/project/), use a custom Nginx/Apache template or create a symlink.

Method 1: Symlink (Simplest)

Create a symlink from the subfolder to a directory outside public_html, or restructure the web root using a symlink inside it:

cd /home/USERNAME/web/DOMAIN/public_html
ln -s /path/to/project project_folder

This works for adding a subfolder alias but does not change the actual document root.

Method 2: Custom VestaCP Template

1. Copy the default template to a new custom template:

cp /usr/local/vesta/data/templates/web/nginx/default.tpl    /usr/local/vesta/data/templates/web/nginx/customroot.tpl
cp /usr/local/vesta/data/templates/web/nginx/default.stpl    /usr/local/vesta/data/templates/web/nginx/customroot.stpl

2. Edit the new template and change the root directive:

nano /usr/local/vesta/data/templates/web/nginx/customroot.tpl

Find the line:

root %sdocroot%/;

Change it to point to the subfolder:

root %sdocroot%/subfolder/;

3. Assign the new template to the domain in VestaCP panel under Web > Domain > Edit, then select customroot as the web template.

4. Rebuild the domain config:

v-rebuild-web-domains USERNAME

Verify

Place a test index.html file in the new root directory and access the domain in a browser to confirm it loads.

Notes

  • Custom templates persist across VestaCP upgrades but must be re-applied if the panel regenerates configs.
  • If both Nginx and Apache are used, create matching templates for both (.tpl and corresponding Apache template).

Upgrade to PHP 7.1 on VestaCP (Ubuntu)

This guide covers installing PHP 7.1 on VestaCP running Ubuntu, using the Ondrej PPA, and configuring VestaCP to use the new version.

Steps

1. Add the PHP PPA:

add-apt-repository ppa:ondrej/php
apt-get update

2. Install PHP 7.1 and required extensions:

apt-get install php7.1 php7.1-cli php7.1-fpm php7.1-mysql   php7.1-gd php7.1-mbstring php7.1-xml php7.1-curl   php7.1-zip php7.1-bcmath

3. Set PHP 7.1 as the default:

update-alternatives --set php /usr/bin/php7.1

4. Update VestaCP to use PHP 7.1 in its Apache/Nginx templates. Edit the relevant template files:

ls /usr/local/vesta/data/templates/web/apache2/

In each template, update FastCGI or PHP-FPM socket references to point to the PHP 7.1 socket:

# Typically something like:
# /var/run/php/php7.1-fpm.sock

5. Rebuild domain configurations:

v-rebuild-web-domains admin
service php7.1-fpm restart
service nginx restart
service apache2 restart

Verify

php -v

Create and visit a phpinfo() page to confirm PHP 7.1 is active. Remove the file afterwards.

Notes

  • PHP 7.1 is end-of-life. Consider upgrading directly to PHP 8.1 or 8.2 for continued security updates.
  • If running multiple PHP versions, use PHP-FPM pools to assign different PHP versions per domain.
  • Test your application on the new PHP version in a staging environment before upgrading production.

Fix "NO LANGUAGE DEFINED" Login Error in VestaCP

The "NO LANGUAGE DEFINED" error on the VestaCP login page is caused by a quota or configuration issue in the admin user's profile. Updating the DISK_QUOTA value in the user config file resolves it.

Steps

1. Open the admin user configuration file:

nano /usr/local/vesta/data/users/admin/user.conf

2. Find the DISK_QUOTA line. If it shows a numeric value that has been exceeded, change it to unlimited:

DISK_QUOTA='unlimited'

3. Also verify the LANGUAGE field is set correctly (default is en):

LANGUAGE='en'

4. Restart VestaCP:

service vesta restart

Verify

Open the VestaCP panel at https://your-server:8083. The login page should display correctly with the language selector visible. Log in to confirm.

Notes

  • The error may also occur if VestaCP language files are missing. Check that the language directory exists: ls /usr/local/vesta/web/locale/
  • If the language directory is empty or missing, reinstall VestaCP or restore the locale files from backup.
  • This error is often triggered when disk quota is misconfigured after a server migration.

Fix SMTP Error 435 in VestaCP

SMTP error 435 ("Unable to authenticate at present") in VestaCP is typically caused by incorrect file permissions on the Exim authentication socket. Fixing the socket permissions resolves the issue.

Steps

1. Identify the authentication socket path used by Exim:

grep -r "auth_client_socket\|saslauthd" /etc/exim4/ 2>/dev/null

2. Check and fix permissions on the socket file:

ls -la /var/run/saslauthd/
chmod 710 /var/run/saslauthd
chown root:sasl /var/run/saslauthd

3. Add the Exim user to the sasl group so it can access the socket:

usermod -aG sasl Debian-exim   # Ubuntu/Debian
usermod -aG sasl exim          # CentOS/RHEL

4. Restart Exim and the authentication daemon:

service saslauthd restart
service exim4 restart   # Ubuntu/Debian
service exim restart    # CentOS/RHEL

Verify

Test SMTP authentication using an email client or via telnet/openssl:

openssl s_client -connect localhost:587 -starttls smtp

Attempt AUTH LOGIN and confirm authentication succeeds without a 435 error.

Notes

  • The Exim user name differs by distro: Debian-exim on Debian/Ubuntu, exim on CentOS/RHEL.
  • Check /var/log/exim4/mainlog for detailed SMTP authentication errors.

Fix Exim "Retry Time Not Reached for Any Host" Error

The Exim error "retry time not reached for any host" means Exim has previously failed to deliver email to a remote host and is waiting before retrying. The emails are stuck in the queue. This typically happens after a server outage or when a remote server was temporarily unavailable.

Cause

Exim maintains a retry database. When delivery to a remote host fails, Exim records the failure and delays further attempts. Until the retry interval expires, Exim refuses to attempt delivery — even if the remote host is now available.

Steps

1. View the current mail queue:

exim -bp

2. Force an immediate retry for all queued messages, ignoring the retry database:

exim -qff

3. If messages are still stuck, flush the retry database:

exim_dumpdb /var/spool/exim4/db/retry | head -20   # view retry records
exim_tidydb -t 1s /var/spool/exim4/db retry         # expire all retry records

4. Force queue run again:

exim -qf

Verify

Check the mail log to confirm messages are being delivered:

tail -f /var/log/exim4/mainlog

Notes

  • exim -qff forces delivery even if a host is marked as failing. Use it only when you are confident the remote host is back online.
  • If delivery still fails after forcing, the remote server may still be down or your server's IP may be on a blocklist.

Fix Exim T=remote_smtp Defer (-53) Error

The Exim error T=remote_smtp defer (-53): retry time not reached for any host indicates the mail queue is frozen due to expired retry records or corrupted spool files. Clearing the Exim spool database resolves this.

Steps

1. Delete the Exim retry and hints database files:

rm /var/spool/exim4/db/*

2. Clear the input queue (this removes all queued messages — only do this if they are undeliverable or you accept the loss):

rm /var/spool/exim4/input/*
rm /var/spool/exim4/msglog/*

3. Clear old Exim log files if they are very large:

rm /var/log/exim4/*

4. Restart Exim:

service exim4 restart   # Ubuntu/Debian
service exim restart    # CentOS/RHEL

Verify

Check the queue after restart:

exim -bp

Monitor the log for successful deliveries:

tail -f /var/log/exim4/mainlog

Notes

  • Deleting files from /var/spool/exim4/input/ permanently removes queued messages. Back them up first if they may be recoverable.
  • If the error recurs, the underlying cause is likely a network issue or a blocklisted IP — check your server's IP against common RBLs (e.g. MXToolbox).

Restore a VestaCP User with v-restore-user

The v-restore-user command restores a complete VestaCP user account (websites, databases, email, DNS records) from a backup archive. This is the standard method for migrating users between VestaCP servers.

Prerequisites

  • A valid VestaCP backup file (e.g. admin.2024-01-15_03-00-00.tar)
  • The backup file placed in /backup/ on the destination server
  • Root access on the destination server

Steps

1. Transfer the backup archive to the destination server:

scp /backup/USERNAME.DATE.tar root@NEW_SERVER:/backup/

2. Restore the user from the backup:

v-restore-user USERNAME /backup/USERNAME.DATE.tar

Example:

v-restore-user admin /backup/admin.2024-01-15_03-00-00.tar

3. Monitor the restore progress in the VestaCP log:

tail -f /var/log/vesta/system.log

Verify

After restoration completes:

v-list-web-domains USERNAME
v-list-databases USERNAME
v-list-mail-domains USERNAME

Confirm that websites, databases, and mail accounts are all listed correctly.

Notes

  • The destination server must have the same or newer version of VestaCP as the source.
  • Update DNS records to point domains at the new server's IP after successful restoration.
  • If the username already exists on the destination server, the restore may fail or overwrite data. Create a new username if needed.

Install mcrypt Extension for PHP 7.2/7.3 in VestaCP

The mcrypt extension was removed from PHP 7.2+. Applications that still require it must use the PECL version of mcrypt. This guide covers installing it on Ubuntu-based VestaCP servers.

Steps

1. Install the required build dependencies:

apt-get install php7.2-dev libmcrypt-dev gcc make autoconf   # adjust for your PHP version

For PHP 7.3:

apt-get install php7.3-dev libmcrypt-dev gcc make autoconf

2. Install mcrypt via PECL:

pecl install mcrypt

When prompted "libmcrypt prefix?", press Enter to use the default.

3. Enable the extension by adding it to the PHP ini file:

echo "extension=mcrypt.so" > /etc/php/7.2/mods-available/mcrypt.ini
phpenmod mcrypt

Or manually add to php.ini:

echo "extension=mcrypt.so" >> /etc/php/7.2/apache2/php.ini
echo "extension=mcrypt.so" >> /etc/php/7.2/fpm/php.ini

4. Restart web services:

service php7.2-fpm restart
service apache2 restart

Verify

php -m | grep mcrypt

The output should show mcrypt. Also verify in a browser via a phpinfo() page.

Notes

  • Adjust all paths and package names for your specific PHP version (7.2, 7.3, 7.4, etc.).
  • The PECL mcrypt extension supports PHP 7.2+ as a compatibility shim — it uses libmcrypt under the hood.
  • Migrate away from mcrypt to OpenSSL for long-term compatibility, as mcrypt is unmaintained and considered insecure.