ruby - 带 docker 的 nginx 没有正确代理到我的 ruby​​ 应用程序

标签 ruby nginx docker reverse-proxy

我有两个 Docker 容器(从自定义配置的 nginx 和 Ruby 图像构建),当我运行容器并发出请求时,它们似乎将请求代理到正确的位置(但其中一个被代理的服务没有不太正确地处理请求)。

即当我尝试代理到我的 Ruby 容器时,我要么收到“Sinatra 无法识别此小曲”错误,要么收到“301 重定向”?

Note: code can be found here as well https://github.com/Integralist/Docker-Examples/tree/master/Nginx

下面是 nginx 的 Dockerfile:

FROM ubuntu

# install nginx
RUN apt-get update && apt-get install -y nginx
RUN rm -rf /etc/nginx/sites-enabled/default

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

以下是 Ruby 应用程序的 Dockerfile:

FROM ruby:2.1-onbuild
CMD ["ruby", "app.rb"]

Note:
Someone asked how my app.rb and other dependencies were being loaded (as my docker run wasn't mounting them and the Dockerfile doesn't appear to add them). If you look at the ruby "onbuild" tagged version of the image you'll see it COPY's all those files for us https://github.com/docker-library/ruby/2.0/onbuild/Dockerfile

Ruby 应用程序如下所示:

require "sinatra"

set :bind, "0.0.0.0"

get "/" do
  "Hello World"
end

nginx.conf 文件如下所示:

user nobody nogroup;
worker_processes auto;          # auto-detect number of logical CPU cores

events {
  worker_connections 512;       # set the max number of simultaneous connections (per worker process)
}

http {
  upstream app {
    server app:4567;            # app is automatically defined inside /etc/hosts by Docker
  }

  server {
    listen *:80;                # Listen for incoming connections from any interface on port 80
    server_name "";             # Don't worry if "Host" HTTP Header is empty or not set
    root /usr/share/nginx/html; # serve static files from here

    location /app/ {            # catch any requests that start with /app/
      proxy_pass http://app;    # proxy requests onto our app server (i.e. a different container)
    }
  }
}

我像这样运行 Ruby 容器:

docker run --name ruby-app -p 4567:4567 -d my-ruby-app

我像这样运行 nginx 容器:

docker run --name nginx-container \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/docker-nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
  --link ruby-app:app \
  -P -d my-nginx

如果我运行 curl http://$(boot2docker ip):32785/app/ 我会返回“Sinatra 不知道这个小东西”错误;如果我运行 curl http://$(boot2docker ip):32785/app 我会收到 301 Moved Permanently 消息吗?

我确定我遗漏了一些非常明显的东西(也许 Sinatra 是如何配置的?比如我需要设置一个 /app 路由吗?或者我应该使用一个 别名nginx.conf 中的 指令一些方法)

感谢任何帮助。

最佳答案

所以我认为您设置的内容和测试的内容只存在一些基本问题。

首先你在 nginx 中说,“当你得到/app/时,将它代理到运行 sinatra 的容器”:

location /app/ {            # catch any requests that start with /app/
  proxy_pass http://app;    # proxy requests onto our app server (i.e. a different container)
}

所以这将被传递给 sinatra,请求 URI 为 /app/

由于您的 sinatra 应用程序没有定义该路由,这就是为什么您会收到“Sinatra 不知道这个小东西”的原因。

当您在没有尾部斜杠的情况下尝试时得到 301 的原因是因为 sinatra 会自动重定向任何没有尾部斜杠的内容。

正如 Dirk 提到的,您在点击时得到“Hello world”的原因:

curl http://$(boot2docker ip):4567/

是因为那条路线是在你的sinatra route 定义的,如果你点击:

curl http://$(boot2docker ip):4567

然后你应该得到一个 301 重定向到/。

要解决您的问题,您需要:

  1. 将您在 sinatra 中的路由更改为“/app”。
  2. 将您的 nginx 位置更改为/而不是/app/。

选项 2 将是最灵活的,因为对 nginx 容器的任何请求都将直接映射到 sinatra 容器,就像您添加了另一条路由,您需要再次更新 nginx 配置以添加此路由以代理到sinatra 容器。

关于ruby - 带 docker 的 nginx 没有正确代理到我的 ruby​​ 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31772520/

相关文章:

配置 : error: C compiler cannot create executables when installing Ruby 1. 9.3

mysql - 我可以在一个数据库操作中将列中的每个值乘以某个数字吗?

django - 从本地主机访问时出现404错误: NGINX uWSGI

docker - 如何更改Docker中的默认分离键序列?

python - Gunicorn导入错误: No module named app

docker - 如何在 docker compose 版本 3 中指定内存和 CPU 限制

ruby-on-rails - 一个存储文件的地方(Ruby on Rails)

ruby - 从较小的短语重建原始句子?

nginx - 代理协议(protocol)和 SSL

ssl - 设置让我们加密后网站重定向次数过多