Webservice не работает после упаковки в образ Docker - PullRequest
0 голосов
/ 13 марта 2019

Я пишу простой веб-сервис на ruby ​​с sinatra.Если я запускаю ruby app.rb, он запускается на localhost: 4567.Я пишу Dockerfile, чтобы создать образ и выставить порт 4567.

Однако, когда я запускаю образ Docker, запускается веб-служба, но если я пытаюсь подключиться (с помощью curl и браузера) к порту 4567, он говорит Connection reset by peer.

У кого-нибудь есть предложения?Потому что я не знаю, что проверить в этом случае.Я пробовал некоторые смутные вещи, но все же ..

Веб-служба работает нормально вне докера.

РЕДАКТ. 1:

Я переместил изображение на eivor/ruby.Если вы запустите его и зайдите в браузер, чтобы проверить, он скажет connection reset.Да, я пытался docker run -p 4567:4567 eivor/ruby, как было сказано, прежде чем отправлять вопрос.

РЕДАКТИРОВАТЬ 2: Вот app.rb

require 'sinatra'
require 'referal' # this is the gem that calculate reward points to users
require 'json'
require 'byebug'

get '/' do
  'hello, world!'
end

# inside docker image, even get / returns connection reset by peer
# not to mention post data to it

post '/' do
  data = JSON.parse(request.body.read)
  input = []
  data.each do | key, value |
    input << value
  end
  invs, users = input.reduce([[],[]]) do | results, instruction |
    results = classify(instruction, results[0], results[1])
    results
  end
  res = export(users)
  # byebug
  puts res
end

post '/text' do
  @data = request.body.readlines
  #byebug
  @processed = @data.map{ |s| process(s) }
  @invs, @users = @processed.reduce([[],[]]) do | results, instruction |
    results = classify(instruction, results[0], results[1])
    results
  end
  @jsn = export(@users)
  puts @jsn
end

Вот Dockerfile, я создаю легкий рубин из альпийских

FROM alpine:3.5
ENV BUILD_PACKAGES bash curl-dev ruby-dev build-base git libstdc++ tzdata ca-certificates
ENV RUBY_PACKAGES ruby>2.3 ruby-irb ruby-rake ruby-io-console ruby-bigdecimal ruby-json

RUN apk update && apk upgrade
RUN apk add $BUILD_PACKAGES && apk add $RUBY_PACKAGES
RUN apk add ruby-bundler>1.17

RUN echo 'gem: --no-document' > /etc/gemrc && rm -rf /var/cach/apk/*

RUN gem install bundler

RUN mkdir /usr/app
WORKDIR /usr/app
RUN git init

COPY . /usr/app

RUN bundle install

RUN bundle exec rake install

EXPOSE 4567

CMD ["ruby", "./app.rb"]

Если я запускаю внешний докер с командой ruby app.rb или bundle exec rerun app.rb, он работает нормально.Но используя образ докера, это не так.Я запускаю команду:

docker run -p 4567:4567 eivor/ruby

Сервер работает,

[2019-03-14 16:59:59] INFO  WEBrick 1.3.1
[2019-03-14 16:59:59] INFO  ruby 2.3.8 (2018-10-18) [x86_64-linux-musl]
== Sinatra (v2.0.5) has taken the stage on 4567 for development with backup from WEBrick
[2019-03-14 16:59:59] INFO  WEBrick::HTTPServer#start: pid=1 port=4567

, но когда я пытаюсь получить доступ с помощью браузера или curl, он говорит connection reset by peer.Если я пытаюсь опубликовать сообщение с помощью curl, данные на самом деле отправляются, но они не отвечают, вместо этого они зависают.

curl -v localhost:4567 --data-binary @test/input
* Rebuilt URL to: localhost:4567/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 4567 (#0)
> POST / HTTP/1.1
> Host: localhost:4567
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 369
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 369 out of 369 bytes
* Recv failure: Connection reset by peer
* stopped the pause stream!
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

Ответы [ 3 ]

1 голос
/ 14 марта 2019

Эта проблема возникает из-за того, что Sinatra по умолчанию (среда разработки) прослушивает 127.0.0.1, которая не работает в случае внешнего подключения к контейнеру

: bind - имя хоста сервераили IP-адрес

Строка, указывающая имя хоста или IP-адрес интерфейса, который будет прослушиваться при включенной настройке: run.Значением по умолчанию в среде разработки является «localhost», что означает, что сервер доступен только с локальной машины.В других средах значением по умолчанию является «0.0.0.0», что заставляет сервер прослушивать все доступные интерфейсы.

Поэтому, если вы продолжите работать в режиме разработки, вам нужно изменить его на 0.0.0.0, например:

docker run -p 4567:4567 --name stack eivor/ruby bash -c 'ruby ./app.rb -o 0.0.0.0'

Который можно использовать в Dockerfile как:

CMD ["ruby", "./app.rb", "-o", "0.0.0.0"]

Или вы можете использовать в своем скрипте следующее:

set :bind, '0.0.0.0'

Тогда из-за пределов контейнера вы можете получить результат:

curl -v localhost:4567
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 4567 (#0)
> GET / HTTP/1.1
> Host: localhost:4567
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 200 OK 
< Content-Type: text/html;charset=utf-8
< Content-Length: 13
< X-Xss-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Server: WEBrick/1.3.1 (Ruby/2.3.8/2018-10-18)
< Date: Thu, 14 Mar 2019 17:17:20 GMT
< Connection: Keep-Alive
< 
* Connection #0 to host localhost left intact
hello, world!

Для дополнительной конфигурации проверьте следующее: НАСТРОЙКИ НАСТРОЙКИ

0 голосов
/ 13 марта 2019

С документация :

Значение флага Описание

-p 8080: 80 Сопоставить TCP-порт 80 в контейнере с портом 8080 на хосте Docker.

Вам необходимо сопоставить TCP-порт 4567 в контейнере с портом на хосте Docker. Например, чтобы сопоставить его с портом 8080:

$ docker run -it -p 8080:4567 image-goes-here
0 голосов
/ 13 марта 2019

Посмотрите на эту статью: https://docs.docker.com/config/containers/container-networking/

В двух словах - попробуйте опубликовать ваши открытые порты с помощью аргумента -p.

Например:

$ docker run -it -p 4567 my-local-image
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...