Docker (rails, postgresql) 启动时挂起,而不是连接到数据库

Docker (rails, postgresql) hanging when started, rather than connecting to DB

我是 docker 的新手,正在尝试了解为什么我的 Docker 设置挂起并且没有像我预期的那样连接。

我是 运行

我的设置基于我发现的 Gist

为了更好地展示问题,我将其缩小了一些。

Docker文件

FROM ruby:2.4

ARG DEBIAN_FRONTEND=noninteractive

RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" >> /etc/apt/sources.list.d/postgeresql.list \
 && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
 && apt-get update                                     \
 && apt-get update                                     \
 && apt-get install -y --no-install-recommends apt-utils \
 && apt-get install -y build-essential \
 && apt-get install -y nodejs \
 && apt-get install -y --no-install-recommends         \
   postgresql-client-9.6 pv ack-grep ccze unp htop vim \
 && apt-get install -y libxml2-dev libxslt1-dev \
 && rm -rf /var/lib/apt/lists/*                        \
 && apt-get purge -y --auto-remove

# Set environment
ENV APP_HOME /usr/src/app
ENV BUNDLER_VERSION 2.0.2

# Setup bundler
RUN gem install bundler -v $BUNDLER_VERSION

WORKDIR $APP_HOME

EXPOSE 7051

CMD ["bundle", "exec", "puma", "-p", "7051", "-C", "config/puma.rb"]

docker_compose.yml

version: '3.1'
services:
  app: &app_base
    build: .
    working_dir: /usr/src/app
    volumes:
      - .:/usr/src/app
      # to be able to forward ssh-agent to github through capistrano (bundle on server)
      - "~/.ssh/id_rsa:/root/.ssh/id_rsa"
      - $SSH_AUTH_SOCK:$SSH_AUTH_SOCK
    environment: &app_environment
      # to keep bundle effect between container restarts (without rebuild):
      BUNDLE_PATH: /usr/src/app/.bundle
      BUNDLE_APP_CONFIG: /usr/src/app/.bundle
      DATABASE_HOST: db
      SSH_AUTH_SOCK: # this left empty copies from outside env
    env_file: '.env'
    ports:
      - "7051:7051"
    depends_on:
      - db

  db:
    image: postgres:9.5.17
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: my_project_development
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root

config/database.yml

development:
  adapter: postgresql
  encoding: unicode
  pool: 5
  database: my_project_development
  username: root
  password: root
  host: db

config/puma.rb

threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port        ENV.fetch("PORT") { 7051 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

所以我正在做的是:

  1. 运行 docker-compose build 首先构建镜像和容器
  2. 运行 docker-compose run --rm app bundle install 安装 gems
  3. 运行 docker-compose run --rm app bundle exec rake db:create db:migrate db:seed 到 create/migrate/seed 数据库

步骤 3. 是我卡住的步骤。它只是挂在那里没有反馈:

docker-compose run --rm app bundle exec rake db:create db:migrate db:seed
Starting my_project_db_1 ... done

我知道数据库是 运行,因为我可以在本地连接到它。

我还可以登录 app 容器,并通过 psql 连接,所以我知道 app 容器可以与 db 容器通信:

docker exec -it f6d6edadaed4 /bin/bash                                                                                       (52s 699ms)
root@f6d6edadaed4:/usr/src/app# psql "postgresql://root:root@db:5432/my_project_development"
psql (9.6.14, server 9.5.17)
Type "help" for help.

my_project_development=# \dt
No relations found.

如果我尝试使用 docker-compose up 启动应用程序,那么它也会挂起:

app_1  | Puma starting in single mode...
app_1  | * Version 3.11.4 (ruby 2.4.6-p354), codename: Love Song
app_1  | * Min threads: 5, max threads: 5
app_1  | * Environment: ci

即puma 通常会在连接后显示 'listening' 消息:

* Listening on tcp://0.0.0.0:7051
Use Ctrl-C to stop

但还没有到那个地步,它只是挂起。

这是怎么回事?为什么我的 Rails 容器不能直接连接到 PostgreSQL 容器并让 puma 正常启动?

更多信息:

我现在知道了,如果我等待 10 分钟以上,它最终会启动!

在那 10 分钟里,我的 CPU 粉丝疯狂地旋转,所以它真的在想一些事情。

但是当它完成时,CPU 风扇关闭,puma 已经启动,我可以像我期望的那样在 http://127.0.0.1:7051 本地访问它。

为什么启动这么慢?我的机器在其他方面相当快。

我认为 OSX 上的 Docker 非常慢。我已经阅读了一些性能问题 here

向卷添加 cached 选项似乎已将启动时间减少到 ~2 分钟

version: '3.1'
services:
  app: &app_base
    build: .
    working_dir: /usr/src/app
    volumes:
      - .:/usr/src/app:cached
    ...

在我看来还是不太能接受。想知道还有什么可以做的吗?

我找到了一个实际可行的答案,我也张贴在这里:

基本上,请参阅 the article here 了解如何正确设置 Dockerfiledocker-compose.yml,以便它在 OSX 上表现良好。

主要了解一下:

To make Docker fast enough on MacOS follow these two rules: use :cached to mount source files and use volumes for generated content (assets, bundle, etc.).

所以如果其他人遇到这个,请按照文章或查看我的其他答案。