Hello community,
I’ve created a Node.js application that currently runs on port 9000. Right now, I can access it at:
mydomain.com:9000/api
However, I want to configure it so that:
- I don’t need to open port 9000 in my firewall
- Users can access it directly at:
mydomain.com/api
- Keep my current Nginx + Apache2 setup intact
Current Setup:
What I’ve Tried:
I understand this requires configuring Nginx as a reverse proxy to forward requests from /api to localhost:9000, but I’m not sure how to properly configure this with my existing Nginx + Apache2 setup.
I attempted to create a custom web template for my Node.js application by creating .tpl and .stpl files in /usr/local/hestia/data/templates/web/nginx/, but when I try to apply the template using:
bash
v-change-web-domain-tpl user domain.com nodejs-template
I get the error: “nodejs-template web template doesn’t exist” even though the files are present with correct permissions.
Questions:
- How should I configure the Nginx location block for
/api requests?
- Will this interfere with my existing Apache2 configuration?
- Should I handle this at the Nginx level or Apache2 level?
- Any security considerations I should be aware of?
Environment:
- Operating System: Linux
- Web Server: Nginx + Apache2
- Application: Node.js (Express)
- Control Panel: HestiaCP (if relevant)
Any guidance or configuration examples would be greatly appreciated! I want to ensure I’m following best practices for security and performance.
Thanks in advance for your help!
HestiaCP Custom Nginx Proxy Template Tutorial
I managed to solve this issue, and I’m sharing here a simple step-by-step approach on how to resolve it correctly.
1 - Creating the Template
Create the HTTP template file:
vim /usr/local/hestia/data/templates/web/nginx/myproject-3001.tpl
File content (make sure to change the naming and port):
# Custom PM2 Template for HTTP
server {
listen %ip%:80;
server_name %domain_idn% %alias_idn%;
error_log /var/log/%web_system%/domains/%domain%.error.log error;
location ~ /\.(?!well-known\/|file) {
deny all;
return 404;
}
location / {
proxy_pass http://127.0.0.1:3001; # Internal app port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # WebSocket support
proxy_set_header Connection "upgrade"; # WebSocket support
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /error/ {
alias %home%/%user%/web/%domain%/document_errors/;
}
include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}
2 - Creating the HTTPS Template
Now let’s create the HTTPS modification:
vim /usr/local/hestia/data/templates/web/nginx/myproject-3001.stpl
File content (make sure to change the naming and port):
# Custom PM2 Template for HTTPS
server {
listen %ip%:443 ssl;
server_name %domain_idn% %alias_idn%;
error_log /var/log/%web_system%/domains/%domain%.error.log error;
ssl_certificate %ssl_pem%;
ssl_certificate_key %ssl_key%;
ssl_stapling on;
ssl_stapling_verify on;
location ~ /\.(?!well-known\/|file) {
deny all;
return 404;
}
location / {
proxy_pass https://127.0.0.1:3001; # Internal app port (adjust as needed)
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # WebSocket support
proxy_set_header Connection "upgrade"; # WebSocket support
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /error/ {
alias %home%/%user%/web/%domain%/document_errors/;
}
include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
3 - Restart Nginx
After doing this, restart nginx:
service nginx restart
4 - Apply the Template
That’s it! Now you just need to choose the template by editing the domain in proxy model.
Hope this helps!
This is great that you solved your own problem! My solution would’ve been to actually use Cloudflare Tunnels. That instead of worrying about all this, you can just install Cloudflare Tunnel on your server and then configure the hostname using Cloudflare zero trust dashboard and without opening the port.
Thank you so much for the tip. The bigger issue is that all my DNS records are tied to government entities, so switching to Cloudflare would be a bit messy—I depend not only on third parties but also on the government, lol.
But thank you anyway. I’m sure your approach is much simpler, and I’m certain our thread will help a lot of people who are dealing with this headache, lol.
oh! Govt
Yes - I hear you man!
I completely agree, your solution is definitely more useful when one can’t depend on third party solutions like Cloudflare.