I am running nginx as a front end reverse-proxy, in a docker (swarm, single node) container, in front of a Restheart application, delivering restheart REST services.
I am using the latest docker image for ngninx on Alpine. The configuration file is attached below.
As a backend, I am using a standard mvn build uberJar of Restheart, where mostly only the root for REST ressources access has been moved to /api instead of /. This works perfectly when accessed directly.
When I test the upstream server ( Restheart ) on (open for debugging) 8080 port directly, all REST apis work as expected.
I use httpie to do the testing.
When I go through nginx, on port 8081, with the same requests, the /api/... and /_logic paths/... are captured and work as expected.
For a reason I cannot understand, the /_authtokens/... and /browser/ paths are not passed to the upstream Restheart server, but end-up being caught by the first block, trying to locate a file with that name in the local filesystem, at /usr/share/nginx/html/...
What is really bothering me is that I do not see why it works perfectly on the first two paths and not on the other two ?!
Any hints or indications on where to look/search for would be greatly appreciated ? (already googled and scrateched my hairs for a few days now ... ;-)
# Configuration file for the nginx front-end container.
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
sendfile off;
keepalive_timeout 65;
gzip on;
include /etc/nginx/mime.types;
# default_type application/json;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log stdout main;
error_log stderr debug;
upstream docker-restheart {
server myrestheart:8080;
}
server {
listen 8081 ;
proxy_pass_request_headers on;
proxy_pass_request_body on;
proxy_http_version 1.1;
proxy_redirect default;
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;
# Default will serve the index as a test.
# This is also where non allocated locations will end up,
# because it is the first block ..
location / {
root /usr/share/nginx/html/;
}
# Restheart api - ok
location /api/ {
proxy_pass http://docker-restheart;
}
# Restheart _logic - ok
location /_logic/ {
proxy_pass http://docker-restheart;
}
# Restheart _authtokens - does not work ?
location /_authtokens/ {
proxy_pass http://docker-restheart;
}
# Restheart browser - does not work ?
location /browser/ {
proxy_pass http://docker-restheart;
}
# Restheart _authtokens - does not work ?
# Restheart browser - does not work ?
# In both cases, no transfer to upstream happening,
# but instead, caught by the first block ...
}
}
# This compose file defines the docker stack for swarm deployement
#
version: "3"
networks:
myoverlay:
driver: overlay
volumes:
dbdata:
services:
mymongo:
image: "mvertes/alpine-mongo:latest"
command: ["mongod","--quiet"]
ports:
- 27017:27017
deploy:
replicas: 1
volumes:
- dbdata:/data/db/
networks:
- myoverlay
myrestheart:
image: openjdk:8-jre-alpine
volumes:
- ./target/MyRestheart-1.0-SNAPSHOT.jar:/myjar.jar:ro
ports:
- 8080:8080
command: ["java","-Dmongo=mongodb://mymongo:27017", "-jar", "/myjar.jar"]
deploy:
replicas: 1
networks:
- myoverlay
mynginx:
image: nginx:alpine
ports:
- 8081:8081
volumes:
- ./nginx.conf:/nginx.conf
command: ["nginx", "-g","daemon off;","-c","/nginx.conf"]
deploy:
replicas: 1
networks:
- myoverlay
We have experienced similar problems with Nginx configurations in the past. In our case we moved to the regex syntax for locations, and it works. Something like:
location ~ /(api|browser|_logic|ping|_authtokens) {
proxy_pass http://docker-restheart;
}