Running multiple projects on a single Ubuntu VPS requires proper virtual host configuration. This guide walks through setting up Apache virtual hosts and wiring in Git auto-pull for seamless deployments — a setup I use across client projects and personal servers.
Prerequisites
- Ubuntu 20.04 / 22.04 LTS
- Apache2 installed (
sudo apt install apache2) - Git installed (
sudo apt install git) - A domain pointing to your server’s IP
Step 1 — Create the Virtual Host Configuration
sudo nano /etc/apache2/sites-available/myproject.conf
Add the following configuration:
<VirtualHost *:80>
ServerName myproject.com
ServerAlias www.myproject.com
DocumentRoot /var/www/html/myproject/public
<Directory /var/www/html/myproject/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/myproject_error.log
CustomLog ${APACHE_LOG_DIR}/myproject_access.log combined
</VirtualHost>
Step 2 — Enable the Site and Reload Apache
sudo a2ensite myproject.conf
sudo a2enmod rewrite
sudo systemctl reload apache2
Step 3 — Clone Your Repository
cd /var/www/html/
git clone git@github.com:youruser/myproject.git
chown -R www-data:www-data myproject/
Step 4 — Git Webhook for Auto Pull
Create a PHP webhook endpoint that GitHub can call on every push:
<?php
// webhook.php — place this in your webroot
$secret = 'your-webhook-secret';
$payload = file_get_contents('php://input');
$signature = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($signature, $_SERVER['HTTP_X_HUB_SIGNATURE_256'])) {
http_response_code(403);
exit('Unauthorized');
}
$output = shell_exec('cd /var/www/html/myproject && git pull origin main 2>&1');
file_put_contents('/var/log/webhook.log', date('Y-m-d H:i:s') . ' ' . $output . PHP_EOL, FILE_APPEND);
echo 'OK';
Step 5 — Add Webhook in GitHub
Go to your repo Settings > Webhooks > Add webhook. Set the Payload URL to https://yourdomain.com/webhook.php, Content type to application/json, and add your secret. Select “Just the push event”.
Every push to your repository now triggers an automatic pull on your server. No more manual deploys.