Related Pages
See also: Nginx Web Server, Nginx Configuration Listings, and Let's Encrypt Free SSL for complete SSL documentation.
1 Adding a New Nginx vHost
You will need to enable Centmin Mod's free SSL certificates support via its Let's Encrypt integration. If you use Cloudflare in front of your domains, use the recommended Cloudflare DNS API domain validation method instead of the default webroot validation. The Cloudflare DNS API method works even when Cloudflare's proxy (orange cloud) is enabled. To use the Cloudflare DNS API validation method, set CF_DNSAPI='y', CF_Token, and CF_Account_ID in /etc/centminmod/custom_config.inc.
Centmin Mod provides two alternative methods for creating Nginx site domain vhost accounts — use either one, not both (they achieve the same result):
- The
/usr/bin/nvSSH command line method (recommended) — OR - Traditional Centmin Mod menu option #2 (interactive menu)
Important: Choose only one method. The nv command and menu option 2 both create the same vhost — do NOT run both for the same domain.
Method 1 (Recommended): Using the nv Command
The /usr/bin/nv command allows unattended or scripted creation of new Nginx vhost accounts. There are three SSL methods: (1) -s lelived for Let's Encrypt SSL (recommended), (2) -s y for self-signed SSL (testing only), or (3) -s lelived with the Cloudflare DNS API validation method for domains behind Cloudflare proxy (CF_DNSAPI='y'). Use -s n for no SSL.
Prerequisite: To use Let's Encrypt SSL options (-s lelived, -s lelive, -s le, -s led), first enable Let's Encrypt support by setting LETSENCRYPT_DETECT='y' in /etc/centminmod/custom_config.inc. See the Let's Encrypt Free SSL page for full setup details.
For a production site with a free Let's Encrypt SSL certificate and HTTPS as default (recommended). For domains behind Cloudflare proxy, use -s lelived with the Cloudflare DNS API validation method (configure CF_DNSAPI='y' in /etc/centminmod/custom_config.inc):
# For Cloudflare proxy domains, enable Cloudflare DNS API validation first:
# Set CF_DNSAPI='y' and CF_Token in /etc/centminmod/custom_config.inc
# See Cloudflare DNS API Validation section below for full setup
/usr/bin/nv -d newdomain.com -s lelived -u MYFTPUSERNAME
For domains behind Cloudflare proxy (orange cloud enabled), use -s lelived with the Cloudflare DNS API validation method. Configure CF_DNSAPI='y' and your Cloudflare API token in /etc/centminmod/custom_config.inc before running nv. See Cloudflare DNS API Validation for full setup:
/usr/bin/nv -d newdomain.com -s lelived -u MYFTPUSERNAME
For quick testing with a self-signed SSL certificate (not browser-trusted):
/usr/bin/nv -d newdomain.com -s y -u MYFTPUSERNAME
Method 2 (Alternative): Using Menu Option #2
Run centmin.sh (can also be called via the centmin alias) and select option 2. You will be prompted for the domain name, SSL certificate option, and FTP username. With LETSENCRYPT_DETECT='y' set in /etc/centminmod/custom_config.inc, the menu will offer Let's Encrypt SSL options — choose lelived for production sites. Self-signed SSL (-s y) is not suitable for production — use it only for local development or testing environments where browser trust is not required. The script will auto-generate the vhost configuration files, SSL certificates, and FTP credentials.
Enter vhost domain name to add (without www. prefix): newdomain.com
Choose SSL certificate type:
lelived - Let's Encrypt SSL + HTTPS default (recommended)
le - Let's Encrypt SSL HTTP default
y - Self-signed SSL (testing only)
n - No SSL
SSL choice: lelived
Create FTP username for vhost domain (enter username): MYFTPUSERNAME
Auto generate FTP password (recommended) [y/n]: y
Cloudflare DNS API Validation
For domains behind Cloudflare's proxy, use the Cloudflare DNS API domain validation method instead of webroot validation. Configure in /etc/centminmod/acmetool-config.ini by setting CF_DNSAPI_GLOBAL='y' and providing your Cloudflare API credentials. This uses --dns dns_cf validation via the acmetool.sh addon. See Let's Encrypt SSL for full Cloudflare DNS API setup instructions.
Hosting Multiple Websites on One Server
You can host unlimited websites on one Centmin Mod server. Run the /usr/bin/nv command once per domain — each domain gets its own Nginx vhost configuration at /usr/local/nginx/conf/conf.d/ and a dedicated document root at /home/nginx/domains/.
# First website — Let's Encrypt SSL (recommended for production)
/usr/bin/nv -d site1.com -s lelived -u user1
# Second website — Let's Encrypt SSL
/usr/bin/nv -d site2.com -s lelived -u user2
# Third website — and so on for each additional domain
/usr/bin/nv -d site3.com -s lelived -u user3
Always use -s lelived for production sites
The -s lelived flag issues a free Let’s Encrypt SSL certificate and sets HTTPS as the default. Use -s y only for local development or testing where browser trust is not required.
Creating a MySQL Database for Each Hosted Website
After adding each Nginx vhost domain, create a dedicated MySQL database and user for that website. Use centmin.sh Menu 6 (MySQL User Database Management) or the mysqladmin_shell.sh addon for non-interactive creation.
# Non-interactive: create database, user, and grant permissions in one command
# Using mysqladmin_shell.sh createuserdb addon (recommended for scripting)
/usr/local/src/centminmod/addons/mysqladmin_shell.sh createuserdb site1db site1user site1pass
/usr/local/src/centminmod/addons/mysqladmin_shell.sh createuserdb site2db site2user site2pass
# Interactive: run centmin menu and select Menu 6 (MySQL User Database Management)
# Then choose Menu 6 sub-option 1 (Create MySQL User and Database)
centmin
Use mysqladmin_shell.sh createuserdb or Menu 6 — not raw SQL
The mysqladmin_shell.sh createuserdb addon creates the database, user, and grants all required web application permissions in one step. Do not use manual CREATE USER / GRANT SQL commands — the addon handles the full workflow correctly. See MariaDB MySQL documentation for all Menu 6 database management options.
2 Document Root Structure
When a new vhost is created, Centmin Mod sets up the following directory and file structure:
| Path | Purpose |
|---|---|
| /home/nginx/domains/newdomain.com/public | Public web root (upload files here) |
| /home/nginx/domains/newdomain.com/log | Vhost log files directory |
| /usr/local/nginx/conf/conf.d/newdomain.com.conf | HTTP vhost config |
| /usr/local/nginx/conf/conf.d/newdomain.com.ssl.conf | HTTPS/SSL vhost config |
| /usr/local/nginx/conf/ssl/newdomain.com/ | Self-signed SSL certificate directory |
For the full guide of Nginx vhost directory structure, see the Centmin Mod configuration files page.
3 vHost Configuration Files
The HTTP vhost config file at /usr/local/nginx/conf/conf.d/newdomain.com.conf contains the basic server block:
server {
server_name newdomain.com www.newdomain.com;
access_log /home/nginx/domains/newdomain.com/log/access.log combined buffer=256k flush=5m;
error_log /home/nginx/domains/newdomain.com/log/error.log;
root /home/nginx/domains/newdomain.com/public;
location / {
# try_files $uri $uri/ /index.php;
}
include /usr/local/nginx/conf/staticfiles.conf;
include /usr/local/nginx/conf/php.conf;
include /usr/local/nginx/conf/drop.conf;
include /usr/local/nginx/conf/vts_server.conf;
}
The HTTPS/SSL vhost config at /usr/local/nginx/conf/conf.d/newdomain.com.ssl.conf adds SSL directives:
server {
listen 443 ssl http2;
server_name newdomain.com www.newdomain.com;
ssl_dhparam /usr/local/nginx/conf/ssl/newdomain.com/dhparam.pem;
ssl_certificate /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.key;
include /usr/local/nginx/conf/ssl_include.conf;
ssl_prefer_server_ciphers on;
ssl_buffer_size 1369;
ssl_session_tickets on;
access_log /home/nginx/domains/newdomain.com/log/access.log combined buffer=256k flush=5m;
error_log /home/nginx/domains/newdomain.com/log/error.log;
root /home/nginx/domains/newdomain.com/public;
location / {
# try_files $uri $uri/ /index.php;
}
include /usr/local/nginx/conf/staticfiles.conf;
include /usr/local/nginx/conf/php.conf;
include /usr/local/nginx/conf/drop.conf;
include /usr/local/nginx/conf/vts_server.conf;
}
Enabling Optional Features
To enable auto index (directory listing when no index file exists), uncomment the autoindex on; directive. To enable server side includes, uncomment ssi on;. After changes, restart Nginx:
# Restart Nginx via service command
service nginx restart
# Or via Centmin Mod command shortcut
ngxrestart
4 HTTP to HTTPS Redirect
Testing Tip
Always test in an incognito/private browser session first. Use return 302 (temporary redirect) before switching to return 301 (permanent redirect) once confirmed working.
With the auto-generated SSL vhost structure, disable the HTTP vhost by renaming it:
mv /usr/local/nginx/conf/conf.d/newdomain.com.conf \
/usr/local/nginx/conf/conf.d/newdomain.com.conf-disabled
Then add a redirect server block at the top of the .ssl.conf file. For redirecting to non-www HTTPS:
# 1st server{} - Redirect HTTP to HTTPS
server {
server_name newdomain.com www.newdomain.com;
return 302 https://newdomain.com$request_uri;
}
# 2nd server{} - Redirect www HTTPS to non-www HTTPS
server {
listen 443 ssl http2;
server_name www.newdomain.com;
ssl_dhparam /usr/local/nginx/conf/ssl/newdomain.com/dhparam.pem;
ssl_certificate /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.key;
include /usr/local/nginx/conf/ssl_include.conf;
return 302 https://newdomain.com$request_uri;
}
# 3rd server{} - Main HTTPS site
server {
listen 443 ssl http2;
server_name newdomain.com;
# ... rest of SSL config ...
}
For redirecting to www HTTPS instead, change the redirect target to https://www.newdomain.com$request_uri and adjust the server_name in the 3rd server block to www.newdomain.com.
Once redirects are confirmed working, change return 302 to return 301 and restart Nginx.
5 Switch to Paid SSL Certificate
To switch from the auto-generated self-signed SSL certificate to a paid certificate, follow the steps outlined in the Let's Encrypt Free SSL guide. You can also refer to the security headers configuration to create the unified certificate chain.
Update the SSL certificate paths in your .ssl.conf file and enable OCSP stapling:
# Change from self-signed paths:
ssl_certificate /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/newdomain.com/ssl.key;
# To paid SSL certificate paths:
ssl_certificate /usr/local/nginx/conf/ssl/newdomain.com/ssl-unified.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.key;
# Enable OCSP stapling (only for trusted certificates):
resolver 8.8.8.8 8.8.4.4 valid=10m;
resolver_timeout 10s;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/nginx/conf/ssl/newdomain.com/ssl-trusted.crt;
6 OCSP Stapling
OCSP Stapling is only used for commercial SSL certificates that are trusted by web browsers. For self-signed certificates, these settings are disabled by default.
To enable OCSP stapling, uncomment the following lines in your SSL vhost config and restart Nginx:
# Enable OCSP stapling
resolver 8.8.8.8 8.8.4.4 valid=10m;
resolver_timeout 10s;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/nginx/conf/ssl/domain.com/domain.com-trusted.crt;
To verify OCSP stapling is working, run via SSH:
openssl s_client -connect domain.com:443 -tls1 -tlsextdebug -status
Look for OCSP Response Status: successful (0x0) in the output. You can also verify at certificate.revocationcheck.com.
7 HSTS for SSL
Warning
HSTS tells browsers to force HTTPS for the specified max-age (up to 1 year). If your site is not fully HTTPS-ready, enabling HSTS can cause errors that persist in browsers for a long time. If using Cloudflare, configure HSTS via the Cloudflare dashboard instead.
HTTP Strict Transport Security (HSTS) forces browsers to redirect all HTTP traffic to HTTPS. To enable, uncomment the appropriate line in your SSL vhost config:
# If SSL covers subdomains:
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
# If SSL does NOT cover subdomains:
add_header Strict-Transport-Security "max-age=31536000;";
For per-site HSTS (when only some sites need it), create a copy of the static files include:
# Create a HSTS-enabled copy of staticfiles.conf
cp -a /usr/local/nginx/conf/staticfiles.conf /usr/local/nginx/conf/staticfiles-hsts.conf
# Then in the HSTS-enabled vhost config, use:
#include /usr/local/nginx/conf/staticfiles.conf;
include /usr/local/nginx/conf/staticfiles-hsts.conf;
# Restart Nginx and PHP-FPM
nprestart
8 Delete an Nginx vHost
Important
Domain deletion is a manual process by design. Always back up your data before removing a vhost. Each vhost creation logs removal commands in /root/centminlogs.
Step 1: Back Up Data
cp -a /usr/local/nginx/conf/conf.d/existingdomain.com.conf \
/usr/local/nginx/conf/conf.d/existingdomain.com.conf.bak
cp -a /home/nginx/domains/existingdomain.com/ \
/home/nginx/domains/existingdomain.com.bak/
Step 2: Delete Domain Files
You can find the exact removal commands logged in /root/centminlogs:
# Removal commands (from /root/centminlogs)
rm -rf /usr/local/nginx/conf/conf.d/existingdomain.com.conf
rm -rf /usr/local/nginx/conf/conf.d/existingdomain.com.ssl.conf
rm -rf /usr/local/nginx/conf/ssl/existingdomain.com/existingdomain.com.crt
rm -rf /usr/local/nginx/conf/ssl/existingdomain.com/existingdomain.com.key
rm -rf /usr/local/nginx/conf/ssl/existingdomain.com/existingdomain.com.csr
rm -rf /usr/local/nginx/conf/ssl/existingdomain.com
rm -rf /home/nginx/domains/existingdomain.com
rm -rf /root/.acme.sh/existingdomain.com
rm -rf /root/.acme.sh/existingdomain.com_ecc
rm -rf /usr/local/nginx/conf/pre-staticfiles-local-existingdomain.com.conf
Step 3: Restart Nginx
service nginx restart
# Or via shortcut:
ngxrestart
Step 4: Remove Backups
Once you are 100% sure the deleted domain is correct, remove the backups:
rm -rf /usr/local/nginx/conf/conf.d/existingdomain.com.conf.bak
rm -rf /home/nginx/domains/existingdomain.com.bak/
9 NSD DNS Setup (Menu Option 3)
Alternative DNS Options
If you prefer not to host your own DNS, you can use third-party DNS providers: Cloudflare DNS (free), DigitalOcean DNS (ns1/ns2/ns3.digitalocean.com), or your domain registrar's DNS hosting.
Setting up DNS is a two-part process:
Part 1: Register Private Nameservers
Register your own private nameservers (ns1.yourdomain.com, ns2.yourdomain.com) with your domain registrar. Tutorials from common registrars:
Part 2: NSD DNS Configuration (Menu Option 3)
Use Centmin Mod menu option #3 to set up NSD DNS on your server. You will need:
- The domain name to add (e.g.,
newdomain.com) - The A record IP address (your server's IP)
- IP addresses for ns1 and ns2 nameservers
IP Address Note
The ns1/ns2 assigned IP addresses should usually not be used to host other domain names. A minimum of 3 IP addresses is recommended: 1 for domains and 2 for ns1/ns2 (though you can use a single IP).
The script creates a DNS zone file at /etc/nsd/master/newdomain.com.zone with the following structure:
$TTL 14400
@ IN SOA ns1.newdomain.com. hostmaster.newdomain.com. (
2010091500
14400
3600
1209600
86400 )
; Nameservers
newdomain.com. 14400 IN NS ns1.newdomain.com.
newdomain.com. 14400 IN NS ns2.newdomain.com.
; A Records
newdomain.com. 14400 IN A YOUR_SERVER_IP
ftp 14400 IN A YOUR_SERVER_IP
localhost 14400 IN A 127.0.0.1
mail 14400 IN A YOUR_SERVER_IP
ns1 14400 IN A NS1_IP_ADDRESS
ns2 14400 IN A NS2_IP_ADDRESS
www 14400 IN A YOUR_SERVER_IP
; MX Record
newdomain.com. 14400 IN MX 10 mail
; TXT Record (for SPF)
newdomain.com. 14400 IN TXT "v=spf1 a mx ip4:YOUR_SERVER_IP ~all"
After modifying the zone file, restart NSD:
service nsd restart
10 Custom Nameservers
By default, the NSD setup script creates ns1.newdomain.com and ns2.newdomain.com. You can change these later by editing the zone file at /etc/nsd/master/newdomain.com.zone.
If you switch your domain's nameservers to use your registrar's or a third-party DNS provider's nameservers, the NSD configuration on the server is bypassed. No changes to the NSD zone file are necessary in that case.
For a full step-by-step NSD DNS setup example, see the Centmin Mod Community forums guide.
11 DNS Propagation
After configuring your DNS records, verify propagation using these DNS testing tools:
- whatsmydns.net -- Global DNS propagation checker
- dnsinspect.com -- DNS configuration inspector
- intodns.com -- DNS health checker
- dnscheck.pingdom.com -- Pingdom DNS checker
The default TTL (Time To Live) in the NSD zone file is 14400 seconds (4 hours). DNS propagation can take anywhere from a few minutes to 48 hours depending on TTL settings and DNS caches worldwide.
Quick DNS Check
You can check DNS resolution from the command line using dig newdomain.com or nslookup newdomain.com. To reduce propagation time before migration, lower the TTL value in advance.
Related Documentation
Domain Parking / Aliases
To serve the same website content under multiple domain names (domain parking or domain aliases), add the additional domains to the server_name directive in the existing vhost configuration. After editing, validate and apply the changes with nginx -t && ngrestart.
Adding Domain Aliases to an Existing Vhost
Edit the vhost config file at /usr/local/nginx/conf/conf.d/primarydomain.com.ssl.conf:
# In the HTTPS server block, add alias domains to server_name
server {
listen 443 ssl http2;
server_name primarydomain.com www.primarydomain.com alias1.com www.alias1.com alias2.com;
...
}
# Also update the HTTP server block for redirects
server {
listen 80;
server_name primarydomain.com www.primarydomain.com alias1.com www.alias1.com alias2.com;
...
}
DNS Requirements
- Each alias domain must have its DNS A/AAAA records pointing to your server’s IP address
- If using Cloudflare, enable the proxy (orange cloud) for each alias domain
SSL Certificate Considerations
- SAN certificates — Use Let’s Encrypt with Subject Alternative Names (SAN) to cover all domains on one certificate:
acmetool.sh issue primarydomain.com lived d alias1.com - Wildcard certificates — If aliases share a parent domain, a wildcard cert (
*.primarydomain.com) covers all subdomains - Separate certificates — Each alias domain can have its own SSL certificate, but this requires separate server blocks
# After editing the vhost config, validate and restart Nginx
nginx -t && ngrestart
For more details, see the forum discussion.
Need Help With DNS or Domain Setup?
Join the Centmin Mod community forums for troubleshooting help and detailed configuration guides.