Nginx microservice gateway config within kubernetes cluster - nginx

Basically we have a set of microservices we have deployed to a kubernetes cluster hosted in AWS. We would like to run these through a gateway configuration in nginx.
Our current configuration which doesn't work looks something like this-
upstream some-api1 {
server some-api1:80;
}
upstream some-api2 {
server some-api2:80;
}
upstream some-api3 {
server some-api3:80;
}
server {
listen 80;
server_name gateway.something.com;
location /api1 {
proxy_pass http://some-api1;
}
location /api2 {
proxy_pass http://some-api2;
}
location /api3 {
proxy_pass http://some-api3;
}
}
Our services have been built with dotnet core, so the underlying urls would be something like http://some-api1/{api/controllername} . I'm always getting a 404 when I try hitting these endpoints through postman, which tells me it can't resolve these mappings.
However I'm able to access an api within the cluster using an explicit config for an api like so(which is what I don't want to do)-
server {
listen 80;
server_name someapi1.something.com;
location /{
proxy_pass http://some-api1;
}
}..
If someone could shed some light on what's wrong with the configuration or recommend the best approach for this it would be greatly appreciated.

As #Luminance suggests, you're seeing traffic to /api1 go to some-api1/api1 instead of just some-api1 on the base path for that target service (which is what your app would respond to). Following https://gist.github.com/soheilhy/8b94347ff8336d971ad0 you could re-write that target like
location /api1 {
rewrite ^/api1(.*) /$1 break;
proxy_pass http://some-api1;
}

Related

Elixir/Phoenix umbrella app with two apps and access through subdomain mapped through reverse proxy with nginx

It's several hours I'm trying but I don't know what I'm doing wrong. I'm on a server with ubuntu 16.04, I have an umbrella app with two apps in it, which I would like to map to frontend.example.com and backend.example.com. On the DNS I have a wildcard for the whole domain (*.example.com + #.example.com). An additional issue is that one of them has to be on HTTPS,so I have the following onstart:
09:45:38.013 [info] Running FrontendWeb.Endpoint with Cowboy using http://0.0.0.0:91
09:45:38.055 [info] Running FrontendWeb.Endpoint with Cowboy using https://0.0.0.0:445
09:45:38.199 [info] Running BackendWeb.Endpoint with Cowboy using http://0.0.0.0:90
I would like Frontend to be mapped to frontend.example.com and the like for the second one. I have this servers.conf under /etc/nginx/conf.d:
server {
listen 80;
server_name backend.example.com;
location / {
proxy_pass http://localhost:90;
...
}
server {
listen 80;
server_name frontend.example.com;
location / {
proxy_pass http://localhost:91;
...
}
server {
listen 443;
server_name frontend.example.com;
location / {
proxy_pass http://localhost:445;
...
}
Is there something missing? It's not really working, only the backend redirect partially works.
EDIT: Should I put something in sites-available too? or the conf file is enough?

nginx responds with 404 Not Found (Single Page App)

I have a Single Page Application with regular Browser Router (without hash). Whenever someone navigates through page and hits refresh button nginx tries to find file on this path. So if someone is on mypage.com/about nginx looks for about file and responds with 404 Not Found. How to fix this issue?
I'm thinking about specifying a location with wildcard - mypage.com/* except /api tho, because every backend endpoint in this app starts with api. How to match all paths except one? This is how my config looks like:
upstream frontend {
server frontend:3000;
}
upstream backend {
server backend:8000;
}
server {
listen 80;
location /api {
proxy_pass http://backend;
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://frontend;
proxy_redirect default;
}
}
Why do your proxy requests for frontend app ? I assume that you are using some kind of development server to serve your frontend application. It is better to build your frontend application to static files and serve them as regular static files, without any server except the nginx.
As for your question, if you will build your frontend application into static files you may configure location in nginx like this:
root /var/www/your_site;
location / {
try_files $uri /index.html;
}
where index.html is entrypoint into your application and the root path should be configured to place where it stored.
If you still want to serve frontend application from development server through nginx you may configure nginx to handle errors from upstream and point error page to root of dev server.
In this case following directives should help you:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page

Deploying multiple Go applications using Nginx

The are two web applications (websites) written on Go. One is turalasgar.pro (here I am using Go built-in server). Another is engossip.com (for now it displays the same ip as former). I have a vps. I know I should use Nginx, but have no idea how? I have heard of Caddy. Please, I need only nginx server, not Caddy. What I need is run two (or more) applications by using my same vps. How should I configure Nginx configuration? Whether by listening to different ports or to the same port. Practical advices and examples highly appreciated.
It's called reverse proxy. Each application uses it's own port to listen. And then you just point to them in nginx config:
server {
listen 80;
server_name turalasgar.pro;
location / {
proxy_pass http://localhost:8080;
...
}
}
server {
listen 80;
server_name engossip.com;
location / {
proxy_pass http://localhost:8081;
...
}
}
Well is really easy.
follow this guide:
https://www.digitalocean.com/community/tutorials/how-to-use-martini-to-serve-go-applications-behind-an-nginx-server-on-ubuntu
After you achieved one application working with martini+nginx just add another server block for the other app.
In case you need more information about server blocks:
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts
Above solutions I tried but didn't work for me
https://gist.github.com/soheilhy/8b94347ff8336d971ad0
server {
listen ...;
...
location / {
proxy_pass http://127.0.0.1:8080;
}
location /blog {
rewrite ^/blog(.*) /$1 break;
proxy_pass http://127.0.0.1:8181;
}
location /mail {
rewrite ^/mail(.*) /$1 break;
proxy_pass http://127.0.0.1:8282;
}
...
}

nginx reverse proxy, single domain, multiple subdirectories

Having trouble figuring this out.
I have nginx running on home.domain.com.
Within my home network, I have multiple web services that I'd like to access externally through a reverse proxy. No SSL for now, but I'll add that later. I need to set up a reverse proxy on subdirectories of home.domain.com/app{1-3} as I only have a valid cert for home.domain.com.
My current configuration:
server {
listen 80 default;
keepalive_timeout 120;
server_name home.domain.com;
location /app1/ {
proxy_pass http://internalIP1:8081/;
}
location /app2/ {
proxy_pass http://internalIP2:5000/;
}
}
When I try to access home.domain.com/app1, it should redirect to home.domain.com/app1/login/?next=%2F, but instead goes to home.domain.com/login/?next=%2F. This obviously throws a 404, as it's not available on the nginx server.
Thoughts? Suggestions?

NGINX Location troubles

I have django and flask applications running on the same machine through different ports:
Django runs on server:8088
Flask runs on server:666
In NGINX.conf I have the following code:
location / {
proxy_pass http://127.0.0.1:8088;
}
location ^/server2 {
proxy_pass http://127.0.0.1:666;
}
Django has been running for over a year successfully with this set up, where as flask is a new addition. Any time I try to access one of the Flask urls I either get a "this url does not exist on this server" error, or on occasion a 500 error (when i've been fiddling).
If I write location information for a specific flask url like this:
location /server2/splash {
proxy_pass http://127.0.0.1:666/splash;
}
It works, but I obviously don't want to write individual location information for each and every URL in the flask application.
I've gone through many of the existing Nginx location posts on stackoverflow but I've not been able to get it working. Any ideas?
Thanks!
EDIT
this is an example of what I'm trying to achieve, but rather than an individual mapping for each URL, I want a single mapping that covers all URLs:
location /server2{
proxy_pass http://127.0.0.1:666/splash;
}
location /server2/split {
proxy_pass http://127.0.0.1:666/split;
}
location /server2/export {
proxy_pass http://127.0.0.1:666/export;
}
location /server2/import {
proxy_pass http://127.0.0.1:666/import;
}
Why do you use the ^ sign? Just remove it I think it will work:
location /server2 {
proxy_pass http://127.0.0.1:666;
}
Note that when you use location /server2 the server2 is still being passed to your flask application.
In this case Nginx is doing the following:
server.com/server2 => http://127.0.0.1:666/server2
server.com/server2/splash => http://127.0.0.1:666/server2/splash
In this case location is not doing a rewrite. Always check /var/log/nginx (or wherever your logs are located) to check the requests done by the browser and what Nginx looks for after the rules for your site are processed.
What you probably want is to set an upstream directive:
upstream flask_server {
server 127.0.0.1:666;
}
server {
...
location /server2 {
proxy_pass http://flask_server;
}
}

Resources