【问题标题】:Nginx seems to crash on Sinatra app in DockerNginx 似乎在 Docker 中的 Sinatra 应用程序上崩溃
【发布时间】:2016-12-30 16:06:19
【问题描述】:

Dockerfile:

FROM ruby:2.3.1-slim
MAINTAINER Marc Lacoursiere <marc@roosoft.com>

RUN apt-get update && apt-get install -yq nginx

RUN rm /etc/nginx/sites-enabled/default
ADD docker/sinatra.conf /etc/nginx/sites-enabled/sinatra.conf

RUN adduser app --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password
RUN mkdir /home/app/webapp

WORKDIR /tmp
COPY app/Gemfile /tmp/
COPY app/Gemfile.lock /tmp/
RUN bundle install

COPY app /home/app/webapp
RUN chown -R app:app /home/app

CMD ["nginx", "-g", "daemon off;"]
CMD ["ruby", "/home/app/webapp/app.rb"]

Sinatra.conf:

upstream app {
    server 127.0.0.1:4000;
}

server {
    listen 80 default_server;
    server_name localhost;

    error_log /var/log/nginx/localhost.error_log info;

    location / {
        proxy_pass http://app;
    }
}

app.rb

require 'sinatra'
require 'sinatra/json'

set :port, 4000

get '/' do
  json 'Hello World!'
end

宝石文件:

source 'https://rubygems.org'

gem 'sinatra', '1.4.6'
gem 'sinatra-contrib', '~> 1.4.2'

如何在 bash 中执行

docker run -p 4444:80 roosoft/sinatra-example

简单地说,我应该让一个 sinatra 应用程序响应容器的端口 4000。Nginx 正在侦听容器的端口 80 并返回它在端口 4000 上找到的内容,这是 sinatra 应用程序。容器的80端口被重定向到本地4444端口,但是4444端口返回:

curl: (52) Empty reply from server

此时,由于某种不明原因,nginx 并未在容器中运行。要修复它,我只需登录到容器,输入service nginx start,一切都很好。我可以从容器中注销,本地端口 4444 会返回预期的结果。

如果我注释掉Dockerfile的最后一行,rebuild并重启容器,容器的4000端口没有sinatra app运行,但是这次运行的是nginx!当我运行 sinatra 时,似乎 nginx 被杀死了。

我做错了什么?我显然希望两者同时运行...

【问题讨论】:

    标签: ruby bash nginx docker sinatra


    【解决方案1】:

    您不能在单个 Dockerfile (https://docs.docker.com/engine/reference/builder/#/cmd) 中包含多个 CMD 语句。如果查看docker build 的输出,您可以看到每个CMD 都会创建一个新图像。每个CMD 都会覆盖上一张图片中指定的那个。

    如果你想在一个 Docker 容器中运行多个进程,你可以使用像 supervisord 这样的进程管理器。 supervisord 还可以帮助您在发生故障时自动重新启动进程。可以在此处找到有关如何完成此操作的教程:

    https://docs.docker.com/engine/admin/using_supervisord/

    另一个(恕我直言,更清洁)解决方案是启动两个容器。一个用于 Sinatra 应用程序,一个用于 Nginx。只需将两个容器链接在一起 (docker create --link ...) 或设置一个网络 (docker network create ...) 并将两个容器连接到它 (docker create --network ...)。

    【讨论】:

    • 是的,开始明白 Docker 是关于单进程应用程序的。因此,运行 sinatra 应用程序似乎是容器的完整用例。我正在考虑在服务器本身上运行 nginx。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多