Can Nxingx do Reverse Proxy updates without downtime - nginx

I have nginx that I am using to receive traffic for multiple domains on port 80 each with upstream to different application servers on application specific ports
e.g
abc.com:80 --> :3345
xyz.com:80 --> :3346
Is it possible to
1. add/delete domains (abc/xyz) without downtime
2. change application level port mapping (3345,3346) without downtime
If nginx can't do it, is there any other service that can do it without restarting the service and incurring downtime ?
Thanks in advance

In short: Yes.
Typically, you'd overwrite the existing config file(s) in place while nginx is running, test it using nginx -t and once everything is fine, reload nginx using nginx -s reload. This will cause nginx to spawn new worker processes which use your new config while old worker processes are being shut down gracefully.. Graceful means closing listen sockets while still serving currently active connections. Every new request/connection will use the new config.
Note that in case nginx is not able to parse the new config file(s), the old config will stay in place.

Related

Nginx if flask app not running redirect to different url

Some times flask app server may not be running which the page will just say server not reached. Is there any way we can have Nginx to redirect to different url if flask app is not able to be reached
This kind of dynamic change of proxying is not possible in Nginx directly. One way you could do is by having a dedicated service(application) that takes care of this by polling your primary flask endpoint at regular intervals.
If the is a negatory response then your service could simply change the nginx config and then send a HUP signal to the nginx process which in turn reloads nginx with the newly available config. This method is pretty efficient and fast.
In case you are making this service in Python, you could use signals library to send the signal to nginx master process and also the nginxparser library to play around with the nginx config

Looking up a container's address via its hostname dynamically in Nginx

I'm currently trying to run two containers on a single host, one being an application (Ruby on Rails) and the other Nginx as a reverse proxy and cache. The app is running on TCP port 80. What I want to be able to do is bring down my application container, remove it and then bring it up again without having to restart nginx. The problem is that Nginx only seems to look up the IP of the container once, so if it goes down then back up at a different address then Nginx will just complain that there's nothing there.
I've tried a few things:
Using resolver 127.0.0.11 valid=5 to use Docker's DNS
Using an upstream block
Using a variable to try to get nginx to resolve at runtime.
I'm not sure where else to look but none of these options work if the application is brought up on a different IP address. Is there something I'm missing making this impossible?
Thanks.
Ended up reading through the 12 factor app which inspired me to remove the Nginx proxying to Rails upstream altogether, and instead used it as a proxy cache which has an upstream of the external DNS name.

How to keep the session when using nginx as the Reverse Proxy to many servers with unsame project

I am new to Nginx. And I have trobule with it. We have many projects with different language and framework. And they are put in different server. How do I keep the session for every project respectively?
Question is not quite clear but from what i understood i will try to guide you a bit...
Nginx is a web server which when used as reverse proxy basically just sits in front of your project appserver. When some client tries to connect to your appserver, it will first connect to nginx and then nginx will forward that request to you appserver.
eg.
client -Req-> nginx (port 8080) -Req-> appserver(jetty, port 9000)
Now if you are trying to use a single nginx instance and direct request to multiple app servers from nginx. You will either have to make nginx listen on different ports and forward them to different appservers. Or nginx can identify which request is meant for which appserver by routes.
Here is a source which can help you to learn how to configure Nginx to do this... please ask again if you need further help.
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts

can I configure ngnix anyways other than through the normal ngnix.conf file

Is there any way I can configure ngnix other than through the normal ngnix.conf file ?
Like xml configuration or memcache or any other ways..?
My objective is to add/remove upstreams to the configuration dynamically. Ngnix doesnt seem to have a direct solution for this so I was planning to play with the configuration file, but I am finding it very difficult and error prone to modify the file through script/programs.
Any suggestions ?
No. You can't. The only way to "dynamically" reconfigure nginx is to process the config files in external software and then reload the server. Neither you can "program" config like in Apache. The nginx config is mostly a static thing which is praised for its performance.
Source: I needed it too, done some research.
Edit: I have a "supervising" tool installed on my hosts that monitors load and clusters and such. I've ended up implementing the upstreams scaling through it. Whenever a new upstream is ready, it notifies my "supervisor" on all web servers. The "supervisors" then query for served "virtual hosts" on the new upstream and add all of them to their context on the nginx host. then it just nginx -t && nginx -s reload everything. This is for nginx fastcgiing to php-fpms.
Edit2: I have many server blocks for different server_names (sites), each has an upstream associated to it on another host(s). In the server block I have include /path/to/where/my/upstream/configs/are/us-<unique_site_id>.conf line. the us-<unique_site_id>.conf is generated when the server block is created and populated with existing upstream(s) information. When there are changes in the upstreams pool or the site configuration, the file is rewritten to reflect it.

docker registry on localhost with nginx proxy_pass

I'm trying to setup a private docker registry to upload my stuff but I'm stuck. The docker-registry instance is running on port 5000 and I've setup nginx in front of it with a proxy pass directive to pass requests on port 80 back to localhost:5000.
When I try to push my image I get this error:
Failed to upload metadata: Put http://localhost:5000/v1/images/long_image_id/json: dial tcp localhost:5000: connection refused
If I change localhost with my server's ip address in nginx configuration file I can push allright. Why would my local docker push command would complain about localhost when localhost is being passed from nginx.
Server is on EC2 if it helps.
I'm not sure the specifics of your traffic, but I spent a lot of time using mitmproxy to inspect the dataflows for Docker. The Docker registry is actually split into two parts, the index and the registry. The client contacts the index to handle metadata, and then is forwarded on to a separate registry to get the actual binary data.
The Docker self-hosted registry comes with its own watered down index server. As a consequence, you might want to figure out what registry server is being passed back as a response header to your index requests, and whether that works with your config. You may have to set up the registry_endpoints config setting in order to get everything to play nicely together.
In order to solve this and other problems for everyone, we decided to build a hosted docker registry called Quay that supports private repositories. You can use our service to store your private images and deploy them to your hosts.
Hope this helps!
Override X-Docker-Endpoints header set by registry with:
proxy_hide_header X-Docker-Endpoints;
add_header X-Docker-Endpoints $http_host;
I think the problem you face is that the docker-registry is advertising so-called endpoints through a X-Docker-Endpoints header early during the dialog between itself and the Docker client, and that the Docker client will then use those endpoints for subsequent requests.
You have a setup where your Docker client first communicates with Nginx on the (public) 80 port, then switch to the advertised endpoints, which is probably localhost:5000 (that is, your local machine).
You should see if an option exists in the Docker registry you run so that it advertises endpoints as your remote host, even if it listens on localhost:5000.

Resources