为什么我的Docker PostgreSQL容器不再运行?

11

自从我将Docker Desktop for Windows从2.1.0.5更新到版本2.2.0.3后,我的应用程序的db容器就出现了问题。在2.1.0.5上一切正常,但现在即使我已经卸载了2.2.0.3并恢复到2.1.0.5,仍然无法工作。现在真希望我没有更新。

我得到的错误是:

could not translate host name "db" to address: Name or service not known
当我运行docker ps命令时,我发现postgres容器甚至没有运行。
一些我尝试过的事情是:
1. 在我的Windows 10 hosts文件中添加db。 2. 在docker-compose.yml中为db暴露端口5432。
但是都没有起作用。
是否有人能够提供任何见解来帮助我理解和解决问题?
我的Docker文件:
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /my-app
WORKDIR /my-app
RUN echo 'gem: --no-document' >> ~/.gemrc
COPY . /my-app
EXPOSE 3000

我的docker-compose.yml文件:

version: '3'
services:
  db:
    image: postgres
    volumes:
      - postgres:/var/lib/postgresql/data/
  redis:
    image: 'redis:4-alpine'
    environment:
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
    ports:
      - '6379:6379'
    command: redis-server --requirepass somepassword
    volumes:
      - redis:/data/
  myapp:
    build: ./myapp/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      - RAILS_ENV=development
      - PORT=3000
      - REDIS_URL=redis://:somepassword@redis:6379/0
    ports:
      - '3000:3000'
    working_dir: /myapp/
    volumes:
      - ./myapp:/myapp:cached
      - myapp_gems:/usr/local/bundle/
      - /myapp/tmp/
    depends_on:
      - db
      - redis
  myapp_sidekiq:
    build: ./myapp/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec sidekiq -C config/sidekiq.yml"
    environment:
      - RAILS_ENV=development
      - PORT=3000
      - REDIS_URL=redis://:somepassword@redis:6379/0
    working_dir: /myapp/
    volumes:
      - ./myapp:/myapp:cached
      - myapp_gems:/usr/local/bundle/
      - /myapp/tmp/
    depends_on:
      - db
      - redis

volumes:
  postgres:
    external: true
  redis:
    external: true
  myapp_gems:

我的database.yml文件:

# Configure Using Gemfile
# gem 'pg'
#
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: 5
  host: db
  username: postgres
  password:

编辑:针对 @Brits 的回应,这里是运行 docker-compose up db 的输出:

Attaching to dev_db_1
db_1                | Error: Database is uninitialized and superuser password is not specified.      
db_1                |        You must specify POSTGRES_PASSWORD to a non-empty value for the
db_1                |        superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".
db_1                | 
db_1                |        You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
db_1                |        connections without a password. This is *not* recommended.     
db_1                | 
db_1                |        See PostgreSQL documentation about "trust":
db_1                |        https://www.postgresql.org/docs/current/auth-trust.html        
dev_db_1 exited with code 1

这很有趣,因为我之前没有指定POSTGRES_PASSWORD,但它却可以正常工作。

感谢@Brits的帮助,我成功找到了问题所在。最近,docker-library/postgres进行了一个低调的更改,从现在开始默认要求指定POSTGRES_PASSWORD,详见此Github问题


如果postgres容器没有运行,那么它可能会遇到错误并退出。运行docker-compose up db并查看输出结果。 - Brits
@Brits 我已经更新了原始问题,并附上了 docker-compose up db 的输出。 - NeyLive
数据库配置文件长什么样? - Daniel
请您检查卷的内容(docker volume inspect postgres,然后显示由Mountpoint指向的文件夹中的内容)。 - Brits
很棒,你解决了这个问题 - 或许将其作为答案发布(在你自己的问题下),这样任何其他人查看时都清楚你已经解决了它(答案上方有相当多的文本 :-) - Brits
1个回答

12

感谢@Brits帮我找到了问题所在。

这是由于docker-library/postgres最近进行了一项低调的更改,要求默认情况下必须指定POSTGRES_PASSWORD,正如此Github问题中所指出的那样。

以下是解决办法:

将POSTGRES_PASSWORD作为环境变量添加到docker-compose.yml(postgres容器以及应用程序容器)中:

version: '3'
services:
  db:
    image: postgres
    environment:
      - POSTGRES_PASSWORD=somepassword
    volumes:
      - postgres:/var/lib/postgresql/data/
  redis:
    image: 'redis:4-alpine'
    environment:
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
    ports:
      - '6379:6379'
    command: redis-server --requirepass somepassword
    volumes:
      - redis:/data/
  myapp:
    build: ./myapp/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      - RAILS_ENV=development
      - PORT=3000
      - REDIS_URL=redis://:somepassword@redis:6379/0
      - POSTGRES_PASSWORD=somepassword
    ports:
      - '3000:3000'
    working_dir: /myapp/
    volumes:
      - ./myapp:/myapp:cached
      - myapp_gems:/usr/local/bundle/
      - /myapp/tmp/
    depends_on:
      - db
      - redis
  myapp_sidekiq:
    build: ./myapp/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec sidekiq -C config/sidekiq.yml"
    environment:
      - RAILS_ENV=development
      - PORT=3000
      - REDIS_URL=redis://:somepassword@redis:6379/0
    working_dir: /myapp/
    volumes:
      - ./myapp:/myapp:cached
      - myapp_gems:/usr/local/bundle/
      - /myapp/tmp/
    depends_on:
      - db
      - redis

volumes:
  postgres:
    external: true
  redis:
    external: true
  myapp_gems:

然后在应用程序的database.yml文件中添加POSTGRES_PASSWORD的ENV变量:

# Configure Using Gemfile
# gem 'pg'
#
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: 5
  host: db
  username: postgres
  password: <%= ENV['POSTGRES_PASSWORD'] %>

2
如果您不想直接将密码放在 docker-compose 文件中,可以将其放在 .env 文件中,然后使用 env_file: .env 将其添加到服务中。 - David Gay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接