rexyai / RestRserve

R web API framework for building high-performance microservices and app backends
https://restrserve.org
271 stars 31 forks source link

Swagger and NGINX Config file on Docker-Compose #172

Closed Tartomas closed 3 years ago

Tartomas commented 3 years ago

Hello everyone I'm working with docker-compose to enable a RestRServe API service controlled by a NGINX PROXY. Everythings go smooth except by the port :8080 in the URL. I have review a lot of rewrite and /locations but anyone seems to work.

I will copy a simple reproducible example

docker-compose.yml

version: '3'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile-api
      args:
        buildno: 1
    restart: always
    ports:
      - "8080:8080"
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro # config file
      - ./nginx/src:/usr/share/nginx/html # simple index.html
    restart: always
    depends_on:
     - api

./nginx/nginx.conf

events {
  worker_connections  4096;  ## Default: 1024
}

http {
        default_type application/octet-stream;
        sendfile     on;
        tcp_nopush   on;
        server_names_hash_bucket_size 128; # this seems to be required for some vhosts

      map $http_upgrade $connection_upgrade {
          default upgrade;
          ''      close;
          }

        server {
                listen       80;
                server_name my.server.com;

                location / {
                  root   /usr/share/nginx/html;
                  index  index.html index.htm;
                }

                location /doc {
                        rewrite ^/doc/(.*) /$1 break;
                        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_pass http://127.0.0.1:8080/;

                }
        }
}

When I load to locahost, apears my index.html rmarkdown file. But when goes to localhost/doc it can't reach the swagger documentation. Just when I open localhost:8080 I cant see the swagger webpage.

Best regards !

dselivanov commented 3 years ago

I believe "proxy_pass http://127.0.0.1:8080/" should be "proxy_pass http://api:8080/ http://127.0.0.1:8080/" as you forward it to API containers.

On Wed, 28 Oct 2020, 23:04 Tomas Acuña Ruz, notifications@github.com wrote:

Hello everyone I'm working with docker-compose to enable a RestRServe API service controlled by a NGINX PROXY. Everythings go smooth except by the port :8080 in the URL. I have review a lot of rewrite and /locations but anyone seems to work.

I will copy a simple reproducible example docker-compose.yml

version: '3'

services: api: build: context: . dockerfile: Dockerfile-api args: buildno: 1 restart: always ports:

  • "8080:8080" nginx: image: nginx ports:
  • "80:80" volumes:
  • ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro # config file
  • ./nginx/src:/usr/share/nginx/html # simple index.html restart: always depends_on:
    • api

./nginx/nginx.conf

events { worker_connections 4096; ## Default: 1024 }

http { default_type application/octet-stream; sendfile on; tcp_nopush on; server_names_hash_bucket_size 128; # this seems to be required for some vhosts

  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
      }

    server {
            listen       80;
            server_name my.server.com;

            location / {
              root   /usr/share/nginx/html;
              index  index.html index.htm;
            }

            location /doc {
                    rewrite ^/doc/(.*) /$1 break;
                    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_pass http://127.0.0.1:8080/;

            }
    }

}

When I load to locahost, apears my index.html rmarkdown file. But when goes to localhost/doc it can't reach the swagger documentation. Just when I open localhost:8080 I cant see the swagger webpage.

Best regards !

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rexyai/RestRserve/issues/172, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHC5XMDGT7QFO3RH3DALEDSNBTNJANCNFSM4TCXYKQQ .

Tartomas commented 3 years ago

Hello, thanks for your reply. But still not work as I expect to

I cant enter to http://localhost:8080/doc properly

Screenshot_2020-10-30 Swagger UI(3)

But when I goes to http://localhost/api/doc I receive the following openapi message

Screenshot_2020-10-30 Swagger UI(2)

Do you have any hint where could be my error in the nginx config file ?

events {
  worker_connections  4096;  ## Default: 1024
}

http {
        default_type application/octet-stream;
        sendfile     on;
        tcp_nopush   on;
        server_names_hash_bucket_size 128; # this seems to be required for some vhosts

      map $http_upgrade $connection_upgrade {
          default upgrade;
          ''      close;
          }

        server {
                listen 80 default_server;
                listen [::]:80 default_server ipv6only=on;
                server_name localhost;

                location / {
                  root   /usr/share/nginx/html;
                  index  index.html index.htm;
                }

                location /api {

                  rewrite ^/api(.*) /$1 break;
                  proxy_pass http://api:8080/;

                }                

        }
}

Thanks !

dselivanov commented 3 years ago

Surely the issue is with nginx config. I'm not very familiar with nginx, so can't spot it straight away. You can set application logger level to 'trace' and see which requests at which routes hit RestRserve service.

Tartomas commented 3 years ago

Hello Thanks ! Not sure how to continue with this issue. I will close the issue for now, maybe in near by future someone find the correct answer. Best !

dselivanov commented 3 years ago

@Tartomas This minimal example works. However you need to investigate how to use nginx rewrite option properly. As you can see you need to redirect /openapi.yaml to RestRserve ( this is from where swagger reads openapi spec)

version: '3'

services:
  api:
    image: rexyai/restrserve:dev-minimal
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./app:/app
    entrypoint: ['Rscript', '/app/app.R']
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro # config file
      - ./nginx/src:/usr/share/nginx/html # simple index.html
    restart: always
    depends_on:
     - api
events {
  worker_connections  4096;  ## Default: 1024
}

http {
        default_type application/octet-stream;
        sendfile     on;
        tcp_nopush   on;
        server_names_hash_bucket_size 128; # this seems to be required for some vhosts

      map $http_upgrade $connection_upgrade {
          default upgrade;
          ''      close;
          }

        server {
                listen 80 default_server;
                listen [::]:80 default_server ipv6only=on;
                server_name localhost;

                location / {
                  root   /usr/share/nginx/html;
                  index  index.html index.htm;
                }

                location /doc {
                  proxy_pass http://api:8080/doc;
                }

                location /openapi.yaml {
                  proxy_pass http://api:8080/openapi.yaml;
                }

                location /fib {
                  proxy_pass http://api:8080/fib;
                }

        }
}
library(RestRserve)
app = Application$new()

calc_fib = function(n) {
  if (n < 0L) stop("n should be >= 0")
  if (n == 0L) return(0L)
  if (n == 1L || n == 2L) return(1L)
  x = rep(1L, n)

  for (i in 3L:n) {
    x[[i]] = x[[i - 1]] + x[[i - 2]]
  }

  return(x[[n]])
}

fib_handler = function(request, response) {
  n = as.integer(request$parameters_query[["n"]])
  if (length(n) == 0L || is.na(n)) {
    raise(HTTPError$bad_request())
  }
  response$set_body(as.character(calc_fib(n)))
  response$set_content_type("text/plain")
}

app$add_get(path = "/fib", FUN = fib_handler)
app$logger$set_log_level("debug")

yaml_file = system.file("examples", "openapi", "openapi.yaml", package = "RestRserve")
app$add_openapi(path = "/openapi.yaml", file_path = yaml_file)
app$add_swagger_ui(path = "/doc", path_openapi = "/openapi.yaml", use_cdn = TRUE)

backend = BackendRserve$new()
backend$start(app, http_port = 8080)