Host Multiple Websites On One Server: Apache & Nginx Guide

by Kenji Nakamura 59 views

Hey guys! So you've got yourself a VPS and you're looking to host multiple websites on it, right? That's awesome! It's totally doable, and in this guide, we'll walk you through how to set up two web servers, Apache and Nginx, to work together on a single machine. This setup is super useful for hosting a variety of websites, from PHP applications to Django projects, all on the same server. Let's dive in!

Why Use Two Web Servers?

Before we get into the nitty-gritty, let's quickly chat about why you might want to use two web servers instead of just one. Both Apache and Nginx are fantastic web servers, but they have different strengths:

  • Nginx: This guy is a performance beast. It's known for its ability to handle tons of concurrent connections with minimal resource usage. Nginx excels at serving static content (like images, CSS, and JavaScript files) and acting as a reverse proxy.
  • Apache: Apache, on the other hand, is super flexible and has a wealth of modules that can handle dynamic content processing, such as PHP. It's also very configurable, making it a great choice for applications that require more complex setups.

By using Nginx as a reverse proxy in front of Apache, you can leverage the strengths of both servers. Nginx can handle the static content and distribute requests efficiently, while Apache can take care of the dynamic content processing for your PHP and other applications. This combo can lead to improved performance, better resource utilization, and a more robust setup overall.

Setting Up the Web Servers

Alright, let's get down to the setup! We'll start by installing both Apache and Nginx on your VPS. I'm assuming you're using a Linux-based VPS (like Ubuntu or CentOS), so the commands might vary slightly depending on your distribution.

Installing Apache

First up, let's install Apache. Open up your terminal and run the following command:

sudo apt update # For Debian/Ubuntu
sudo apt install apache2

# OR

sudo yum update # For CentOS/RHEL
sudo yum install httpd

Once Apache is installed, it should start automatically. You can check its status by running:

sudo systemctl status apache2 # For Debian/Ubuntu

# OR

sudo systemctl status httpd # For CentOS/RHEL

Installing Nginx

Next, let's install Nginx. Use the following command:

sudo apt update # For Debian/Ubuntu
sudo apt install nginx

# OR

sudo yum update # For CentOS/RHEL
sudo yum install nginx

Similarly, you can check Nginx's status with:

sudo systemctl status nginx # For Debian/Ubuntu/CentOS/RHEL

Configuring Apache

Now that both servers are installed, we need to configure them to work together. The key is to have Nginx listen on port 80 (the standard HTTP port) and act as a reverse proxy, forwarding requests for dynamic content to Apache, which will be listening on a different port (like 8080).

First, let's configure Apache to listen on port 8080. Open the Apache ports configuration file:

sudo nano /etc/apache2/ports.conf # For Debian/Ubuntu

# OR

sudo nano /etc/httpd/conf/httpd.conf # For CentOS/RHEL

Find the line that says Listen 80 and change it to Listen 8080. Save the file and exit.

Next, you need to configure your virtual hosts in Apache to listen on port 8080 as well. For each virtual host configuration file (e.g., /etc/apache2/sites-available/domain.com.conf for Debian/Ubuntu or /etc/httpd/conf.d/domain.com.conf for CentOS/RHEL), make sure the <VirtualHost *:80> directive is changed to <VirtualHost *:8080>.

For example, a virtual host configuration might look like this:

<VirtualHost *:8080>
    ServerName domain.com
    DocumentRoot /var/www/domain.com
    <Directory /var/www/domain.com>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/domain.com_error.log
    CustomLog ${APACHE_LOG_DIR}/domain.com_access.log combined
</VirtualHost>

Don't forget to enable the virtual host if you haven't already:

sudo a2ensite domain.com.conf # For Debian/Ubuntu

# For CentOS/RHEL, you might need to create a symlink manually:
sudo ln -s /etc/httpd/conf.d/domain.com.conf /etc/httpd/conf.d/vhost.conf

After making these changes, restart Apache:

sudo systemctl restart apache2 # For Debian/Ubuntu

# OR

sudo systemctl restart httpd # For CentOS/RHEL

Configuring Nginx as a Reverse Proxy

Now for the fun part: configuring Nginx to act as a reverse proxy. We'll create server blocks (similar to virtual hosts in Apache) for each of your websites.

Open the default Nginx configuration file (you might want to create separate files for each domain later, but let's start with the default for simplicity):

sudo nano /etc/nginx/conf.d/default.conf # For CentOS/RHEL

# OR

sudo nano /etc/nginx/sites-available/default # For Debian/Ubuntu

Inside the file, you'll create a server block for each website. Here's an example configuration for domain.com:

server {
    listen 80;
    server_name domain.com www.domain.com;
    root /var/www/domain.com;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass 127.0.0.1:8080; # Forward PHP requests to Apache
    }

    location /phpmyadmin {
        proxy_pass http://127.0.0.1:8080/phpmyadmin; # Forward phpMyAdmin requests to Apache
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~ /\.ht {
        deny all;
    }

    access_log /var/log/nginx/domain.com.access.log;
    error_log /var/log/nginx/domain.com.error.log;
}

Let's break down this configuration:

  • listen 80;: Tells Nginx to listen for HTTP traffic on port 80.
  • server_name domain.com www.domain.com;: Specifies the domain names this server block should handle.
  • root /var/www/domain.com;: Sets the root directory for the website files.
  • index index.php index.html index.htm;: Defines the order in which index files should be served.
  • location / { ... }: This block handles most requests. The try_files directive tells Nginx to first try serving the requested URI as a file, then as a directory, and finally, if neither exists, to pass the request to index.php (which is common for PHP applications).
  • location ~ \.php$ { ... }: This block handles PHP requests. It includes the fastcgi-php.conf snippet (which contains common PHP FastCGI settings) and uses fastcgi_pass 127.0.0.1:8080; to forward the requests to Apache on port 8080.
  • location /phpmyadmin { ... }: This is where we handle the phpmyadmin subdomain. We use proxy_pass to forward requests to Apache, and we also set some headers to ensure Apache receives the correct information about the client's IP address.
  • location ~ /\.ht { ... }: This block denies access to .ht files (like .htaccess), which are often used for Apache-specific configurations and shouldn't be publicly accessible.
  • access_log and error_log: These directives specify the log files for this server block.

For your Django site (beta.domain.com), the configuration will be similar, but you'll need to use a different location block to handle the Django application. Assuming you're using Gunicorn to serve your Django app, the configuration might look something like this:

server {
    listen 80;
    server_name beta.domain.com;
    root /var/www/beta.domain.com;

    location / {
        proxy_pass http://127.0.0.1:8000; # Assuming Gunicorn is running on port 8000
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    access_log /var/log/nginx/beta.domain.com.access.log;
    error_log /var/log/nginx/beta.domain.com.error.log;
}

In this case, we're using proxy_pass to forward all requests to Gunicorn, which is running on port 8000. You'll need to make sure Gunicorn is properly configured to serve your Django application.

Repeat this process for each website you want to host, creating a new server block for each one. Don't forget to adjust the server_name, root, and other directives accordingly.

Once you've configured all your server blocks, save the file and restart Nginx:

sudo nginx -t # Test the configuration for syntax errors
sudo systemctl restart nginx

The nginx -t command is super handy for checking your configuration for any syntax errors before restarting the server. If there are any errors, Nginx will tell you where they are, making it easier to fix them.

Setting Up phpMyAdmin and phpPgAdmin

You also mentioned wanting to host phpMyAdmin and phpPgAdmin. We've already covered how to handle phpmyadmin in the Nginx configuration for domain.com. For phppgadmin (assuming you want it accessible under beta.domain.com/phppgadmin), you can add a similar location block to the beta.domain.com server block:

location /phppgadmin {
    proxy_pass http://127.0.0.1:8080/phppgadmin; # Forward phpPgAdmin requests to Apache
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Of course, you'll need to make sure phpPgAdmin is installed and configured to work with Apache. The specifics of this will depend on your distribution and how you've chosen to install phpPgAdmin.

Final Thoughts

And there you have it! You've now set up Apache and Nginx to work together on a single machine, allowing you to host multiple websites with different requirements. This setup can seem a bit complex at first, but once you get the hang of it, it's a powerful way to manage your web applications.

Remember, this is just a starting point. You can further optimize your setup by tweaking Nginx and Apache configurations, setting up caching, and implementing other performance-enhancing techniques. Don't be afraid to experiment and see what works best for your specific needs.

If you run into any issues, don't hesitate to consult the documentation for Apache and Nginx, or ask for help in online forums and communities. There are tons of resources available to help you get your web servers running smoothly.

Happy hosting, guys! You got this!