Docker-compose: Nginx proxy_pass my api - api

I am trying proxy my api to my client with nginx, everything is dockerized.
I got my client container which is a simple angular2 client hosted with nginx linked to my api, my api container linked to my mongo container.
The problem is my localhost:80/api is a 404 everytime.
I must be missing something....
Here is my nginx.conf
server {
listen 80;
# location /api/ {
# proxy_pass http://api:3000/;
# proxy_redirect http://api:3000/ http://localhost:80/api/;
# proxy_set_header Host $host;
# }
# location ~ /api/(?<section>.+) {
# proxy_pass http://api:3000/api/$section;
# proxy_set_header Host $host;
# }
location /api {
proxy_pass http://api:3000/api/;
proxy_redirect off;
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-Host $server_name;
}
Here is my docker-compose
services:
mongo:
image: mongo
ports:
- "27017:27017"
api:
build: ./server
ports:
- "3000"
volumes:
- .:/server
depends_on:
- mongo
web:
build: ./client
ports:
- "80:80"
volumes:
- .:/client
depends_on:
- api

I workarounded it by doing a node.js reverse proxy instead of nginx

Related

Kubernets ingress-nginx timeout in 120s

I have one api, which will run about 4 minutes. I have deployed it on kubernetes with ingress-nginx. All api work normally except the long-run api, it always return 504 Gateaway as below:
I have check in stackoverflow, and try some solution, none of it work for me.
any help is welcome.
Kubernetes Ingress (Specific APP) 504 Gateway Time-Out with 60 seconds
I have changed ingress config as below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.releaseName }}-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
nginx.ingress.kubernetes.io/server-snippet: "keepalive_timeout 3600s; grpc_read_timeout 3600s; grpc_send_timeout 3600s;client_body_timeout 3600s;"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "3601"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3601"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3601"
# nginx.org/proxy-connect-timeout: 3600s
# nginx.org/proxy-read-timeout: 3600s
# nginx.org/proxy-send-timeout: 3600s
nginx.ingress.kubernetes.io/proxy-body-size: "100M"
nginx.ingress.kubernetes.io/proxy-next-upstream: "error non_idempotent http_502 http_503 http_504"
nginx.ingress.kubernetes.io/retry-non-idempotent: "true"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "5"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "1"
# nginx.ingress.kubernetes.io/configuration-snippet: |-
# location /HouseKeeping/Health/Healthz {
# deny all;
# return 403;
# }
# location /InternalApi/ {
# deny all;
# return 403;
# }
nginx.ingress.kubernetes.io/server-snippets: |
http {
client_max_body_size 100m;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Connection $http_connection;
proxy_cache_bypass $http_upgrade;
proxy-connect-timeout: 3602;
proxy-read-timeout: 3602;
proxy-send-timeout: 3602;
}
spec:
rules:
- host: {{ .Values.apiDomain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Values.releaseName }}-web-clusterip-srv
port:
number: 80
I also change the configMap for ingress-nginx-controller to add below config:
apiVersion: v1
data:
allow-snippet-annotations: "true"
proxy-connect-timeout: "300"
proxy-read-timeout: "300"
proxy-send-timeout: "300"
kind: ConfigMap
I also used command to get ingress-nginx's conf, it seems okay
kubectl -n ingress-nginx exec ingress-nginx-controller-6cc65c646d-ljmrm cat /etc/nginx/nginx.conf | tee nginx.test-ingress-export.conf
# Custom headers to proxied server
proxy_connect_timeout 3601s;
proxy_send_timeout 3601s;
proxy_read_timeout 3601s;
it still timeout in 120 seconds.
Typo
Replace below (ingress config):
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "5"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "1"
In place of (ingress config)
nginx.ingress.kubernetes.io/proxy_next_upstream_timeout: "5"
nginx.ingress.kubernetes.io/proxy_next_upstream_tries: "1"
Edit :
Check this comment may help to resolve your issue.

Nginx not redirecting on named route

I'm trying to setup a reverse proxy to a sentry relay using Nginx. Config file as follows:
events {
worker_connections 768;
}
http {
server {
listen 0.0.0.0:80;
location /sentry-relay {
proxy_pass http://127.0.0.1:3001;
proxy_redirect off;
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-Host $server_name;
}
}
}
Browsing directly to the relay server on port 3001 works fine:
However using the location path set in Nginx fails:
I've also put the redirect onto the default path: location / and it works fine. Why won't this custom path redirect properly?
I worked it out.
Nginx will append the location prefix to the proxy server request unless this prefix is replaced.
Thus to fix I changed:
proxy_pass http://127.0.0.1:3001;
to
proxy_pass http://127.0.0.1:3001/;
The extra slash is used to replace the sentry-relay path.

how to proxy to my domain with port from request urls that start with api?

I have a loopback 3 set up listening on the port 3000. And my front end app is built with Vue JS. ( I uploaded dist files to the server). Whenever I make an api call (https://example.com/api/xxx), I need to proxy to (https://example.com:3000/api/xxx) in order to avoid cors issues.
How do I resolve this?
FYI, the loopback and vueJS are hosted on the same web server (apache, centos8)
Use NGINX Reverse Proxy
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
http://localhost:5000 - points to your Vue.js app
http: //localhost:3000 - points to your REST API app
server {
listen 80;
server_name example.org;
location / {
proxy_pass http://localhost:5000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
location ^ ~/api {
proxy_pass http: //localhost:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}

Ocelot gateway unable to obtain configuration from identityserver in docker compose

I have an error that I can't seem to understand why this is happening.
I have a microservice architecture running in a docker network. I'm trying to set up an identity server with the framework Identityserver4.
There is a proxy forwarding to an Ocelot gateway. The client is an angular application.
The login and logout and retrieving the access token and the identity token is successful, but when I try to set up authentication in Ocelot, I get the following error.
DX20803: Unable to obtain configuration from: 'http://identityservice:5010/.well-
known/openid-configuration'.
gateway_1 | System.InvalidOperationException: IDX20803: Unable to obtain
configuration from: 'http://identityservice:5010/.well-known/openid-configuration'.
gateway_1 | ---> System.IO.IOException: IDX20804: Unable to retrieve document
from: 'http://localhost/auth/.well-known/openid-configuration/jwks'.
gateway_1 | ---> System.Net.Http.HttpRequestException: Cannot assign
requested address
The docker-compose is set up in this way
version: '3.0'
services:
pricecalendarservice:
build:
context: ./PriceCalendarService
environment:
- ASPNETCORE_URLS=http://+:5002
- RedisConnection=redis
gateway:
build:
context: ./Gateway/
environment:
- ASPNETCORE_URLS=http://+:5000
- ID_URL=http://identityservice
frontend:
build:
context: ./SPA
dockerfile: staging.dockerfile
itemmanagerservice:
build:
./ItemManagerService
environment:
- ASPNETCORE_URLS=http://+:5003
- IdentityUrl=http://identityservice
identityservice:
build:
context: ./IdentityServer/IdentityServer
environment:
- DEV_URL=http://localhost
- ASPNETCORE_ENVIRONMENT=Developmnet
- ASPNETCORE_URLS=http://+:5010
- IDENTITY_ISSUER=http://localhost/auth
- RedisConnection=redis
ports:
- 5010:5010
proxy:
build:
context: ./proxy
ports:
- 80:80
redis:
image: redis
ports:
- 6379:6379
The Identityserver is configured in the following way
string redisConnectionString = Environment.GetEnvironmentVariable("RedisConnection",
EnvironmentVariableTarget.Process);
string prodEnv = Environment.GetEnvironmentVariable("PROD_URL");
string devEnv = Environment.GetEnvironmentVariable("DEV_URL");
string env = Environment.GetEnvironmentVariable("ASPNETCORE_URLS");
string issuer = Environment.GetEnvironmentVariable("IDENTITY_ISSUER");
var redis = ConnectionMultiplexer.Connect( redisConnectionString + ":6379");
services.AddDataProtection()
.PersistKeysToStackExchangeRedis( redis , "DataProtection-Keys")
.SetApplicationName("product");
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder
.WithOrigins("https:localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader();
}));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is
needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
var config = new Config();
config.setEnvironemnt(devEnv);
services.AddIdentityServer(options => {
options.PublicOrigin = issuer;
})
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(config.GetIdentityResources())
.AddInMemoryApiResources(config.GetApis())
.AddInMemoryClients(config.GetClients())
.AddTestUsers(config.GetUsers());
NB. the issuer is set to "http://localhost/auth"
The Nginx proxy server is set with the following settings
server {
listen 80;
location / {
proxy_pass http://frontend;
proxy_redirect off;
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-Host $server_name;
}
location /api/hub {
proxy_pass http://gateway:5000;
proxy_redirect off;
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-Host $server_name;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api {
proxy_pass http://gateway:5000;
proxy_redirect off;
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-Host $server_name;
proxy_set_header Upgrade $http_upgrade;
proxy_cache_bypass $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /auth {
proxy_pass http://gateway:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
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;
proxy_cache_bypass $http_upgrade;
}
}
The gateway configuration is, as read in the documentation at Ocelot Documentation
var authenticationProviderKey = "TestKey";
s.AddAuthentication()
.AddIdentityServerAuthentication(authenticationProviderKey, x =>
{
x.Authority = "http://identityservice:5010";
x.RequireHttpsMetadata=false;
});
/*
options.TokenValidationParameters = new
Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidAudiences = new[] {"item"}
};
*/
s.AddOcelot();
s.AddSwaggerGen(swagger =>
{
swagger.SwaggerDoc("v1", new OpenApiInfo { Title = "PriceCalendarService" });
});
It seems that the gateway, which is running inside the docker network cant get access to the identity server. But I have tried both the URL which the angular is calling which is
"http://localhost/auth"
And also the name of the service running in docker, in multiple ways.
"http://identityservice:5010"
"http://identityservice"
But somehow, the gateway can't get access to the identity server to load the discovery document.
Can anyone point me in any direction on how to get this right.

Running Apache Zeppelin with nginx as reverse proxy

In our current architecture we have two apache front servers, in front of them, we have an nginx load balancer. And in front of that an nginx reverse proxy.
My problem is that i'm trying to run Apache Zeppelin through the reverse proxy, and i'm having some problems with the websockets.
I get an error like this : 400 HTTP method GET is not supported by this URL
And here is a screenshot of what the Chrome's Networks tab shows :
I add my reverse proxy config for Zeppelin:
error_log /var/log/nginx/nginx_error.log warn;
server {
listen 80;
server_name localhost;
location /zeppelin/ {
proxy_pass http://zeppelin:8080/;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection upgrade;
}
# fallback
location / {
return 301 http://ci.blablalablab.com/app/;
}
}
Zeppelin is running inside a docker container, and i have exposes the 8080 port, its host name is : zeppelin.
If you have any questions on the architecture or so, don't hesitate to ask.
Thank you very much guys !
you can add to your reverse proxy configuration
location /ws { # For websocket support
proxy_pass http://zeppelin:8080/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection upgrade;
proxy_read_timeout 86400;
}
Reference: Zeppelin 0.7 auth docs
After a lot of digging around, i ended up with this configuration :
location /zeppelin/ {
proxy_pass http://zeppelin:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
}
location /zeppelin/ws {
proxy_pass http://zeppelin:8080/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
This is working pretty good, thank you everyone for your efforts ;)