// ── Nginx Proxy Manager ───────────────────────────────────────────────────────
async function nginxProxy() {
const [statusR, hostsR] = await Promise.all([
Nova.api('proxy', 'status'),
Nova.api('proxy', 'hosts'),
]);
const s = statusR?.data || {};
const hosts = hostsR?.data || (Array.isArray(hostsR) ? hostsR : []);
const run = s.running;
const inst = s.installed;
return `
Nginx Status
${inst ? (run ? 'Running' : 'Stopped') : 'Not Installed'}
${s.version || (inst ? 'nginx' : 'click Install to set up')}
Proxy Hosts
${hosts.length}
${hosts.filter(h => h.enabled).length} active
SSL Enabled
${hosts.filter(h => h.ssl_enabled).length}
of ${hosts.length} hosts
${!inst ? `
Nginx Not Installed
Install Nginx on this VM to use it as a reverse proxy in front of Apache, or use a separate proxy VM (see Setup Guide).
` : `
${hosts.length === 0 ? `
No proxy hosts yet. Click Sync Accounts to auto-add all hosted domains, or + Add Host to add manually.
` : `
| Domain |
Upstream |
SSL |
Status |
Actions |
${hosts.map(h => `
| ${Nova.escHtml(h.domain)} |
${Nova.escHtml(h.upstream)} |
${h.ssl_enabled ? Nova.badge('SSL','green') : Nova.badge('HTTP','muted')} |
${h.enabled ? Nova.badge('Active','green') : Nova.badge('Disabled','red')} |
|
`).join('')}
`}
`}`;
}
window.proxyInstall = async () => {
if (!confirm('Install Nginx on this VM? This will run apt-get install nginx.')) return;
Nova.toast('Installing nginx...', 'info');
const r = await Nova.api('proxy', 'install', { method: 'POST' });
Nova.toast(r?.data?.result || r?.message || 'Done', r?.data?.result === 'installed' ? 'success' : 'info');
Nova.loadPage('nginx-proxy', window._novaPages);
};
window.proxyControl = async (action) => {
const r = await Nova.api('proxy', 'control', { method: 'POST', body: { action } });
Nova.toast(r?.data?.result || r?.message || action + ' done', 'success');
setTimeout(() => Nova.loadPage('nginx-proxy', window._novaPages), 800);
};
window.proxySync = async () => {
const r = await Nova.api('proxy', 'sync', { method: 'POST' });
Nova.toast(`Synced: ${r?.data?.added ?? 0} new hosts added`, 'success');
Nova.loadPage('nginx-proxy', window._novaPages);
};
window.proxyAddHost = () => {
Nova.modal('Add Proxy Host', `
e.g. http://127.0.0.1:80 or http://10.0.0.2:8080
`, async () => {
const domain = document.getElementById('ph-domain')?.value?.trim();
const upstream = document.getElementById('ph-upstream')?.value?.trim();
if (!domain || !upstream) { Nova.toast('Domain and upstream required', 'error'); return; }
const r = await Nova.api('proxy', 'hosts', {
method: 'POST',
body: { domain, upstream, ssl_enabled: document.getElementById('ph-ssl')?.checked ? 1 : 0 }
});
Nova.toast(r?.success ? 'Host added' : (r?.message || 'Failed'), r?.success ? 'success' : 'error');
if (r?.success) Nova.loadPage('nginx-proxy', window._novaPages);
});
};
window.proxyEditHost = async (id) => {
const hostsR = await Nova.api('proxy', 'hosts');
const hosts = hostsR?.data || (Array.isArray(hostsR) ? hostsR : []);
const h = hosts.find(x => x.id == id);
if (!h) return;
Nova.modal('Edit Proxy Host', `
Leave blank to use auto-generated config
`, async () => {
const r = await Nova.api('proxy', `hosts/${id}`, {
method: 'PUT',
body: {
domain: document.getElementById('phe-domain')?.value?.trim(),
upstream: document.getElementById('phe-upstream')?.value?.trim(),
ssl_enabled: document.getElementById('phe-ssl')?.checked ? 1 : 0,
custom_config: document.getElementById('phe-custom')?.value?.trim() || null,
}
});
Nova.toast(r?.success ? 'Updated' : (r?.message || 'Failed'), r?.success ? 'success' : 'error');
if (r?.success) Nova.loadPage('nginx-proxy', window._novaPages);
});
};
window.proxyToggle = async (id, enable) => {
const r = await Nova.api('proxy', `hosts/${id}/toggle`, { method: 'POST', body: { enabled: enable } });
Nova.toast(r?.success ? (enable ? 'Enabled' : 'Disabled') : 'Failed', r?.success ? 'success' : 'error');
if (r?.success) Nova.loadPage('nginx-proxy', window._novaPages);
};
window.proxyDeleteHost = (id, domain) => {
Nova.confirm(`Delete proxy host for ${domain}?`, async () => {
const r = await Nova.api('proxy', `hosts/${id}`, { method: 'DELETE' });
Nova.toast(r?.success ? 'Deleted' : 'Failed', r?.success ? 'success' : 'error');
if (r?.success) Nova.loadPage('nginx-proxy', window._novaPages);
}, true);
};
window.proxySetupInstructions = async () => {
const scriptUrl = '/api/proxy/setup-script';
Nova.modal('Nginx Proxy Setup Guide', `
Option A — Local (Nginx on this VM)
Install Nginx alongside Apache on this VM. Nginx listens on ports 80/443 and forwards to Apache. Best for SSL termination and caching.
- Click Install Nginx Locally on the main Nginx Proxy page
- Move Apache to port 8080: edit
/etc/apache2/ports.conf → change Listen 80 to Listen 8080
- Update upstream in all proxy hosts to
http://127.0.0.1:8080
- Click Sync Accounts to auto-populate proxy hosts from your hosted accounts
- Click Reload Config to apply changes
Option B — Remote Proxy VM (Recommended for production)
Run a dedicated Nginx proxy VM in front of this NovaCPX VM. Traffic flows: Internet → FortiGate → Nginx Proxy VM → NovaCPX VM (Apache).
- Create a new VM on Proxmox (Ubuntu 22.04, 1 vCPU, 1GB RAM)
- Run the setup script below on the new VM as root
- Point FortiGate VIPs to the proxy VM IP (ports 80/443)
- Set the proxy upstream to this NovaCPX VM IP (
http://10.48.200.110:80)
- Add proxy hosts for each domain from your NovaCPX admin panel
Automated Setup Script
Run this on the target VM (local or remote) as root:
curl -sk https://YOUR_NOVACPX_IP:8882/api/proxy/setup-script | bash
Or download and review before running:
curl -sk https://YOUR_NOVACPX_IP:8882/api/proxy/setup-script -o proxy-setup.sh
cat proxy-setup.sh # review
bash proxy-setup.sh
Integration with VirtualHost Manager
When proxy mode is active, NovaCPX automatically:
- Creates a proxy host entry for every new account
- Removes the proxy host when an account is terminated
- Re-generates Nginx config on every account change
- Uses account SSL certs automatically if SSL is enabled on the proxy host
`, null, { cancelLabel: 'Close', showConfirm: false });
};