Rails服务器仍在新打开的docker容器中运行

han*_*ock 41 ruby-on-rails docker dockerfile docker-compose

我想使用Docker部署我的rails项目.所以我使用Docker-Compose.但我得到一个奇怪的错误消息.当运行docker-compose up(这包含带有postgresql的db-container,带有rails的redis和web容器)时,我得到一个

web_1 | => Booting Puma web_1 | => Rails 4.2.4 application starting in production on http://0.0.0.0:3000 web_1 | => Runrails server -h for more startup options web_1 | => Ctrl-C to shutdown server web_1 | A server is already running. Check /usr/src/app/tmp/pids/server.pid. web_1 | Exiting 所以我无法理解为什么我会收到这条消息,因为每次运行docker-compose时,新容器都会启动,而不是之前的容器.即使想要删除这些server.pid我也无法做到这一点,因为这个容器没有运行.

我的docker-compose.yml文件

web:
  dockerfile: Dockerfile-rails
  build: .
  command: bundle exec rails s -p 3000 -b '0.0.0.0'
  ports:
    - "80:3000"
  links:
    - redis
    - db
  environment:
    - REDISTOGO_URL=redis://user@redis:6379/

redis:
  image: redis

db:
  dockerfile: Dockerfile-db
  build: .
  env_file: .env_db
Run Code Online (Sandbox Code Playgroud)

Dockerfile护栏

FROM rails:onbuild

ENV RAILS_ENV=production
Run Code Online (Sandbox Code Playgroud)

我认为我不需要发布我的所有Dockerfiles

UPD:我自己解决了这个问题:我刚刚删除了所有容器并docker-compose up再次运行了

Top*_*erH 51

您正在使用onbuild图像,因此您的工作目标将安装在容器图像中.这非常适合开发,因为您的应用程序在编辑代码时会实时更新,并且主机系统会在您运行迁移时得到更新.

这也意味着每次服务器运行时,您的主机系统tmp目录都将使用pid文件写入,如果服务器未正确关闭,它将保留在那里.

只需从主机系统运行此命令:

sudo rm tmp/pids/server.pid 
Run Code Online (Sandbox Code Playgroud)

当您在docker-compose下使用foreman时,这可能是一个真正的痛苦,因为只需按ctrl + c就不会删除pid文件.

  • 我认为解决方法可能是运行"docker-compose run web/bin/bash"并从那里删除pid文件.然后尝试调查它是如何到达那里的.此外,您应该在容器上运行"docker inspect",因为它可能无法正确安装主机目录. (6认同)
  • 问题是:我的`tmp/pids`目录中没有`server.pid`文件 (3认同)
  • 这个的变体对我有用,我在运行foreman start之前添加到我的启动脚本`rm/myapp/tmp/pids/server.pid`. (2认同)

Bre*_*ley 38

在我弄清楚究竟发生了什么之前,我被同样的问题困扰了一下.真正的答案是进一步下降......首先,您可能想在docker-compose.yml文件中尝试类似以下命令:

command: /bin/sh -c "rm -f /rails/tmp/pids/server.pid && rails server puma"
Run Code Online (Sandbox Code Playgroud)

(我正在使用Alpine和busybox来保持微小的东西,所以没有bash!但是-c也可以使用bash)这将删除文件,如果它存在,这样你就不会遇到容器保持的问题退出并坐在那里无法运行命令.

不幸的是,这不是一个好的解决方案,因为您在服务器之前添加了额外的/ bin/sh层,这会阻止服务器获取stop命令.结果是docker stop命令不能正常退出,并且问题将永远发生.

您可以使用docker-compose运行rm命令以删除文件,然后将命令更改回服务器并继续.

但是,真正的答案是创建一个简单的docker-entry.sh文件,并确保使用exec表单入口点文档调用它,以便信号(如停止)进入服务器进程.

#!/bin/sh
set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

exec bundle exec "$@"
Run Code Online (Sandbox Code Playgroud)

注意:我们在最后一行使用exec以确保rails将作为pid 1运行(即没有额外的shell),从而使信号停止.然后在Dockerfile(或compose.yml)文件中添加入口点和命令

# Get stuff running
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["rails", "server", "puma"]
Run Code Online (Sandbox Code Playgroud)

而且,你必须使用[]格式,以便它被执行而不是以sh -c""运行

  • 很棒的回答,谢谢.请注意,我必须使用`chmod + x docker-entrypoint.sh`来解决权限被拒绝错误. (6认同)
  • 很好的答案.我必须将我的入口点设置为"/myapp/docker-entrypoint.sh"才能使其正常工作.相关讨论,请访问https://github.com/docker/compose/issues/1393. (4认同)
  • @Seafish,我在使用 docker-compose 时添加了 [一个经过调整的答案](/sf/answers/3753063611/) 来解决这个问题 (2认同)

dav*_*son 9

这是改编版布兰顿Whateleys答案

Docker Compose解决方案

1.创建docker-entrypoint.sh

#!/bin/bash
set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

exec bundle exec "$@"
Run Code Online (Sandbox Code Playgroud)

2.修改您的docker-compose.yml

services:
  web:
    build: .
    entrypoint: /myapp/docker-entrypoint.sh
    command: ["rails", "server", "-b", "0.0.0.0"]
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
Run Code Online (Sandbox Code Playgroud)

请注意,您将必须提供安装应用程序iE的路径: /myapp

2.5如果遇到权限错误

运行docker-compose up或生成映像之前,请在终端中运行此命令。谢谢sajadghawami

chmod +x docker-entrypoint.sh
Run Code Online (Sandbox Code Playgroud)

3.不必再手动删除server.pid


cha*_*sdg 5

我做了什么,是继续使用docker的bash shell:

docker-compose run web /bin/bash

然后删除以下文件

rm tmp/pids/server.pid

希望对你有所帮助!


mrp*_*877 5

为了我的工作:

docker-compose run web bash
Run Code Online (Sandbox Code Playgroud)

然后使用cd命令逐个文件夹(我正在使用win 7工具箱),所以最后我在bash中使用:

rm tmp/pids/server.pid


Arn*_*Roa 5

如果您的解决方案是使用rm删除入口点上的 pid 文件,我认为更好的解决方案是告诉 Rails 将 pid 文件写入临时路径,例如:

web:
   command: bundle exec rails server -b '0.0.0.0' -p 3000 -P /tmp/rails.pid 
Run Code Online (Sandbox Code Playgroud)

然而,大多数时候这是因为 docker 容器仍在运行而引起的,我通常做的是:

web:
   command: bundle exec rails server -b '0.0.0.0' -p 3000 -P /tmp/rails.pid 
Run Code Online (Sandbox Code Playgroud)

这将停止所有正在运行的容器。这-a适用于所有-q安静(仅)容器 ID