NGINX reverse proxy to docker container running web app - node.js

On the host I have the docker container on port 4012, and in the docker container the webapp runs on port 3000 ( 0.0.0.0:4012->3000/tcp )
So to access the webapp i simply go to http://hostname:4012 and the webpage shows fine.
I want to be able to go to http://hostname/metrics to run the same webpage from my browser.
While I got this to work by simply adding a location to the nginx.conf on the host:
location /metrics {
proxy_pass http://localhost:4012;
}
All that loads is the index.html (I see the same html source code at http://localhost:4012 and http://hostname/metrics)
but the http://hostname/metrics does not load the javascript assets needed to run the webapp.
From developer tools I see the non proxied site loads assets like so:
http://hostname:4012/assets/styles.css
While the proxied version that goes to /metrics tries to load like this:
http://hostname/assets/styles.css
It doesn't append the /metrics to the assets like it does to get the index.html...
What am I missing here?
If it means anything, the webapp is running on a nodejs express server listening to port 3000 on the docker container.

You need to make the app work that way
location /metrics/ {
proxy_pass http://localhost:4012/;
sub_filter_once off;
sub_filter 'http://localhost:4012/' '$scheme://$host/metrics/';
sub_filter '<head>' '<head>\n<base href="hostname:4012">';
}
So adding a <base> tag to the html helps change /css to /metrics/css. Then absolute urls are also changed using sub_filter.

Related

Can't redirect traffic to localhost with nginx and docker

I'm new to Docker and nginx so this may be a simple question but I've been searching through question/answers for a while and haven't found the correct solution.
I'm trying to run an nginx server through docker to reroute all requests to my.example.com/api/... to localhost:3000/api/...
I have the following Dockerfile:
FROM nginx
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
and the nginx.conf file:
server {
server_name my.example.com;
location / {
proxy_pass http://localhost:3000/;
}
}
When I make the calls to the api on localhost:3000 this works fine but when I try to run against my.example.com I get a network error that the host isn't found. To be clear the domain I want to 'redirect' traffic from to localhost host is a valid server address, but I want to mock the api for it for development.
This isn't working because your nginx proxying request to localhost which is container itself but your app is running on host's port 3000 -- outside of container. check this article
change
proxy_pass http://localhost:3000/;
  to
proxy_pass http://host.docker.internal.
add 127.0.0.1 example.com my.example.com in etc/hosts

Deploying dynamic Nextjs + Nodejs application inside docker using caddy server

I am currently developing a simple portfolio app and my app structure is like this.
Nextjs/client,
Nodejs/server,
Mongodb/db
Nextjs is hosted locally on port 3001, Nodejs app on 5000. Whenever nextjs needs to fetch any api it calls nodejs application. All the things are configured inside docker. I am very new to deploying nextjs application and have recently used caddy server which has automatic https.
I am able to deploy the nextjs application statically using commands
next build
next export
The statically exported file called index.html inside out directory of nextjs application is pointed to caddy server on port 80 and 443. Statically exported app doesn't support api routes which I recently came to know. I tried next build and next start command to generate a dynamic production build inside .next directory. The main problem is How do I point my dynamically generated nextjs application in caddy configuration inside docker container. My present caddy configuration looks like
www.example.com:443 {
tls xyz#email.com
root * /srv
route {
reverse_proxy /api* api-server:5000
try_files {path} {path}/ /index.html
file_server
}
}
I am looking for hints especially related to proxy server.
Thank you in advance
I'm assuming the api url in your frontend looks like this http://localhost:5000 (based on your youtube comment here) which won't work if you're accessing your dockerized app from a remote computer (in this case your computer, since I'm assuming your app is hosted). Try changing it to https://www.example.com:5000 and rebuild your image.

How to setup Nginix Docker Reverse proxy

I am trying to use Nginix reverse proxy container for my web application(another docker container) which runs on non standard port ,
unfortunately I cannot edit my web application container as its developed by some vendor , so I have a plain request that I need to setup nginx as frontend with 80/443 and forward all requests to 10.0.0.0:10101(web app container).
I had tried jwilder/nginx proxy and default docker nginx container not able to get the right configurtaion .any lead would be great.
At the moment I haven't shared any conf files , I can share it on demand. here is the environment details
OS - Ubuntu
Azure
Use proxy_pass nginx feature
Assuming you have both containers linked and the web app container's name is webapp use this configuration on nginx container
upstream backend {
server webapp:10101;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
NOTE: please note that I am skipping some configurations as this is just an example
Put the configuration in nginx.conf file and then deploy the container like this
docker run -d -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf -p 80:80 nginx
Then you'll be able to access your webapp on http://locahost

how to config nginx docker container to recognize localhost application in different port?

Setup:
All following are running on my Mac OS:
localhost:8089 a nodejs REST api runing in my local, OUTSIDE of the nginx container, stand alone!
locahost:80 nginx docker container
I was able to serve static file inside the nginx docker container, but when I set the config for the nginx as:
http {
server {
location / {
root /usr/share/nginx/html;
}
location /api/ {
proxy_pass http://localhost:8089;
}
}
}
for some reason, any localhost:80/api call that suppose to direct to http://localhost:8089; call is returning 404 not found page
404 Not Found
nginx/1.13.6
Any idea where is the config I made wrong? I feel like maybe I shouldn't use localhost:8089 inside nginx? But then what should I be using?
An example can be found here
https://github.com/adamchenwei/docker-nginx-playground
Containers have their own networking namespace / networking stack. So localhost inside the container is the localhost of the container itself.
If you are running Docker for Mac, there is a special hostname that's available inside the container that allows you to connect to services that are running on the host itself. Refer to this answer for more information; https://stackoverflow.com/a/43541732/1811501
If you are running Docker on Linux, this answer (on the same question) allows you to find the IP-address to connect to; https://stackoverflow.com/a/31328031/1811501

Nginx + node.js configuration

I need the right configuration of nginx for my problem.
Suppose the nginx + nodejs serverprograms are running on the same debian machine.
Domain name for my website is for simplicity just webserver.com (and www.webserver.com as alias)
Now, when someone surfs on the internet to "webserver.com/" it should pass the request to the nodejs application which should run on a specific port like 3000 for example. But the images and css files should get served by nginx as static files and the filestructure should looke like webserver.com/images or webserver.com/css .. images + css should get served by nginx like a static server
Now it gets tricky:
But when someone surfs on webserver.com/staticsite001 or webserver.com/staticsite002 then it should get served by the nginx server only. no need for nodejs then.
And for the nodejs server, I am just setting up my nodejs application with port 3000 for example to receive the bypass from nginx for webserver.com/
to put it in a more understandable language: when someone surfs to webserver.com/staticsite001 it should NOT pass it to the node application. It should only pass it to the node application if its inside of the first webserver.com/ directory that the outsiders can see. The webserver.com/staticsite001 should only get serverd by nginx.
How, how do I do that ? And what should the http and server block look like for the nginx configuration look like?
I am familiar with nodejs. But I am new to nginx and new to reverse proxying.
thanks
the file structure on the debian hard drive looks like:
/home/wwwexample/staticsite001 (for www.webserver.com/staticsite001/) only handled by nginx
/home/wwwexample/staticsite002 (for www.webserver.com/staticiste002/) only handlex by nginx
/home/wwwexample/images
/home/wwwexample/css
and in
/home/nodeapplication is my node js application
This server block should work:
server {
listen 80;
server_name webserver.com www.webserver.com;
root /home/wwwexample;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
}
location /staticsite001 {
}
location /staticsite002 {
}
location /images {
}
location /css {
}
}
First location makes nginx to proxy everything to localhost:3000. Following empty locations instruct nginx to use default behavior, that is to serve static files.
Put this code into file /etc/nginx/sites-available/my-server and create a symlink to it in /etc/nginx/sites-enabled. There is a default config, which you could use as a reference.
After that you could use command sudo /usr/sbin/nginx -t to check configuration. If everything is OK use /etc/init.d/nginx reload to apply new configuration.

Resources