iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
The most reliable design is one VPS with Nginx or Apache at the public edge, DNS records for every domain, and a separate virtual host or server block for each site. Serve static files directly, send CMS requests to isolated PHP-FPM, Apache, or container services, and keep each site’s files, database, credentials, logs, and backups separate.
This arrangement lets domains share one public IP without merging applications. Its practical limit is not a fixed site count: traffic concurrency, PHP workers, database queries, plugins or modules, cache efficiency, storage I/O, backups, and monitoring determine whether the VPS has enough headroom.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchThe architecture that works for mixed sites
A VPS can answer for many domains because HTTP clients send the requested hostname and the web server selects a matching name-based virtual host (Apache terminology) or server block (Nginx terminology). Apache’s documentation defines a virtual host as running more than one website on one machine. The same principle applies when all domains resolve to one IPv4 address, and it also works with IPv6 when every domain has the correct AAAA record.
Use this traffic path:
Visitor → DNS → VPS ports 80/443 → Nginx or Apache → site root or application upstream → database/cache on a private network
Static sites stop at the file server. A CMS request continues to PHP-FPM, an Apache upstream, or an application container. The proxy should be the only service exposed to the internet unless an administrative service has a deliberate, documented access policy.
#1 Best Overall
What belongs in the shared edge
- Listening on ports 80 and 443.
- Matching the requested hostname to exactly one site configuration.
- Serving static assets and applying cache and compression policy.
- Terminating TLS and selecting the correct certificate.
- Forwarding dynamic requests to the intended application service.
- Writing access and error logs that identify the site.
What should stay behind it
- PHP-FPM sockets or ports.
- CMS application processes.
- MySQL, MariaDB, PostgreSQL, Redis, and similar services.
- Deployment tooling, management dashboards, and backup agents.
Bind those internal services to localhost or an internal container network. Do not publish database ports merely because several websites share the server.
Nginx or Apache: choose by operating model
Both servers can host multiple domains. The better choice depends on how you prefer to configure applications and how much compatibility you need with existing CMS instructions.
| Decision point | Nginx | Apache |
|---|---|---|
| Static delivery | Direct file serving with lightweight server blocks | Direct file serving through virtual hosts |
| Dynamic traffic | Usually proxies to PHP-FPM, Apache, or a container | Can use PHP-FPM or an integrated module, depending on the deployment |
| Per-directory overrides | No .htaccess equivalent; rules belong in the administrator-managed configuration | Can support .htaccess when enabled, which suits CMS packages that document those files |
| Reverse-proxy style | Natural fit for several independent upstream services | Can reverse-proxy too, but many teams use it primarily as the application web server |
| Operational trade-off | Centralized, explicit configuration and reloads | Familiar CMS workflows and compatibility with .htaccess-based guidance |
WordPress documentation notes that many sites identified as Nginx sites are actually Apache behind Nginx as a reverse proxy. That is a valid arrangement, but it adds another layer to update and troubleshoot. Use it when an existing Apache application depends on Apache behavior while you still want Nginx at the public edge.
Choose Nginx when you want one transparent proxy configuration for static files and several application services. Choose Apache when .htaccess compatibility and established CMS procedures matter more than a proxy-first design. Do not run both by default; each additional layer increases configuration and failure points.
Give every website a separate boundary
Shared hardware does not require shared application state. Create a boundary for every site before installing the first CMS.
Separate document roots
Use a predictable path such as:
/srv/www/site-a/public
/srv/www/site-b/public
/srv/www/blog.example.net/public
Point each virtual host or server block to one root only. Never place one site’s upload directory inside another site’s root, and do not use a single generic web root with hostname-based subdirectories selected by application code.
Rank #2
Separate users and permissions
Run deployment and application processes with the least privilege that still permits updates. A static site’s files can be owned by a deployment user and read by the web server. A CMS normally needs a writable uploads or files directory, but that writable area should be narrower than the entire codebase. Keep configuration files containing secrets outside public directories, and ensure private keys are readable only by the service account that needs them.
Separate logs and deployment settings
Write access and error logs per site. This makes rate spikes, broken rewrites, and abusive paths attributable to one domain rather than hidden in one undifferentiated file. Keep each site’s repository, deployment variables, scheduled jobs, and rollback instructions separate as well.
Separate databases and credentials
Give each CMS its own database and database user, even when all databases run in one database server. A compromised plugin should not automatically receive credentials for another site. Store credentials in a protected environment file or secret store, not in a publicly served configuration file or a repository.
When containers are worth adding
Docker Compose defines multi-container applications in YAML, including services, networks, and volumes. A useful pattern is one front proxy, one application service per CMS, and a database or cache service attached only to that CMS’s internal network. Containers provide stronger process and dependency separation and make a deployment repeatable, but they do not replace patching, least-privilege permissions, or backups. A vulnerable application in a container can still expose data reachable from its network.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →services:
cms_a:
image: your-cms-image
networks: [site_a_net]
volumes:
- site_a_files:/var/www/html
db_a:
image: your-database-image
networks: [site_a_net]
volumes:
- site_a_db:/var/lib/database
networks:
site_a_net:
internal: true
volumes:
site_a_files:
site_a_db:
The example is a pattern rather than a drop-in production file: pin image versions, set passwords through secrets, define health checks, and document the persistent paths before deploying.
Plan capacity without inventing a site count
There is no honest universal answer to “How many sites can a 2 GB or 4 GB VPS handle?” Official guidance for the components above publishes no general site-count statistic. A lightly visited static site may consume almost no CPU while idle; one busy CMS can exhaust memory or database I/O by itself.
Rank #3
| Workload signal | Why it matters | What to measure |
|---|---|---|
| Static traffic | Mostly file reads and network throughput | Bandwidth, cache hit rate, disk latency, and open connections |
| PHP or application concurrency | Each active worker consumes memory and CPU | Worker utilization, queue time, request latency, and out-of-memory events |
| Database activity | Queries and indexes can become the bottleneck before the web server | Query latency, locks, buffer usage, and storage I/O |
| Plugins or modules | Extensions add background jobs, queries, and attack surface | Slow requests, scheduled-task duration, and error rates after updates |
| Backups and scans | Maintenance jobs compete for CPU, memory, and disk | Backup duration, snapshot space, and I/O contention during the job |
| Logging and monitoring | Verbose logs can fill a small disk | Disk usage, retention, and alert delivery |
Start with measured usage, leave headroom for bursts and maintenance, then scale vertically or split workloads when contention appears. A sensible split is to move the noisiest database or highest-traffic CMS to another VPS while leaving low-traffic static sites on the original server.
Prepare the VPS before adding domains
- Patch the operating system. Apply security updates, set the correct time zone, and enable automatic security updates when your distribution supports them.
- Create an administrative path. Use a non-root administrator with key-based SSH, restrict SSH access with a firewall policy, and keep a documented recovery account.
- Install the edge server. Install Nginx or Apache, enable its service at boot, and verify that a default page is reachable before adding custom sites.
- Install the runtime. Add the PHP version and extensions required by each CMS, or prepare the application containers. Do not assume that one CMS’s requirements suit another.
- Create storage and service accounts. Make the per-site directories, ownership rules, log paths, and database users before copying application files.
- Set a firewall. Allow inbound TCP 80 and 443. Allow SSH only from the addresses or access method you deliberately maintain. Keep database and cache ports private.
Connect DNS to the VPS
For every hostname, create an A record pointing to the VPS’s IPv4 address. Add an AAAA record only when the server is correctly configured for IPv6 and the firewall permits it. Include the bare domain and the intended subdomains; a record for www does not automatically cover the apex domain.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches- Create the A and, if applicable, AAAA records at the authoritative DNS provider.
- Wait until public resolvers return the VPS address. Check both the apex name and every
wwwor CMS subdomain you plan to serve. - Make the hostname list in the DNS records match the names in the web-server configuration exactly.
- Keep the old server online until the new records resolve consistently and the new site has passed testing.
DNS propagation is not a signal that the application is ready. Test the origin directly with the hostname, inspect which virtual host answered, and confirm that an unknown hostname does not expose the wrong site’s files.
Configure name-based sites
Static site with Nginx
Create one server block per domain, with a unique root and log files:
server {
listen 80;
server_name example.net www.example.net;
root /srv/www/example.net/public;
index index.html;
access_log /var/log/nginx/example.net.access.log;
error_log /var/log/nginx/example.net.error.log;
location / {
try_files $uri $uri/ =404;
}
}
Enable the file according to your distribution’s layout, validate the complete configuration, and gracefully reload Nginx. Use a separate block for every domain rather than adding unrelated roots to one block.
Free tools Windows power users keep installed
One-click scans. No signup required.
CMS requests through Nginx
A PHP CMS needs a front controller rule and a PHP-FPM upstream. The exact socket path depends on the installed PHP version, so use the path supplied by your distribution:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
Do not copy this socket name blindly. Confirm it exists, restrict direct access to sensitive files, and test permalinks, uploads, and administrator login after reloading.
Virtual host with Apache
An Apache virtual host follows the same isolation rule:
<VirtualHost *:80>
ServerName example.net
ServerAlias www.example.net
DocumentRoot /srv/www/example.net/public
ErrorLog ${APACHE_LOG_DIR}/example.net-error.log
CustomLog ${APACHE_LOG_DIR}/example.net-access.log combined
<Directory /srv/www/example.net/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Enable only the override behavior your CMS actually needs. If you use Nginx in front of Apache, make Apache listen on a private address or port and configure Nginx to proxy only the intended hostnames.
Enable HTTPS for every hostname
Open inbound ports 80 and 443, confirm DNS resolves, and then obtain certificates with Certbot’s Nginx or Apache plugin. Certbot can request a certificate and optionally install the web-server changes.
- Install Certbot and the plugin matching Nginx or Apache.
- Request a certificate for every name the site serves, for example the apex and
wwwhostname. - Choose the plugin installation mode if you want Certbot to edit the active server configuration, or use certificate-only mode when you maintain the TLS configuration yourself.
- Test HTTPS in a browser and with a command-line request. Check that the certificate names match the hostname and that HTTP redirects to HTTPS only after the HTTPS virtual host works.
- Verify the scheduled renewal job. Run a dry-run renewal test, then validate the web-server configuration and perform a graceful reload after a real renewal.
Keep certificate and private-key permissions restricted. If a certificate covers several domains, list every covered name in your inventory and renew it as one unit. A failed renewal should trigger an alert before the existing certificate expires.
Back up files, databases, and configuration independently
A website is not recoverable from its document root alone. Back up these components separately:
Best Value
- Static assets and CMS uploads.
- Application code and deployment manifests.
- Database dumps, with credentials stored outside the dump location.
- Nginx or Apache configuration, enabled-site links, and TLS automation settings.
- Docker Compose files, image version records, and persistent volumes when containers are used.
- Scheduled jobs, environment variables, and a map of DNS records.
Keep at least one copy away from the VPS. Encrypt backups, restrict access, retain several historical points, and rehearse restoration to a clean host. A backup that has never been restored is an assumption, not a recovery plan.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Operate many sites without losing track
Use a per-site deployment checklist
- Build or pull the release artifact.
- Run database migrations for that site only.
- Deploy files atomically, such as by switching a release symlink.
- Set ownership and writable-directory permissions.
- Clear the appropriate application cache.
- Check the homepage, a representative dynamic page, login, forms, uploads, and scheduled tasks.
- Keep the previous release available for rollback.
Monitor shared bottlenecks
Watch memory pressure, swap activity, CPU saturation, disk utilization, inode usage, storage latency, PHP-FPM queues, database connections, certificate expiry, and HTTP error rates. Alert per hostname so one failing CMS does not hide behind an apparently healthy aggregate metric.
Control scheduled jobs
Stagger backups, CMS cron tasks, image processing, search indexing, and security scans. Running every site’s heavy job at the same minute can create a false capacity problem. Record which user runs each job and where its output is logged.
Keep configuration reviewable
Store server blocks, virtual hosts, Compose files, and deployment scripts in version control. Validate configuration before reloads. A failed syntax check should stop the deployment rather than take every domain offline.
Architecture choices compared
| Pattern | Isolation | Operational effort | Best fit | Main risk |
|---|---|---|---|---|
| One Nginx edge, host-managed static sites and PHP-FPM pools | Separate roots and pools; shared kernel and host | Moderate | Teams wanting explicit, fast configuration | A host-level mistake can affect every site |
| One Apache edge with virtual hosts | Separate roots and virtual hosts | Moderate | CMS installations that rely on Apache conventions | Loose .htaccess or permissions can expose files or consume resources |
| Nginx edge proxying Apache applications | Separate edge and application layers | Higher | Existing Apache applications needing a proxy front end | Two configurations and logs must agree |
| Nginx or Apache edge with Docker Compose sites | Separate processes, networks, and volumes | Higher initially, repeatable later | Multiple CMS versions or teams needing reproducible deployments | Container and image maintenance can be neglected |
| Control-panel or automation-managed virtual hosts | Depends on the tool’s user and service model | Lower for repetitive setup | Operators prioritizing guided provisioning | Generated configuration may be less transparent during incidents |
Troubleshoot by following the request path
| Symptom | Likely cause | First checks |
|---|---|---|
| The wrong website appears | DNS points elsewhere, or the hostname is missing from the matching block | Resolve the hostname, inspect the active configuration, and test the exact Host header |
| 502 or 504 from the proxy | PHP-FPM, Apache, or a container is stopped or unreachable | Check service status, socket or upstream address, permissions, and application logs |
| Permalinks return 404 | Front-controller rewrite is absent or overrides are disabled | Check Nginx try_files or Apache rewrite and override settings |
| HTTPS certificate mismatch | The TLS block lacks a hostname or DNS still reaches the old server | Inspect certificate names, DNS answers, and the selected 443 server block |
| Uploads fail | The writable directory has wrong ownership, quota, or insufficient disk | Check effective service user, permissions, inode and disk usage, and CMS limits |
| All sites slow down together | Shared CPU, memory, database, storage, or backup contention | Compare resource graphs with request latency and pause or reschedule heavy jobs |
| Renewal fails | Port 80 is blocked, DNS changed, or the web-server configuration is invalid | Run a renewal dry run, validate configuration, and inspect the Certbot log |
When to split sites across VPSs
Move a site or service when measurements show sustained contention, not simply because the server hosts a certain number of domains. Split workloads when one CMS needs a different PHP or database version, when a noisy neighbor repeatedly consumes the shared pool, when a customer or team requires administrative isolation, or when maintenance windows cannot be coordinated.
A practical migration keeps DNS TTLs low before the change, copies files and a recent database dump, tests the new origin through a temporary hostname, freezes writes for the final database export, switches DNS, and watches logs and error rates. Keep the old origin available until caches expire and rollback criteria are met.
Quick Recap
Final implementation checklist
- Every domain has correct A and, where used, AAAA records.
- Each hostname maps to one documented server block or virtual host.
- Static roots, CMS code, uploads, logs, databases, and credentials are separated.
- Only ports 80 and 443 are publicly reachable by default.
- Dynamic services are reachable only from the edge or their private container network.
- HTTPS certificates cover every served name and renewal has been dry-run tested.
- Configuration validation and graceful reloads are part of deployment.
- Files, databases, proxy configuration, and service definitions have independent backups.
- A restoration rehearsal has produced a working site on a clean location.
- Monitoring measures per-site errors as well as shared CPU, memory, storage, and database pressure.
- Capacity decisions use observed workload and reserved headroom rather than a guessed site count.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

