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 行,重建并重新启动容器,容器的端口 4000 中没有运行 sinatra 应用程序,但 nginx 这次正在运行!似乎nginx在我运行辛纳屈时被杀死了。
我做错了什么?我显然希望两者同时运行...
不能在单个 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 ...
(。