Running multiple web applications on a single Ubuntu server is a smart way to save costs and simplify management — especially if you’re combining apps built with different tech stacks, like PHP and Java.
In this post, we’ll walk you through running a PHP web app and a Java-based Metabase instance on the same Ubuntu server, using Apache as the front-facing web server and SSL secured via your own certificate or Let’s Encrypt.
What We’ll Achieve
- ✅ Run a PHP site using Apache
(e.g. https://app.example.com)
- ✅ Run a Java app like Metabase
(e.g. https://metabase.example.com)
- ✅ Use Apache as a reverse proxy for the Java app
- ✅ Secure both apps with SSL
1. Prerequisites
- Ubuntu 22.04+ server
- Apache installed:
sudo apt install apache2 -y
- Domain(s) pointed to your server (A-records)
- PHP installed for your web app
sudo apt install php libapache2-mod-php -y
- Java installed for Metabase
sudo apt install openjdk-17-jdk -y
(or higher) - Metabase
.jar
file
2. Set Up the PHP App (app.example.com)
Create a directory for your PHP app:
sudo mkdir -p /sites/web/app.example.com
sudo chown -R $USER:www-data /sites/web/app.example.com
Create a virtual host config:
sudo nano /etc/apache2/sites-available/app.example.com.conf
Paste:
ServerName app.example.com
DocumentRoot "/sites/web/app.example.com"
ErrorLog "/sites/logs/app-error_log"
CustomLog "/sites/logs/app-access_log" combined
Enable the site:
sudo a2ensite app.example.com.conf
sudo systemctl reload apache2
Then place your PHP files in /sites/web/app.example.com/
and verify it works via browser.
3. Run Metabase (Java App on Port 3000)
Download the Metabase JAR, then run:
nohup java -jar metabase.jar > metabase.log 2>&1 &
Check if it’s running:
sudo ss -tulpn | grep 3000
You should see java
listening on *:3000
.
4. Configure Apache Reverse Proxy for Metabase
Let’s assume you want to serve Metabase at https://metabase.example.com
.
Create Apache config:
sudo nano /etc/apache2/sites-available/metabase.example.com.conf
Paste this SSL-ready reverse proxy config:
ServerName metabase.example.com
Redirect permanent / https://metabase.example.com/
ServerName metabase.example.com
SSLEngine on
SSLCertificateFile /sites/SSL/certificate.crt
SSLCertificateKeyFile /sites/SSL/private.key
SSLCertificateChainFile /sites/SSL/ca_bundle.crt
ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ErrorLog "/sites/logs/metabase-error_log"
CustomLog "/sites/logs/metabase-access_log" combined
Note: Replace the SSL file paths with your actual certificate files.
Enable the site and required modules:
sudo a2enmod proxy proxy_http headers ssl
sudo a2ensite metabase.example.com.conf
sudo systemctl reload apache2
5. Add Free SSL (Two Options)
You can secure your apps with HTTPS using either of these methods:
Option 1: Use Let’s Encrypt with Certbot (Automatic)
If you prefer automation and easy renewal:
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d metabase.example.com -d app.example.com
This will automatically configure SSL and set up renewal for you.
Option 2: Use SSLsForFree.com (Manual)
Prefer to generate certificates manually?
- Visit https://www.sslsforfree.com
- Enter your domain (e.g.,
metabase.example.com
) - Follow instructions for DNS or file-based validation
- Download the certificate files:
certificate.crt
ca_bundle.crt
private.key
- Save them to your server, e.g.:
/sites/SSL/metabase/certificate.crt
/sites/SSL/metabase/ca_bundle.crt
/sites/SSL/metabase/private.key - Update your Apache config like so:
SSLCertificateFile /sites/SSL/metabase/certificate.crt
SSLCertificateKeyFile /sites/SSL/metabase/private.key
SSLCertificateChainFile /sites/SSL/metabase/ca_bundle.crt - Reload Apache:
sudo systemctl reload apache2
Now your Metabase (and PHP app) will be accessible securely via HTTPS.
Final Check
Visit https://app.example.com
→ You should see your PHP app
Visit https://metabase.example.com
→ You should see Metabase UI, proxied securely
Conclusion
With Apache’s reverse proxy and a bit of configuration, it’s easy to host multiple apps (even in different languages) on a single server. Whether you’re bootstrapping a startup or managing internal tools, this approach is both efficient and production-ready.
Let us know in the comments — are you running other combinations like Node.js + PHP, or Java + Python?