docker-compose Rails 应用程序无法在端口 3000 上访问

Gre*_*ogy 5 ruby-on-rails docker docker-compose

我正在为一个简单的 Rails/Postgres 应用程序构建 docker 容器。Rails 应用程序已启动并正在侦听端口 3000。我已为 Rails 容器公开了端口 3000。但是,http://localhost:3000 的响应为ERR_EMPTY_RESPONSE. 我假设 Rails 容器应该可以在端口 3000 上访问。我还需要做什么吗?

\n\n
greg@MemeMachine ~ $ docker ps\nCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES\need45208bbda        realestate_web      "entrypoint.sh bash \xe2\x80\xa6"   About a minute ago   Up About a minute   0.0.0.0:3000->3000/tcp   realestate_web_1\na9cb8cae310e        postgres            "docker-entrypoint.s\xe2\x80\xa6"   About a minute ago   Up About a minute   5432/tcp                 realestate_db_1\ngreg@MemeMachine ~ $ docker logs realestate_web_1\n=> Booting Puma\n=> Rails 6.0.2.2 application starting in development \n=> Run `rails server --help` for more startup options\nPuma starting in single mode...\n* Version 3.12.4 (ruby 2.6.3-p62), codename: Llamas in Pajamas\n* Min threads: 5, max threads: 5\n* Environment: development\n* Listening on tcp://localhost:3000\nUse Ctrl-C to stop\ngreg@MemeMachine ~ $ curl http://localhost:3000\ncurl: (52) Empty reply from server\n
Run Code Online (Sandbox Code Playgroud)\n\n

Dockerfile

\n\n
FROM ruby:2.6.3\n\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client\nRUN mkdir /myapp\nWORKDIR /myapp\nCOPY Gemfile /myapp/Gemfile\nCOPY Gemfile.lock /myapp/Gemfile.lock\nRUN gem install bundler -v 2.0.2\nRUN bundle install\nCOPY . /myapp\n\n# Add a script to be executed every time the container starts.\nCOPY entrypoint.sh /usr/bin/\nRUN chmod +x /usr/bin/entrypoint.sh\nENTRYPOINT ["entrypoint.sh"]\nEXPOSE 3000\n\n# Start the main process.\nCMD ["rails", "server", "-b", "0.0.0.0"]\n
Run Code Online (Sandbox Code Playgroud)\n\n

docker-compose.yml

\n\n
version: \'3\'\nservices:\n  db:\n    image: postgres\n    volumes:\n      - ./tmp/db:/var/lib/postgresql/data\n    env_file:\n      - \'.env\'\n  web:\n    build: .\n    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b \'0.0.0.0\'"\n    volumes:\n      - .:/myapp\n    ports:\n      - "3000:3000"\n    depends_on:\n      - db\n    env_file:\n      - \'.env\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

入口点.sh

\n\n
#!/bin/bash\n\n# Compile the assets\nbundle exec rake assets:precompile\n\n# Start the server\nbundle exec rails server\n
Run Code Online (Sandbox Code Playgroud)\n

Dav*_*aze 3

当您同时提供 anENTRYPOINT和 a时CMDDocker 会将它们组合成一个命令。如果您只是docker run构建图像,则入口点脚本将rails server -b 0.0.0.0作为命令行参数传递命令部分;但它忽略了这一点,只是启动 Rails 服务器本身(在本例中,没有导入-b 0.0.0.0选项)。

对此的通常答案是不要尝试直接在入口点中运行主进程,而是通过exec "$@"附加参数来运行命令来结束脚本。

在这种情况下,有两个附加位。文件command:中的docker-compose.yml表示需要在入口点中完成一些额外的设置(您不需要覆盖图像的命令来运行同一服务器)。您还需要提供的附加环境设置bundle exec。将这一切移至入口点脚本中,您将得到

#!/bin/sh
# ^^^ this script only uses POSIX shell features

# Compile the assets
bundle exec rake assets:precompile

# Clean a stale pid file
rm -f tmp/pids/server.pid

# Run the main container process, inside the Bundler context
exec bundle exec "$@"
Run Code Online (Sandbox Code Playgroud)

您的 Dockerfile 可以保持原样;command:您可以从文件中删除重复项docker-compose.yml