Rails服务器仍然在一个新的打开的泊坞窗容器中运行

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

web_1 | => Booting Puma web_1 | => Rails 4.2.4 application starting in production on http://0.0.0.0:3000 web_1 | => Run web_1 | => Booting Puma web_1 | => Rails 4.2.4 application starting in production on http://0.0.0.0:3000 web_1 | => Run rails 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 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 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组成,新的容器启动,而不是以前。 即使想删除这些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 

Dockerfile护栏

 FROM rails:onbuild ENV RAILS_ENV=production 

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

UPD:我自己修复了:我刚刚删除了所有的容器,然后再次运行docker-compose up

你正在使用一个onbuild图像,所以你的工作direcotry被安装在容器图像。 这对于开发非常有用,因为在编辑代码时实时更新应用程序,并且在运行迁移时更新主机系统。

这也意味着,每当服务器运行时,你的主机系统tmp目录将被写入pid文件,并且如果服务器没有被正确closures,它将保持在那里。

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

 sudo rm tmp/pids/server.pid 

这可能是一个真正的痛苦,当你是例如使用docker工作的领class,因为只要按Ctrl + C不会删除PID文件。

我被同样的问题困住了一阵子,直到我知道了究竟是怎么回事。 真正的答案是更进一步…首先,你可能想在你的docker-compose.yml文件中尝试类似下面的命令:

 command: /bin/sh -c "rm -f /rails/tmp/pids/server.pid && rails server puma" 

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

不幸的是,这不是一个好的解决scheme,因为在服务器之前添加了一个额外的/ bin / sh层,这样可以防止服务器获得停止命令。 结果是docker stop命令不会优雅地退出,问题总是会发生的。

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

但是,真正的答案是创build一个简单的docker-entry.sh文件,并确保使用exec窗体Entrypoint文档调用它,以便信号(如stop)到达服务器进程。

 #!/bin/sh set -e if [ -f tmp/pids/server.pid ]; then rm tmp/pids/server.pid fi exec bundle exec "$@" 

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

 # Get stuff running ENTRYPOINT ["docker-entrypoint.sh"] CMD ["rails", "server", "puma"] 

再次,您必须使用[]格式,以便它被执行,而不是像sh -c“

对于没有tmp/pids/server.pid有问题的人实际上是存在的:

(Docker版本1.11.2,build b9f10c9)

  1. 解决scheme,这对我来说是添加确切的命令docker-compose.yml ,例如:

     command: rails s -b0 

    有这个命令,实际上可能只是复制Dockerfile的CMD – 问题与陈旧.pid不会出现。

  2. 其他选项,当你需要使用Dockerfile的CMD时,运行选项--build重build镜像:

     docker-compose up --build 

    虽然需要时间,所以第一个解决scheme更方便

我所做的,就是在docker的bash shell上:

docker-compose run web /bin/bash

然后删除以下文件

rm tmp/pids/server.pid

希望它有帮助!

如果你感觉冒险,可以在代码库中searchserver.pid,并检查pid写入的位置。 这样,您可以检查是否不允许写入修复您的根本问题。 因为貌似pid的创build有助于防止在两个不同的docker容器中运行重复的服务。 但是这应该在docker工人照顾下。 如果由于某种原因,它不是,港口碰撞方法应该一定照顾和提醒你。 注:我还没有尝试过这种方法,因为这是一般的移动系统:)

或者,你可以在你的Makefile中有命令。 任务的任务是:

任务:
docker-compose stop service_name
docker-compose rm service_name
rm -f ./tmp/pids/server.pid(或者你的pid文件的相对path名)
docker-up up service_name

然后在terminal上make task ,然后回车。 上述任务命令假设您要运行的服务位于名为docker-compose.yml的文件中

如果名称不同,那么命令

docker-compose stop service_name – > docker-compose -f your-compose-filename.yml stop service_name

等等等等。

====================回来更新这个。 所以,我尝试注释掉我的write_pid方法function。 基本上保持方法的定义,但没有做任何事情。 目前运行良好。 它根本不写pid。 如果你在Docker上运行你的服务,我相信这是完全安全的。