Tools: How to Host Multiple Websites on a Single VPS

Tools: How to Host Multiple Websites on a Single VPS

Understanding the Foundation: What is a VPS?

Why Host Multiple Websites on a Single VPS?

Essential Software for Multi-Website Hosting

Setting Up Your VPS: A Step-by-Step Approach

1. Update Your System

2. Install the Nginx Web Server

3. Install a Database Server (MariaDB)

4. Install PHP

5. Configure Nginx for Multiple Websites (Server Blocks)

5.1. Create Website Directories

5.2. Set Permissions

5.3. Create Sample Index Files

5.4. Create Nginx Server Block Configuration Files

5.5. Enable the Server Blocks

5.6. Test Nginx Configuration and Reload

6. Configure DNS Records

7. Setting Up SSL/TLS Certificates (HTTPS)

8. Managing Databases for Each Website Are you looking to maximize your budget and server resources by hosting multiple websites on one Virtual Private Server (VPS)? This guide will walk you through the essential steps and considerations to set up your VPS for efficient multi-website hosting. You'll learn how to configure your server to serve different domains from a single IP address, making it a cost-effective solution for developers and small businesses. Before we dive into hosting multiple sites, let's clarify what a Virtual Private Server (VPS) is. Think of a physical server as a large building. A VPS is like renting out an entire apartment within that building. You get your own dedicated space with guaranteed resources (CPU, RAM, storage), but you share the underlying physical hardware with other tenants. This offers more control and performance than shared hosting, where you're just a room in a shared house. A VPS provides you with root access, meaning you have administrative control over your server environment. This level of access is crucial for installing and configuring the software needed to host multiple websites. The primary driver for hosting multiple websites on one VPS is cost-efficiency. Instead of paying for several separate hosting plans, you consolidate your needs onto a single, more powerful server. This can significantly reduce your monthly hosting expenses. Beyond cost, a single VPS can offer simplified management. Imagine having one control panel or one server to update and monitor, rather than juggling multiple accounts. This can save valuable time and reduce the potential for errors. Finally, it allows for resource consolidation. If one website experiences a surge in traffic, the VPS can often handle it better than a resource-limited shared hosting plan. You also have the flexibility to allocate resources as needed across your hosted sites. To host multiple websites, your VPS will need a few key pieces of software. We'll focus on the most common and robust combination: the LAMP stack. You'll also need a way to manage these services and configure your web server to direct traffic to the correct website. This is where virtual hosts (or server blocks in Nginx terminology) come into play. This section assumes you have a fresh VPS instance running a Linux distribution like Ubuntu. You should have SSH access to your server. The first and most crucial step is to ensure your server's software packages are up to date. This helps patch security vulnerabilities and ensures you have the latest features. This command first updates the list of available packages and their versions (apt update) and then installs any available upgrades (apt upgrade). The -y flag automatically answers "yes" to any prompts. Nginx is a high-performance web server. You can install it with a simple command: Once installed, you can check its status: You should see output indicating that Nginx is active and running. You can also test it by visiting your VPS's IP address in a web browser. You should see the default Nginx welcome page. For this example, we'll install MariaDB, a popular open-source relational database management system. After installation, it's a good practice to run the security script: This script will guide you through setting a root password for the database, removing anonymous users, disallowing root login remotely, and removing the test database. PHP is essential for dynamic websites. We'll install PHP and a few common extensions that are often needed. You can check your installed PHP version with: This is where the magic of hosting multiple sites on one VPS happens. Nginx uses server blocks (similar to Apache's virtual hosts) to manage different domains on the same IP address. Each server block defines how Nginx should handle requests for a specific domain. Let's say you want to host website1.com and website2.com. First, create directories to store the files for each website. Grant ownership of these directories to your regular user (replace your_user with your actual username) and set appropriate permissions. Create a simple index.html file for each website to test the configuration. Add the following content: Save and exit (Ctrl+X, Y, Enter). Add the following content: Now, create a separate configuration file for each website within Nginx's sites-available directory. Paste the following configuration, adjusting server_name and root as needed: Paste a similar configuration, changing server_name and root: Important Note: The fastcgi_pass line might need to be adjusted based on your installed PHP version. You can find the correct socket path by looking in /run/php/. To activate these configurations, you need to create symbolic links from sites-available to sites-enabled. Before reloading Nginx, it's vital to test your configuration for syntax errors. If the test is successful, you'll see messages like: If there are errors, the output will tell you where to look. Once the test passes, reload Nginx to apply the changes: For your websites to be accessible on the internet, you need to configure the DNS (Domain Name System) records for website1.com and website2.com. You'll need to point the A records for both website1.com and www.website1.com to your VPS's IP address. Do the same for website2.com. This is typically done through your domain registrar's control panel. Securing your websites with HTTPS is no longer optional. We'll use Let's Encrypt and Certbot to easily obtain and install free SSL/TLS certificates. First, install Certbot: Now, request certificates for your domains. Certbot will automatically modify your Nginx configuration files. Follow the prompts. Certbot will ask if you want to redirect HTTP traffic to HTTPS. It's generally recommended to choose the redirect option. Certbot will also set up automatic renewal for your certificates. You can test the renewal process with: After this step, your websites should be accessible via HTTPS. Each website will likely need its own database. You can create them using the MariaDB command line. Enter the root password you set during mysql_secure_installation. Create a database and user for website1.com: Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

$ -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update && -weight: 600;">sudo -weight: 500;">apt -weight: 500;">upgrade -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update && -weight: 600;">sudo -weight: 500;">apt -weight: 500;">upgrade -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update && -weight: 600;">sudo -weight: 500;">apt -weight: 500;">upgrade -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install nginx -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install nginx -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install nginx -y -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status nginx -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status nginx -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status nginx -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mariadb-server -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mariadb-server -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install mariadb-server -y -weight: 600;">sudo mysql_secure_installation -weight: 600;">sudo mysql_secure_installation -weight: 600;">sudo mysql_secure_installation -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php-fpm php-mysql php-mbstring php-xml php--weight: 500;">curl -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php-fpm php-mysql php-mbstring php-xml php--weight: 500;">curl -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install php-fpm php-mysql php-mbstring php-xml php--weight: 500;">curl -y -weight: 600;">sudo mkdir -p /var/www/website1.com/public_html -weight: 600;">sudo mkdir -p /var/www/website2.com/public_html -weight: 600;">sudo mkdir -p /var/www/website1.com/public_html -weight: 600;">sudo mkdir -p /var/www/website2.com/public_html -weight: 600;">sudo mkdir -p /var/www/website1.com/public_html -weight: 600;">sudo mkdir -p /var/www/website2.com/public_html -weight: 600;">sudo chown -R your_user:www-data /var/www/website1.com -weight: 600;">sudo chown -R your_user:www-data /var/www/website2.com -weight: 600;">sudo chmod -R 755 /var/www/website1.com -weight: 600;">sudo chmod -R 755 /var/www/website2.com -weight: 600;">sudo chown -R your_user:www-data /var/www/website1.com -weight: 600;">sudo chown -R your_user:www-data /var/www/website2.com -weight: 600;">sudo chmod -R 755 /var/www/website1.com -weight: 600;">sudo chmod -R 755 /var/www/website2.com -weight: 600;">sudo chown -R your_user:www-data /var/www/website1.com -weight: 600;">sudo chown -R your_user:www-data /var/www/website2.com -weight: 600;">sudo chmod -R 755 /var/www/website1.com -weight: 600;">sudo chmod -R 755 /var/www/website2.com -weight: 600;">sudo nano /var/www/website1.com/public_html/index.html -weight: 600;">sudo nano /var/www/website1.com/public_html/index.html -weight: 600;">sudo nano /var/www/website1.com/public_html/index.html <!DOCTYPE html> <html> <head> <title>Welcome to website1.com!</title> </head> <body> <h1>Success! The website1.com server block is working!</h1> </body> </html> <!DOCTYPE html> <html> <head> <title>Welcome to website1.com!</title> </head> <body> <h1>Success! The website1.com server block is working!</h1> </body> </html> <!DOCTYPE html> <html> <head> <title>Welcome to website1.com!</title> </head> <body> <h1>Success! The website1.com server block is working!</h1> </body> </html> -weight: 600;">sudo nano /var/www/website2.com/public_html/index.html -weight: 600;">sudo nano /var/www/website2.com/public_html/index.html -weight: 600;">sudo nano /var/www/website2.com/public_html/index.html <!DOCTYPE html> <html> <head> <title>Welcome to website2.com!</title> </head> <body> <h1>Success! The website2.com server block is working!</h1> </body> </html> <!DOCTYPE html> <html> <head> <title>Welcome to website2.com!</title> </head> <body> <h1>Success! The website2.com server block is working!</h1> </body> </html> <!DOCTYPE html> <html> <head> <title>Welcome to website2.com!</title> </head> <body> <h1>Success! The website2.com server block is working!</h1> </body> </html> -weight: 600;">sudo nano /etc/nginx/sites-available/website1.com -weight: 600;">sudo nano /etc/nginx/sites-available/website1.com -weight: 600;">sudo nano /etc/nginx/sites-available/website1.com server { listen 80; listen [::]:80; server_name website1.com www.website1.com; root /var/www/website1.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } server { listen 80; listen [::]:80; server_name website1.com www.website1.com; root /var/www/website1.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } server { listen 80; listen [::]:80; server_name website1.com www.website1.com; root /var/www/website1.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } -weight: 600;">sudo nano /etc/nginx/sites-available/website2.com -weight: 600;">sudo nano /etc/nginx/sites-available/website2.com -weight: 600;">sudo nano /etc/nginx/sites-available/website2.com server { listen 80; listen [::]:80; server_name website2.com www.website2.com; root /var/www/website2.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } server { listen 80; listen [::]:80; server_name website2.com www.website2.com; root /var/www/website2.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } server { listen 80; listen [::]:80; server_name website2.com www.website2.com; root /var/www/website2.com/public_html; index index.html index.htm index.nginx-debian.html; location / { try_files $uri $uri/ =404; } # Pass PHP scripts to FastCGI server location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust PHP version if necessary fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } } -weight: 600;">sudo ln -s /etc/nginx/sites-available/website1.com /etc/nginx/sites-enabled/ -weight: 600;">sudo ln -s /etc/nginx/sites-available/website2.com /etc/nginx/sites-enabled/ -weight: 600;">sudo ln -s /etc/nginx/sites-available/website1.com /etc/nginx/sites-enabled/ -weight: 600;">sudo ln -s /etc/nginx/sites-available/website2.com /etc/nginx/sites-enabled/ -weight: 600;">sudo ln -s /etc/nginx/sites-available/website1.com /etc/nginx/sites-enabled/ -weight: 600;">sudo ln -s /etc/nginx/sites-available/website2.com /etc/nginx/sites-enabled/ -weight: 600;">sudo nginx -t -weight: 600;">sudo nginx -t -weight: 600;">sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful -weight: 600;">sudo -weight: 500;">systemctl reload nginx -weight: 600;">sudo -weight: 500;">systemctl reload nginx -weight: 600;">sudo -weight: 500;">systemctl reload nginx -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-nginx -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-nginx -y -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install certbot python3-certbot-nginx -y -weight: 600;">sudo certbot --nginx -d website1.com -d www.website1.com -d website2.com -d www.website2.com -weight: 600;">sudo certbot --nginx -d website1.com -d www.website1.com -d website2.com -d www.website2.com -weight: 600;">sudo certbot --nginx -d website1.com -d www.website1.com -d website2.com -d www.website2.com -weight: 600;">sudo certbot renew --dry-run -weight: 600;">sudo certbot renew --dry-run -weight: 600;">sudo certbot renew --dry-run -weight: 600;">sudo mysql -u root -p -weight: 600;">sudo mysql -u root -p -weight: 600;">sudo mysql -u root -p sql CREATE DATABASE website1_db; CREATE USER 'website1_user'@'localhost' IDENTIFIED BY 'your_strong_ sql CREATE DATABASE website1_db; CREATE USER 'website1_user'@'localhost' IDENTIFIED BY 'your_strong_ sql CREATE DATABASE website1_db; CREATE USER 'website1_user'@'localhost' IDENTIFIED BY 'your_strong_ - Linux: The operating system. Most VPS providers offer various Linux distributions like Ubuntu, CentOS, or Debian. We'll assume you're using a popular choice like Ubuntu. - Apache or Nginx: The web server. This software is responsible for receiving requests from visitors' browsers and sending back the website's content. Nginx is often favored for its performance and efficiency, especially with static content and high traffic. Apache is also very capable and widely used. For this guide, we'll use Nginx as it's a popular choice for modern VPS setups. - MySQL/MariaDB: The database server. Websites often store data like user information, blog posts, or product details in a database. MySQL and its fork, MariaDB, are popular choices. - PHP: The server-side scripting language. PHP is used to create dynamic web pages, interact with databases, and process user input. - php-fpm: FastCGI Process Manager, which is how Nginx communicates with PHP. - php-mysql: Allows PHP to connect to MySQL/MariaDB databases. - php-mbstring: Handles multi-byte strings, crucial for internationalization. - php-xml: For working with XML data. - php--weight: 500;">curl: For making HTTP requests from PHP.