Virtualmin
This guide provides step-by-step instructions to configure a multi-tenant SaaS application for Saas module for concord CRM in Virtualmin, enabling wildcard subdomain support (e.g., tenant1.yoursaas.com), custom domain support (e.g., clientdomain.com), and automatic wildcard SSL certificates via Let's Encrypt, which ensures automatic provisioning of tenants.
✅ Requirements
Before configuring, ensure:
Your Concord CRM instance is successfully hosted on Virtualmin.
You have root or admin access to Virtualmin.
Your server supports Let's Encrypt (available in Virtualmin by default).
Your domain’s DNS is managed via Virtualmin or you can modify DNS records externally.
The SaaS module is installed and activated in Concord CRM.
🧭 Goal
Enable multi-tenant SaaS routing with:
Wildcard Subdomain Support (e.g., tenant1.yoursaas.com)
Custom Domain Support (e.g., clientdomain.com)
Automatic SSL (via Let’s Encrypt) for both wildcard subdomains and custom domains
⚙️ Step-by-Step Configuration
1. Set Public Document Root
Ensure the web root for your Concord CRM instance is correctly set in Virtualmin:
Log into Virtualmin as the administrator.
Navigate to Virtualmin > Select your domain (yoursaas.com).
Go to Server Configuration > Website Options.
Set Website documents sub-directory to public (e.g., /home/yoursaas/public_html/public).
Save changes.
📌 This ensures all tenants and domains serve from the same entry point (public directory).
2. Configure Wildcard Subdomain Support
🛠 A. Set Wildcard DNS Record
Navigate to Virtualmin > Select your domain (yoursaas.com) > Server Configuration > DNS Records.
Add a new DNS record:
Type: A
Name: *.yoursaas.com
Value: Your Virtualmin server's IP address
Save changes.
📌 This allows all subdomains (e.g., tenant1.yoursaas.com, tenant2.yoursaas.com) to resolve to your server.
🛠 B. Enable Wildcard Subdomain in Virtualmin
Go to Virtualmin > Select your domain (yoursaas.com) > Server Configuration > Website Options.
Set Website matches all sub-domains? to Yes.
Save changes.
📌 This configures Apache to handle requests for any subdomain under yoursaas.com.
🔐 C. Enable Wildcard SSL (Let's Encrypt)
Navigate to Virtualmin > Select your domain (yoursaas.com) > Server Configuration > Manage SSL Certificate.
Go to the Let’s Encrypt tab.
Ensure the following domains are listed under Domains associated with this server:
yoursaas.com
*.yoursaas.com (check the wildcard option)
Select Request certificate for: Ensure yoursaas.com and *.yoursaas.com are included.
Check Also request wildcard certificate.
Select SSL certificate provider: Let’s Encrypt.
Enable Automatically renew certificate.
Click Request Certificate.
📌 Note: Wildcard SSL requires DNS-based validation, which Virtualmin handles automatically if DNS is managed within Virtualmin. Ensure your DNS is correctly propagated.
3. Add Catch-All Apache Configuration (Optional but Recommended)
Virtualmin manages Apache configurations, but to ensure a catch-all setup for subdomains:
Navigate to Virtualmin > Select your domain (yoursaas.com) > Server Configuration > Edit Apache Configuration.
Add or modify the VirtualHost to include a catch-all ServerAlias:
Save and restart Apache via Webmin > Servers > Apache Webserver > Apply Configuration.
📌 This ensures all subdomains point to the same document root. For HTTPS, Virtualmin automatically applies similar settings to port 443 when SSL is enabled.
4. Configure Custom Domain Support for Tenants
When a client wants to use a custom domain (e.g., clientdomain.com):
🪪 A. Ask Client to Point DNS
Instruct the client to configure their DNS at their registrar:
A Record:
Type: A
Host: @ (or root)
Value: Your Virtualmin server's IP address
Optional CNAME Record (for www):
Type: CNAME
Host: www
Value: clientdomain.com
🔗 B. Add Domain to Virtualmin
Go to Virtualmin > Create Virtual Server.
Enter:
Domain name: clientdomain.com
Description: (Optional, e.g., "Client Custom Domain")
Document Root: /home/yoursaas/public_html/public (same as main domain)
Ensure Enabled features includes:
Apache website enabled
SSL website enabled (if needed)
Save to create the virtual server.
📌 This points clientdomain.com to the same Concord CRM instance.
🔐 C. Install Let’s Encrypt for Client Domain
Navigate to Virtualmin > Select clientdomain.com > Server Configuration > Manage SSL Certificate.
Go to the Let’s Encrypt tab.
Ensure Domains associated with this server includes:
clientdomain.com
www.clientdomain.com (if needed)
Enable Automatically renew certificate.
Click Request Certificate.
📌 If the client provides their own certificate:
Go to Manage SSL Certificate > Upload Certificate.
Upload the .crt, .key, and CA bundle files provided by the client.
Save changes.
🔄 SSL Renewal & Maintenance
Let’s Encrypt certificates in Virtualmin auto-renew every 60–90 days.
Ensure:
Ports 80 and 443 are open on your server.
DNS records resolve correctly to your server’s IP.
Verify SSL status using:
Virtualmin’s Manage SSL Certificate page.
External tools like SSL Labs (https://www.ssllabs.com/ssltest/).
📌 Troubleshooting
Wildcard SSL Fails: Ensure DNS is managed by Virtualmin and the *.yoursaas.com A record is propagated. Check Virtualmin’s error logs at /var/log/virtualmin/yoursaas.com_error_log.
Subdomains Not Resolving: Verify the wildcard DNS record (*.yoursaas.com) and that Website matches all sub-domains? is enabled.
Custom Domain SSL Errors: Confirm the client’s A record points to your server’s IP. Check for HTTP-to-HTTPS redirects blocking Let’s Encrypt validation (disable temporarily if needed).
Content from Wrong Domain: Ensure all virtual servers use the correct document root (/home/yoursaas/public_html/public). Check Apache configuration for overlapping ServerName or ServerAlias directives.
DNS Validation Issues: If DNS is external, manually add the _acme-challenge TXT record as prompted by Virtualmin during wildcard SSL setup.
🔌 MySQL Root Integration for Automatic Tenant Provisioning
The MySQL Root Integration allows the SaaS system to perform database-level operations using root or privileged MySQL credentials. This is essential when using a multi-database or isolated-database tenancy model.
📥 Configuration Fields
Go to Settings > MySQL Root tab in your Concord CRM admin panel.
Provide the MySQL root credentials or privileged user credentials.
⚙️ How It Works
When creating a new tenant with the "Create a new database" or "I will provide my own credentials" option:
A new database is automatically created.
A new MySQL user is created (if enabled).
Required privileges are assigned to the user.
Credentials are securely used on the server side only.
🧠 Fallback Behavior
If disabled or credentials aren't provided:
The system uses the current database connection from
.env
.Ideal for shared hosting or single-database (table-prefix-based) tenancy.
🛡️ Security Recommendations
You may use a dedicated MySQL user with scoped privileges instead of a root user.
Avoid reusing root credentials for other services.
Ensure secure access policies are enforced on your MySQL server.
Last updated