我正在尝试"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:
由于您使用的是官方的 postgres docker 容器,因此官方文档包含一些相关信息:
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_USER
和 POSTGRES_PASSWORD
.我使用您的docker-compose.yml
和Dockerfile
在本地使用示例应用程序对此进行了测试,我需要:
- 将
POSTGRES_USER
和POSTGRES_PASSWORD
添加到相应env
/environment
的web
和postgres
部分(您需要将它们添加到要包含的.env
文件中) - 将
username
键和password
键添加到相关部分中的database.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
等,而上述更改没有问题。