【问题标题】:dockerize a Rails app, error Postgresdockerize 一个 Rails 应用程序,错误 Postgres
【发布时间】:2017-06-17 13:30:25
【问题描述】:

我正在尝试对 Rails 应用程序进行 dockerize。我得到的问题是我得到了这个错误:

PG::ConnectionBad: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

存放 Postgres 的 docker 容器(顺便说一句):

3e11664277b3        postgres:9.6.1      "/docker-entrypoint.s"   2 days ago          Up 33 minutes       0.0.0.0:15432->5432/tcp                    mystore_prod_db_1

包含以下数据库:

 Name        |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-------------------+----------+----------+------------+------------+-----------------------
 myshop_prod_db    | shopradu | UTF8     | en_US.utf8 | en_US.utf8 | 
 myshop_production | shopradu | UTF8     | en_US.utf8 | en_US.utf8 | 
 postgres          | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 shopradu          | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
 template1         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
(6 rows)

我可以使用以下命令手动连接用户 shopradu:

psql -d myshop_production -U shopradu

我的 .env.prod 文件:

POSTGRES_USER=shopradu
POSTGRES_PASSWORD=somePassword
POSTGRES_HOST=prod_db
RAILS_ENV=production
RAILS_SERVE_STATIC_FILES=true
SECRET_KEY_BASE=someKeyBase

database.yml:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>

development:
  <<: *default
  host: localhost
  username: radu
  password: devPassword
  database: mystore_dev

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  host: <%= ENV["POSTGRES_HOST"] %>
  database: myshop_production

docker-compose.prod.yml 文件:

version: "2"

volumes:
  assets:
    external: false
  configs:
    external: false
  db-data:
    external: false

services:
  webserver:
    image: "nginx:1.11.8"
    env_file: .env.prod
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - assets:/usr/share/nginx/html
      - configs:/etc/nginx/conf.d

  prod_db:    
    image: postgres:9.6.1
    ports:
    - "15432:5432"
    env_file: .env.prod
    volumes:
      - db-data:/var/lib/postgresql/data

  prod_app:
    build:
      context: .
      dockerfile: Dockerfile.prod
    env_file: .env.prod
    ports:
      - "3000:3000"
    volumes:
      - assets:/usr/share/nginx/html
      - configs:/etc/nginx/conf.d
    depends_on:
      - prod_db
- webserver

Docker 文件:

FROM ruby:2.2.5

RUN apt-get update -yqq \
  && apt-get install -yqq --no-install-recommends \
    postgresql-client \
    nodejs \
  && apt-get -q clean


# Pre-install gems with native extensions
RUN gem install nokogiri -v "1.6.8.1"

WORKDIR /usr/src/app
COPY Gemfile* ./
RUN bundle install
COPY . .

# Pre-compile assets
ENV RAILS_ENV production
RUN rake assets:precompile

CMD script/start

Production.rb 文件:

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true
  config.serve_static_files = true
  config.assets.compile = true
  config.assets.digest = true
  config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

  # Eager load code on boot. This eager loads most of Rails and
  # your application in memory, allowing both threaded web servers
  # and those relying on copy on write to perform better.
  # Rake tasks automatically ignore this option for performance.
  config.eager_load = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Enable Rack::Cache to put a simple HTTP cache in front of your application
  # Add `rack-cache` to your Gemfile before enabling this.
  # For large-scale production use, consider using a caching reverse proxy like
  # NGINX, varnish or squid.
  # config.action_dispatch.rack_cache = true

  # Disable Rails's static asset server (Apache or NGINX will already do this).
  config.serve_static_assets = false

  # Compress JavaScripts and CSS.
  config.assets.js_compressor = :uglifier
  # config.assets.css_compressor = :sass

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Asset digests allow you to set far-future HTTP expiration dates on all assets,
  # yet still be able to expire them through the digest params.
  config.assets.digest = true

  # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  config.force_ssl = !!ENV["RAILS_FORCE_SSL"].presence

  # Decrease the log volume.
  # config.log_level = :info

  # Prepend all log lines with the following tags.
  # config.log_tags = [ :subdomain, :uuid ]

  # Use a different logger for distributed setups.
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = 'http://assets.example.com'

  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation cannot be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new

  # Do not dump schema after migrations.
  config.active_record.dump_schema_after_migration = false
end

这里有什么问题吗? 谢谢!

【问题讨论】:

  • db容器的公共端口不是默认的:- "15432:5432",所以需要在rails databse.yml文件中指定。
  • 与 psql 连接而不提及主机通过 Unix 套接字连接。这是不同的权限。
  • 指定端口的语法是 port: 15432:5432 ?如果我没有在 docker.compose.prod.yml 中指定端口,这意味着我不应该使用端口修改 database.yml 文件?
  • 我认为你必须在你的数据库和你的 RAILS 应用程序之间使用一个链接。

标签: ruby-on-rails postgresql docker


【解决方案1】:

docker-compose.yml 中,您需要在prod_appprod_db 之间添加一个链接。排除当前配置,这是缺少的:

prod_app:
  links:
    - prod_db

这样做是将prod_db 添加到prod_app 图像中的/etc/hosts,这意味着您可以使用prod_db 作为POSTGRES_HOST 的值。

顺便说一句,database.yml 中的端口不需要更改。 docker-compose.yml 中的 ports 指令将主机上的端口映射到容器上的端口。语法为HOST:CONTAINER,意思是15672:5672 将主机(即您的机器)上的端口15672 映射到容器上的端口5672。仅当您想从主机连接到容器时才需要。容器之间不需要此端口映射来进行通信。只要您链接两个容器,它们就可以在其所有端口上相互通信。

【讨论】:

  • 它仍然无法正常工作。当我尝试以 shopradu 用户 psql -h prod_db -p 5432 -U shopradu -W somePassword myshop_production >>> 的身份手动连接到数据库时,它要求输入密码,我在 .env.prod somePassword 中提供密码。比我得到错误 psql: invalid port number: "5432" 我使用 ALTER USER shopradu WITH PASSWORD 'somePassword' 确保用户 shopradu 具有 .env.prod 文件中提供的密码;从 postgres 控制台。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 2019-07-22
  • 2023-02-14
  • 2023-03-12
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
相关资源
最近更新 更多