Why Vtiger Needs Separate Instances, Not Multi-Tenancy
Vtiger CRM (the open-source on-premise edition) was built as a single-tenant application. One codebase connects to exactly one database defined in config.inc.php, and that database holds every account, contact, module layout, workflow, and user record for a single organization. There is no built-in tenant switcher, no network of linked sites, and no concept of a shared user table serving multiple isolated company spaces the way WordPress Multisite or a true SaaS platform operates. The hosted Vtiger.com product offers multi-company features, but the software you install on a shared hosting account does not.
That architecture has a direct consequence: if you need to run a CRM for two separate departments, two clients, or a staging copy alongside production, you do not configure "sites" inside one Vtiger. You install Vtiger again, fully, in a separate directory with its own database. Each installation is independent. Upgrading one does not touch the other, a corrupted workflow in one cannot leak into the other, and you can assign each a different PHP version if their module versions require it.
On managed shared hosting this is entirely achievable without root access. cPanel Jupiter and DirectAdmin Evolution both let an unprivileged user create subdomains, provision MySQL databases, set document roots, and pin PHP versions per domain. The work is mostly organizational discipline: keeping directories, databases, and database users cleanly separated so the instances never accidentally share state. The sections below walk through a practical two-instance deployment on subdomains, then cover the isolation and resource settings that keep both running cleanly on one account.
Creating Subdomains and Isolated Document Roots
Decide on a naming scheme before you touch anything. Subdomains read well and keep cookies and sessions separate by hostname, which matters because Vtiger stores its session and login state per domain. A typical layout for a primary domain example.com would be sales.example.com and support.example.com, or crm.example.com for production and crm-staging.example.com for testing.
In cPanel Jupiter, open Domains and click Create A New Domain. Enter sales.example.com. cPanel suggests a document root automatically; override it to a clean, predictable path such as /home/username/vtiger_sales rather than nesting it under public_html. Keeping each instance in its own top-level folder under the home directory prevents one site's .htaccess from inheriting rules from another. Repeat for the second subdomain, pointing it at /home/username/vtiger_support.
In DirectAdmin Evolution, the path is Account Manager → Domain Setup → Add Another Domain for a full domain, or use Subdomain Management to add sales under your main domain. DirectAdmin places subdomain roots under /home/username/domains/example.com/public_html/sales by default. That nesting is acceptable, but confirm the exact path shown in the panel so you upload Vtiger to the right place.
Download the Vtiger release ZIP from the official SourceForge/Vtiger download page, then use File Manager to upload it into the first instance's document root and extract it there. Do not copy one extracted installation into the second folder by hand before configuration — upload a fresh copy for each instance so neither one carries over the other's generated cache or config. After extraction, confirm the folder owns a cache/, storage/, user_privileges/, and config.template.php set, and that the extracted files sit at the document root level rather than inside an extra vtigercrm/ subfolder (move them up one level in File Manager if they do).
Database Provisioning and Strict Isolation
Each Vtiger instance must have its own database and its own database user. Sharing a single database between two installations will cause the installers to overwrite each other's tables and destroy both. In cPanel use MySQL Databases; in DirectAdmin use Account Manager → MySQL Management. Create one database per instance with names that mirror the subdomains, for example username_vtsales and username_vtsupport. The username_ prefix is added automatically on shared hosting.
Create a dedicated user for each database — username_vtsalesusr and username_vtsupportusr — with distinct strong passwords, and assign each user to only its matching database with ALL PRIVILEGES. Never assign one user to both databases. This single-user-per-database rule is your isolation boundary: a compromised credential or a misconfigured instance can only reach its own data.
Run each installer by visiting the subdomain in a browser, for example https://sales.example.com/. The Vtiger web installer will prompt for database host (use localhost on shared hosting, not 127.0.0.1 unless the panel documents otherwise), the database name, the database user, and the password you just created. The installer writes these values into config.inc.php in that instance's root. Open each instance's config.inc.php afterward in File Manager and verify the $dbconfig['db_server'], $dbconfig['db_name'], and $site_URL values point only at that instance. The $site_URL must exactly match the subdomain, including https://, or module links, AJAX calls, and the login redirect will break.
Because Vtiger relies on scheduled background tasks for workflows, email, and recurring records, each instance needs its own cron entry pointing at that instance's vtigercron.php. In cPanel Cron Jobs or DirectAdmin Cron Jobs, add one line per instance, for example /usr/local/bin/php /home/username/vtiger_sales/cron/vtigercron.php and a second identical line for the support path. The scheduling and stuck-job principles carry over closely from other PHP CRMs — the approach documented for SuiteCRM scheduler configuration on shared hosting applies to diagnosing a Vtiger cron that silently stops firing.
Per-Instance PHP, Limits, and Troubleshooting
Running two Vtiger instances on one account means they draw from the same CloudLinux LVE resource pool — CPU, memory, and the entry-process limit are shared across everything your account runs. Tune each instance to stay lean so one does not starve the other. Vtiger wants generous PHP settings, but you can scope them per instance using a .user.ini file placed in each document root. A reasonable baseline per instance:
memory_limit = 256M
max_execution_time = 120
max_input_time = 120
post_max_size = 32M
upload_max_filesize = 32M
max_input_vars = 4000Because .user.ini is read per directory, the sales instance and support instance can hold different values if one handles larger imports than the other. Changes take effect after the user_ini.cache_ttl window (commonly 300 seconds) rather than instantly.
If both instances need the same PHP branch, set it once; if a plugin in one requires an older interpreter, scope it individually. In cPanel use MultiPHP Manager, select the specific subdomain, and assign its PHP version — this writes the correct handler into that subdomain's .htaccess without affecting the other. In DirectAdmin, use the domain's PHP Version Selector. Then open the PHP Selector → Extensions area (cPanel: Select PHP Version → Extensions) and confirm Vtiger's required extensions are enabled: imap, mbstring, gd, pdo_mysql, zip, and curl. Enabling them for the account covers both instances since the selector is account-wide, but each subdomain still needs the matching PHP version assigned.
When one instance misbehaves, read its own log, not a shared one. Each Vtiger writes PHP errors to the error_log file in its document root (and often inside cache/ or logs/). A blank page after login on support.example.com but a healthy sales.example.com almost always traces to a wrong $site_URL, a stale cache/ directory copied from the other instance, or that subdomain being pinned to a PHP version missing imap. Clear the offending instance's cache/ contents via File Manager, re-check its config.inc.php, and watch its local error_log while you reload. Keeping the directories, databases, users, cron jobs, and logs strictly one-per-instance is what lets several independent Vtiger CRMs coexist cleanly on a single unprivileged hosting account.