为什么docker化的Rails应用会引发“ PG :: ConnectionBad”?

时间:2019-01-03 01:20:33

标签: ruby-on-rails docker

我正在尝试“ dockerize”现有的Rails开发应用程序。这是我第一次尝试Docker。

在网上搜索和阅读了大量信息之后,我终于设法建立了一个容器并运行了以下几种服务:app,postgres,redis,sidekiq和Guard。

但是我无法连接到数据库。

Starting postgres ... done
Starting redis    ... done
rails aborted!
PG::ConnectionBad: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Address not available
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432? 

毫无疑问,有一个简单的配置被我忽略了,但是我一直无法弄清楚是什么,也找不到合适的指南。

我确实注意到IP地址似乎不匹配。

$ docker-compose ps
Name                  State   Ports
------------------------------------------------------
postgres              Up      0.0.0.0:5432->5432/tcp

最严重的错误表明postgres应该位于127.0.0.1。这可能是原因吗?

有人能指出我正确的方向吗?

Dockerfile

# Dockerfile
FROM ruby:2.4-alpine

# Install runtime dependencies
RUN apk add --update --virtual runtime-deps postgresql-client nodejs libffi-dev readline-dev yarn git

RUN apk add --virtual build-deps build-base postgresql-dev libc-dev linux-headers libxml2-dev libxslt-dev readline-dev git 

# Copy the app's code into the container
ENV APP_HOME /app
COPY . $APP_HOME
WORKDIR $APP_HOME

# Budnle gems
RUN bundle install --jobs 4

# Install Yarn packages
RUN yarn install
RUN yarn upgrade

# Configure production environment variables
ENV RAILS_ENV=production \
    RACK_ENV=production

# Expose port 3000 from the container
EXPOSE 3000

# Run puma server
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

docker-compose.yml

version: '3'

services:
  postgres:
    container_name: postgres
    ports:
      - "5432:5432"
    volumes:
      - $HOME/postgres-data:/var/lib/postgresql
    image: postgres:9.6.9

  redis:
    container_name: redis
    ports:
      - "6379:6379"
    links:
      - postgres
    image: redis:5.0-rc

  web:
    container_name: web
    build: .
    ports:
      - "3000:3000"
    command: /bin/sh -c "rails s -b 0.0.0.0 -p 3000"
    env_file:
      - .env
    links:
      - postgres
      - redis

  guard:
    build: .
    env_file:
      - .env
    command: bundle exec guard --no-bundler-warning --no-interactions

  sidekiq:
    build: .
    command: bundle exec sidekiq -C config/sidekiq.yml
    links:
      - postgres
      - redis
    env_file:
      - .env

volumes:
  redis:
  postgres:
  sidekiq:
  guard:

1 个答案:

答案 0 :(得分:1)

由于您使用的是官方的postgres Docker容器,因此official documentation具有一些相关信息:

The PostgreSQL image sets up trust authentication locally so you may 
notice a password is not required when connecting from localhost 
(inside the same container). However, a password will be required 
if connecting from a different host/container.

由于您不在同一个容器中,因此可能需要使用POSTGRES_USERPOSTGRES_PASSWORD。我使用您的docker-compose.ymlDockerfile在本地使用示例应用程序对此进行了测试,我需要:

  • POSTGRES_USERPOSTGRES_PASSWORD分别添加到web / postgres中的envenvironment部分中(您将添加它们到您要包含的.env文件中)
  • 在相关部分的username上添加passworddatabase.yml键,以提取我在上面设置的环境变量

database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: postgres
  pool: 5
  timeout: 5000
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>

通过这些更改,我能够从Web容器连接到postgres容器/数据库。

我的docker-compose ps显示与您的相似:

   Name                      Command                State             Ports
----------------------------------------------------------------------------------------
hello_app_sidekiq_1   bundle exec sidekiq -C con ...   Exit 127
postgres              docker-entrypoint.sh postgres    Up         0.0.0.0:5432->5432/tcp
redis                 docker-entrypoint.sh redis ...   Up         0.0.0.0:6379->6379/tcp
web                   /bin/sh -c bundle exec rai ...   Up         0.0.0.0:3000->3000/tcp

我能够运行docker-compose run --rm web /bin/ash并进入rails console,运行rails db:migrate等,而不会发生上述更改。