英文:
Connecting a Dockerized Ruby on Rails WebApp to an external Azure Hosted Postgres Database
问题
I have translated the relevant parts of your text:
Background that can be skipped
这个Web应用是非营利组织的众多应用之一。我们正在将所有的Web资源迁移到Microsoft Azure以降低总体成本。我们目前已将数据库转移到Azure,并所有的Ruby on Rails Web应用都在Heroku上运行。我们需要将我们的Web应用程序Docker化,因为似乎Azure将不再支持Ruby作为独立的语言。一旦它们被Docker化,我们将需要部署到Azure。
What Needs to Happen
我们计划扩展性,因此每个Web应用程序都需要能够运行多个实例,所有这些实例都连接到托管在Azure上的中央数据库。
这个RoR应用程序,目前在Heroku上运行,连接到两个不同的数据库;一个用于会员登录,另一个用于应用程序特定的数据。这是因为有多个站点使用相同的中央会员登录数据库,并有自己的应用程序特定数据库。一旦RoR应用程序在Docker镜像中,它应该包括RoR代码的模板,以及SideKiq和Redis。这样,当容器被创建时,代码将运行并连接到外部的Postgres数据库。
The Problem
每次我尝试查找解决方案时,我都会得到与在Docker容器内连接到Postgres数据库、连接到本地托管的数据库或一系列其他情况相关的结果。我已经花了几周的时间研究这个问题,我确定我错过了一些简单的东西,因为这似乎应该是一个直截了当的情况。
My development Environment
- Ruby版本: 3.2.1
- Rails版本: 7.0.4.2
- Redis: 4.1.4
- DB(1)位置:托管在Microsoft Azure上
- DB(2)位置:托管在Microsoft Azure上
Code
database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
primary:
<<: *default
url: <%= ENV['DB_URL'] %>
migrations_paths: db/migrate
members:
<<: *default
url: <%= ENV['MEMBER_DB_URL'] %>
migrations_paths: db/member_migrate
test:
primary:
<<: *default
database: app_primary_test
migrations_paths: db/migrate
members:
<<: *default
database: members_test
migrations_paths: db/member_migrate
production:
primary:
<<: *default
url: <%= ENV['DB_URL'] %>
members:
<<: *default
url: <%= ENV['MEMBER_DB_URL'] %>
Dockerfile
# 使用官方的Ruby运行时作为父镜像
FROM ruby:3.2.1
# 设置工作目录
WORKDIR /app
# 安装依赖项
RUN apt-get update && \
apt-get install -y \
build-essential \
nodejs \
postgresql-client && \
rm -rf /var/lib/apt/lists/*
# 安装gems
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && \
bundle install --jobs 4
# 复制应用程序代码
COPY . .
# 暴露端口
EXPOSE 3000
# 设置入口命令
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
ports:
- "3000:3000"
depends_on:
- db
- redis
db:
image: postgres:12
environment:
- BUNDLE_WITHOUT=${BUNDLE_WITHOUT}
- DB_DATABASE=${DB_DATABASE}
- DB_HOST=${DB_HOST}
- DB_PASSWORD=${DB_PASSWORD}
- DB_PORT=${DB_PORT}
- DB_URL=${DB_URL}
- DB_USERNAME=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_DB=${DB_DATABASE}
- MEMBER_DB_DATABASE=${MEMBER_DB_DATABASE}
- MEMBER_DB_HOST=${MEMBER_DB_HOST}
- MEMBER_DB_PASSWORD=${MEMBER_DB_PASSWORD}
- MEMBER_DB_PORT=${MEMBER_DB_PORT}
- MEMBER_DB_URL=${MEMBER_DB_URL}
- MEMBER_DB_USERNAME=${MEMBER_DB_USERNAME}
- DEPLOYMENT_BRANCH=${DEPLOYMENT_BRANCH}
- MEMBERS_BUCKET_AWS=${MEMBERS_BUCKET_AWS}
- MAILGUN_API_KEY=${MAILGUN_API_KEY}
- MAILGUN_DOMAIN=${MAILGUN_DOMAIN}
- RAILS_ENV=${RAILS_ENV}
- RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
- RECAPTCHA_SECRET_KEY=${RECAPTCHA_SECRET_KEY}
- RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY}
- SECRET_ACCESS_KEY_A
<details>
<summary>英文:</summary>
First, let me say, I have tried so many different search terms for weeks now and have not found an answer. So, the title to this question is very specific to what I am needing to do.
**Background that can be skipped**
This webapp is one of many for a non-profit organization. We are moving all our web resources to Microsoft Azure to reduce overall costs. We currently have our databases transferred to Azure, and all Ruby on Rails WebApps running on Heroku. We are needing to change our WebApps to be Dockerized as it seems Azure will soon not support Ruby as a stand alone language. Once they are Dockerized, we will need to deploy to Azure.
**What Needs to Happen**
We are planning on scalability, so each WebApp will need to be able to have multiple instances running all of which connect to central databases hosted on Azure.
This RoR app, currently running on Heroku, connects to 2 different databases; one for member logins and the other for the app specific data. This is because there are multiple sites that utilize the same central member login database and have their own app specific database.
Once the RoR app is in a Docker image, it should have the template for the RoR code as well as SideKiq and Redis. That way when containers are made, the code will run with SideKiq and Redis and access the external Postgres Databases.
**The Problem**
Every time I search to try and find a solution, I get results about connecting to a Postgres DB within a Docker Container, or connecting to a locally hosted DB, or a host of other scenarios. I have spent weeks researching this and I am sure that I am missing something simple as it seems like this should be a straight forward situation.
**My development Environment**
- Ruby version: 3.2.1
- Rails version: 7.0.4.2
- Redis: 4.1.4
- DB (1)location: Hosted on Microsoft Azure
- DB (2) location: Hosted on Microsoft Azure
**Code**
`database.yml`
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
primary:
<<: *default
url: <%= ENV['DB_URL'] %>
migrations_paths: db/migrate
members:
<<: *default
url: <%= ENV['MEMBER_DB_URL'] %>
migrations_paths: db/member_migrate
test:
primary:
<<: *default
database: app_primary_test
migrations_paths: db/migrate
members:
<<: *default
database: members_test
migrations_paths: db/member_migrate
production:
primary:
<<: *default
url: <%= ENV['DB_URL'] %>
members:
<<: *default
url: <%= ENV['MEMBER_DB_URL'] %>
`Dockerfile`
# Use an official Ruby runtime as a parent image
FROM ruby:3.2.1
# Set the working directory
WORKDIR /app
# Install dependencies
RUN apt-get update && \
apt-get install -y \
build-essential \
nodejs \
postgresql-client && \
rm -rf /var/lib/apt/lists/*
# Install gems
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && \
bundle install --jobs 4
# Copy the application code
COPY . .
# Expose ports
EXPOSE 3000
# Set the entrypoint command
CMD ["rails", "server", "-b", "0.0.0.0"]
`docker-compose.yml`
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
ports:
- "3000:3000"
depends_on:
- db
- redis
db:
image: postgres:12
environment:
- BUNDLE_WITHOUT=${BUNDLE_WITHOUT}
- DB_DATABASE=${DB_DATABASE}
- DB_HOST=${DB_HOST}
- DB_PASSWORD=${DB_PASSWORD}
- DB_PORT=${DB_PORT}
- DB_URL=${DB_URL}
- DB_USERNAME=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_DB=${DB_DATABASE}
- MEMBER_DB_DATABASE=${MEMBER_DB_DATABASE}
- MEMBER_DB_HOST=${MEMBER_DB_HOST}
- MEMBER_DB_PASSWORD=${MEMBER_DB_PASSWORD}
- MEMBER_DB_PORT=${MEMBER_DB_PORT}
- MEMBER_DB_URL=${MEMBER_DB_URL}
- MEMBER_DB_USERNAME=${MEMBER_DB_USERNAME}
- DEPLOYMENT_BRANCH=${DEPLOYMENT_BRANCH}
- MEMBERS_BUCKET_AWS=${MEMBERS_BUCKET_AWS}
- MAILGUN_API_KEY=${MAILGUN_API_KEY}
- MAILGUN_DOMAIN=${MAILGUN_DOMAIN}
- RAILS_ENV=${RAILS_ENV}
- RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
- RECAPTCHA_SECRET_KEY=${RECAPTCHA_SECRET_KEY}
- RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY}
- SECRET_ACCESS_KEY_AWS=${SECRET_ACCESS_KEY_AWS}
- SECRET_KEY_BASE=${SECRET_KEY_BASE}
redis:
image: redis:7.0.0
And then each of the variables are defined in a `.env` file in the `root` directory along side the `Dockerfile` and `docker-compose.yml` files.
**Final Information**
Now, I am not sure if all of those environment variables need to be there, or how secure it is to have them there. (I am used to storing them within the app Settings on Heroku, not within the code itself.)
The `POSTGRES_USER`, `POSTGRES_PASSWORD` and `POSTGRES_DB` I put there because of another StackOverflow answer which made me think that there are system default ENV variable names that need to be used. (Again, not sure if that is the case or not)
The `DB_URL` and `MEMBER_DB_URL` are single strings (again which Heroku uses) that combines the username, password, host, port, etc for connecting to the DB. In short all things that someone would need to gain access to the data. (Security wise that scares me a bit)
(EDIT: Per comment request here are the URLs with sensitive info removed.)
DB_URL: postgres://<user_name>:<password>@<server_url>/<db_name>?sslmode=require
MEMBER_DB_URL: postgres://<user_name>:<password>@<server_url>/<member_db_name>?sslmode=require
Please Note that I am able to connect to the Azure databases using PgAdmin4 on my local machine via this information and the URL strings are the same as in Heroku and that app can connect to the databases.
**ERROR Message**
Here is the error message when I run Rails console from within the shell.
# rails c
Loading development environment (Rails 7.0.4.2)
irb(main):001:0> Member.first
/usr/local/bundle/gems/activerecord-7.0.4.2/lib/active_record/connection_adapters/postgresql_adapter.rb:87:in `rescue in new_client': could not connect to server: No such file or directory (ActiveRecord::ConnectionNotEstablished)
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
/usr/local/bundle/gems/pg-1.4.5/lib/pg/connection.rb:755:in `connect_start': could not connect to server: No such file or directory (PG::ConnectionBad)
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Here is the error log when I try and pull up `localhost:3000`
2023-02-27 09:50:58 => Booting Puma
2023-02-27 09:50:58 => Rails 7.0.4.2 application starting in development
2023-02-27 09:50:58 => Run `bin/rails server --help` for more startup options
2023-02-27 09:51:00 [1] Puma starting in cluster mode...
2023-02-27 09:51:00 [1] * Version 4.2.1 (ruby 3.2.1-p31), codename: Distant Airhorns
2023-02-27 09:51:00 [1] * Min threads: 5, max threads: 5
2023-02-27 09:51:00 [1] * Environment: development
2023-02-27 09:51:00 [1] * Process workers: 2
2023-02-27 09:51:00 [1] * Preloading application
2023-02-27 09:51:00 [1] * Listening on tcp://0.0.0.0:3000
2023-02-27 09:51:00 [1] Use Ctrl-C to stop
2023-02-27 09:51:00 [1] - Worker 1 (pid: 16) booted, phase: 0
2023-02-27 09:51:00 [1] - Worker 0 (pid: 13) booted, phase: 0
2023-02-27 10:31:19 DEPRECATION WARNING: Non-URL-safe CSRF tokens are deprecated. Use 6.1 defaults or above. (called from block (3 levels) in <class:Railtie> at /usr/local/bundle/gems/actionpack-7.0.4.2/lib/action_controller/railtie.rb:80)
2023-02-27 10:31:19 Started GET "/" for 172.20.0.1 at 2023-02-27 17:31:19 +0000
2023-02-27 10:31:19 Cannot render console from 172.20.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
2023-02-27 10:31:19
2023-02-27 10:31:19 ActiveRecord::ConnectionNotEstablished (could not connect to server: No such file or directory
2023-02-27 10:31:19 Is the server running locally and accepting
2023-02-27 10:31:19 connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
2023-02-27 10:31:19 ):
2023-02-27 10:31:19
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/postgresql_adapter.rb:87:in `rescue in new_client'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/postgresql_adapter.rb:77:in `new_client'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/postgresql_adapter.rb:37:in `postgresql_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:656:in `public_send'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:656:in `new_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:700:in `checkout_new_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:679:in `try_to_checkout_new_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:640:in `acquire_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:341:in `checkout'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_adapters/abstract/connection_handler.rb:211:in `retrieve_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_handling.rb:313:in `retrieve_connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/connection_handling.rb:280:in `connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/migration.rb:613:in `connection'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/migration.rb:608:in `build_watcher'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/migration.rb:590:in `block in call'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/migration.rb:589:in `synchronize'
2023-02-27 10:31:19 activerecord (7.0.4.2) lib/active_record/migration.rb:589:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
2023-02-27 10:31:19 activesupport (7.0.4.2) lib/active_support/callbacks.rb:99:in `run_callbacks'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
2023-02-27 10:31:19 web-console (4.2.0) lib/web_console/middleware.rb:132:in `call_app'
2023-02-27 10:31:19 web-console (4.2.0) lib/web_console/middleware.rb:19:in `block in call'
2023-02-27 10:31:19 web-console (4.2.0) lib/web_console/middleware.rb:17:in `catch'
2023-02-27 10:31:19 web-console (4.2.0) lib/web_console/middleware.rb:17:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/show_exceptions.rb:26:in `call'
2023-02-27 10:31:19 railties (7.0.4.2) lib/rails/rack/logger.rb:40:in `call_app'
2023-02-27 10:31:19 railties (7.0.4.2) lib/rails/rack/logger.rb:25:in `block in call'
2023-02-27 10:31:19 activesupport (7.0.4.2) lib/active_support/tagged_logging.rb:99:in `block in tagged'
2023-02-27 10:31:19 activesupport (7.0.4.2) lib/active_support/tagged_logging.rb:37:in `tagged'
2023-02-27 10:31:19 activesupport (7.0.4.2) lib/active_support/tagged_logging.rb:99:in `tagged'
2023-02-27 10:31:19 railties (7.0.4.2) lib/rails/rack/logger.rb:25:in `call'
2023-02-27 10:31:19 sprockets-rails (3.4.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/request_id.rb:26:in `call'
2023-02-27 10:31:19 rack (2.2.6.2) lib/rack/method_override.rb:24:in `call'
2023-02-27 10:31:19 rack (2.2.6.2) lib/rack/runtime.rb:22:in `call'
2023-02-27 10:31:19 activesupport (7.0.4.2) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
2023-02-27 10:31:19 rack-livereload (0.3.17) lib/rack/livereload.rb:23:in `_call'
2023-02-27 10:31:19 rack-livereload (0.3.17) lib/rack/livereload.rb:14:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/static.rb:23:in `call'
2023-02-27 10:31:19 rack (2.2.6.2) lib/rack/sendfile.rb:110:in `call'
2023-02-27 10:31:19 actionpack (7.0.4.2) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
2023-02-27 10:31:19 webpacker (5.4.4) lib/webpacker/dev_server_proxy.rb:25:in `perform_request'
2023-02-27 10:31:19 rack-proxy (0.7.6) lib/rack/proxy.rb:87:in `call'
2023-02-27 10:31:19 railties (7.0.4.2) lib/rails/engine.rb:530:in `call'
2023-02-27 10:31:19 puma (4.2.1) lib/puma/configuration.rb:228:in `call'
2023-02-27 10:31:19 puma (4.2.1) lib/puma/server.rb:667:in `handle_request'
2023-02-27 10:31:19 puma (4.2.1) lib/puma/server.rb:470:in `process_client'
2023-02-27 10:31:19 puma (4.2.1) lib/puma/server.rb:328:in `block in run'
2023-02-27 10:31:19 puma (4.2.1) lib/puma/thread_pool.rb:134:in `block in spawn_thread'
2023-02-27 10:31:19 #<Errno::EADDRNOTAVAIL: Failed to open TCP connection to localhost:35729 (Cannot assign requested address - connect(2) for "localhost" port 35729)>
2023-02-27 10:31:19 2023-02-27 17:31:19 +0000: Rack app error handling request { GET / }
2023-02-27 10:31:19 #<Errno::EADDRNOTAVAIL: Failed to open TCP connection to localhost:35729 (Cannot assign requested address - connect(2) for "localhost" port 35729)>
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1271:in `initialize'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1271:in `open'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1271:in `block in connect'
2023-02-27 10:31:19 /usr/local/bundle/gems/timeout-0.3.2/lib/timeout.rb:189:in `block in timeout'
2023-02-27 10:31:19 /usr/local/bundle/gems/timeout-0.3.2/lib/timeout.rb:196:in `timeout'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1269:in `connect'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1248:in `do_start'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1237:in `start'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1817:in `request'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/net/http.rb:1797:in `send_request'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:50:in `use_vendored?'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:101:in `livereload_source'
2023-02-27 10:31:19 (erb):14:in `block (2 levels) in process!'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/erb.rb:429:in `eval'
2023-02-27 10:31:19 /usr/local/lib/ruby/3.2.0/erb.rb:429:in `result'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:78:in `block (2 levels) in process!'
2023-02-27 10:31:19 /usr/local/bundle/gems/activesupport-7.0.4.2/lib/active_support/core_ext/string/output_safety.rb:313:in `block in gsub!'
2023-02-27 10:31:19 /usr/local/bundle/gems/activesupport-7.0.4.2/lib/active_support/core_ext/string/output_safety.rb:311:in `gsub!'
2023-02-27 10:31:19 /usr/local/bundle/gems/activesupport-7.0.4.2/lib/active_support/core_ext/string/output_safety.rb:311:in `gsub!'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:78:in `block in process!'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:76:in `each'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb:76:in `process!'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload.rb:28:in `_call'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-livereload-0.3.17/lib/rack/livereload.rb:14:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/actionpack-7.0.4.2/lib/action_dispatch/middleware/static.rb:23:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-2.2.6.2/lib/rack/sendfile.rb:110:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/actionpack-7.0.4.2/lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/webpacker-5.4.4/lib/webpacker/dev_server_proxy.rb:25:in `perform_request'
2023-02-27 10:31:19 /usr/local/bundle/gems/rack-proxy-0.7.6/lib/rack/proxy.rb:87:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/railties-7.0.4.2/lib/rails/engine.rb:530:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/puma-4.2.1/lib/puma/configuration.rb:228:in `call'
2023-02-27 10:31:19 /usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:667:in `handle_request'
2023-02-27 10:31:19 /usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:470:in `process_client'
2023-02-27 10:31:19 /usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:328:in `block in run'
2023-02-27 10:31:19 /usr/local/bundle/gems/puma-4.2.1/lib/puma/thread_pool.rb:134:in `block in spawn_thread'
**Question**
What am I missing? Am I not declaring the ENV correctly for Docker? Does it have to do with Docker's unique networking setup? I would think this should be straight forward as I am sure I am not the only one that will have multiple Docker containers needing access to a centralized database. Please help! I'll buy you a coffee ;-) Or send out good thoughts and vibes to you.
Thank you for your help!
</details>
# 答案1
**得分**: 0
我找出了我的错误所在。它在我的 `docker-compose.yml` 文件中。我在数据库服务下设置了环境变量 (ENV),而不是在 web 服务下设置。因此,尽管数据库具有连接所需的值,但 Web 应用程序却没有,因此 `database.yml` 文件没有获得所需的连接值。
现在,我以为它会像在开发环境中一样从 `.env` 文件中获取值,但就像它们需要在Heroku设置中列出的那样,它们需要在这里列出。(尽管现在我遇到了另一个问题,我将发布一个新问题。[在这里][1])
**解释**
在 `docker-compose.yml` 文件中,您基本上指定了在 Docker 容器中将运行什么。现在,我将“运行”用引号括起来,因为从技术上讲情况并非如此,我将在逐步浏览文件时解释这一点。
*首先是设置*
基本的 `docker-compose.yml` 文件
version: "3"
services:
web:
db:
redis:
这告诉 Docker Compose 使用的 composer 版本是什么(版本 3),容器中将有 3 个服务:Web 应用程序、数据库连接和 Redis 数据存储。
接下来,您需要解释每个服务的信息。
扩展的 `docker-compose.yml` 文件
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3100 -b '0.0.0.0'
ports:
- "3100:3100"
environment:
# 在这里放置环境变量
depends_on:
- db
- redis
db:
image: postgres:12
ports:
- "5432:5432"
environment:
# 放置连接变量
redis:
image: redis:7.0.0
让我们从底部开始:
*在 `redis` 服务下*
- 这里的信息说明 Docker Compose 应该从在线获取 Redis 映像以创建 Redis 数据存储(即版本 7.0.0)。
*在 `db` 服务下*
- 这里的信息说明 Docker Compose 应该从在线获取 PostgreSQL 映像以创建数据库和/或了解数据库结构应该如何(即版本 12)。这是“从技术上来说并不运行”的地方。容器中没有运行 PostgreSQL 数据库,但这里的信息是必需的,因为正在运行的 Web 应用程序依赖于连接(稍后详细说明)。
- 然后说明了访问数据库的端口(即 5432),如果在容器中找到数据库,则需要;否则不需要。
- 然后说明了访问数据库所需的变量。
*在 `web` 服务下*
- 这里的信息告诉 Docker Compose 从 `Dockerfile` 构建。
- 然后运行服务器。注意:我将端口 3100 指定为在我的计算机上运行 Rails 应用程序而不是 Docker 容器;但是,如果您希望,可以将其更改为 3000。
- 然后指定要释放用于访问 Web 应用程序的端口(应该与上述步骤中指定的相同)。
- 然后指定应用程序内部所需的任何环境变量。
- 然后指定应用程序依赖的内容,即数据库和 Redis 数据存储。如果这些内容不可访问,容器和 Web 应用程序将失败。
因此,我的最终 `docker-compose.yml` 文件如下:
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3100 -b '0.0.0.0'
ports:
- "3100:3100"
environment:
RAILS_MASTER_KEY: ${RAILS_MASTER_KEY}
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
RAILS_ENV: production
DEPLOYMENT_BRANCH: main
BUNDLE_WITHOUT: development,test
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
PRIMARY_DB_NAME: ${PRIMARY_DB_NAME}
PRIMARY_DB_USERNAME: ${PRIMARY_DB_USERNAME}
PRIMARY_DB_PASSWORD: ${PRIMARY_DB_PASSWORD}
MEMBER_DB_NAME: ${MEMBER_DB_NAME}
MEMBER_DB_USERNAME: ${MEMBER_DB_USERNAME}
MEMBER_DB_PASSWORD: ${MEMBER_DB_PASSWORD}
ACCESS_KEY_ID_AWS: ${ACCESS_KEY_ID_AWS}
SECRET_ACCESS_KEY_AWS: ${SECRET_ACCESS_KEY_AWS}
AVATAR_BUCKET_AWS: ${AVATAR_BUCKET_AWS}
MAILGUN_API_KEY: ${MAILGUN_API_KEY}
MAILGUN_DOMAIN: ${MAILGUN_DOMAIN}
RECAPTCHA_SECRET_KEY: ${RECAPTCHA_SECRET_KEY}
RECAPTCHA_SITE_KEY: ${RECAPTCHA_SITE_KEY}
depends_on:
- db_primary
- db_member
- redis
db_primary:
image: postgres:12
environment:
POSTGRES_HOST: ${DB_HOST}
POSTGRES_PORT: 5432
POSTGRES_NAME: ${PRIMARY_DB_NAME}
POSTGRES_USER: ${PRIMARY_DB_USERNAME}
POSTGRES_PASSWORD: ${PRIMARY_DB_PASSWORD}
db_member:
image: postgres:12
environment:
POSTGRES_HOST: ${DB_HOST}
POSTGRES_PORT: 5432
POSTGRES_NAME: ${MEMBER_DB_NAME}
POSTGRES_USER: ${MEMBER_DB_USERNAME}
POSTGRES_PASSWORD: ${MEMBER_DB_PASSWORD}
redis:
image: redis:7.0.0
**结论**
通过进行这些更改,我的应用程序实际上能够运行并部署到 Azure,尽管现在我遇到了不同的错误。但是,在我的本地计算机上以及在登录到 Shell 后,我能够运行 Rails 控制台并查看数据库数据;因此,我知道这个问题已经解决。现在转向我在[这里][1]发布的下一个问题。哈哈。
**愉快编程!**
[1]: https://stackoverflow.com/questions/75620376/getting-a-failed-to-open-tcp-connection
<details>
<summary>英文:</summary>
I figured out where I was going wrong. It's within my `docker-compose.yml` file. I was setting the environment variables (ENV) under the database service, not the web service. So, even though the database had the values needed to connect, the web app didn't and so the `database.yml` file wasn't getting the connection values it needed.
Now, I thought that it would get the values like it does in the development environment, from the `.env` file, but just like they needed to be listed in the Heroku settings, they needed to be listed here. (Though now I am having another issue, which I will post a new question. [here][1])
**Explanation**
Within the `docker-compose.yml` file you basically state what is going to be "running" within the docker container. Now, I put "running" in quotes because that is not technically the case, which I will explain as we step through the file.
*First the setup*
Basic `docker-compose.yml` file
version: "3"
services:
web:
db:
redis:
This tells the Docker Composer what version of composer to use (version 3) and that there will be 3 services within the container: a web app, a database connection and a Redis data store.
Next, you need to explain information about each.
Expanded `docker-compose.yml` file
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3100 -b '0.0.0.0'
ports:
- "3100:3100"
environment:
# Put ENV values here
depends_on:
- db
- redis
db:
image: postgres:12
ports:
- "5432:5432"
environment:
# Put Connection Variables Here
redis:
image: redis:7.0.0
Let's work from the bottom up:
*Under the `redis` service*
- The information here states that the Docker Composer should grab a Redis image from online to create the Redis data store (ie version 7.0.0).
*Under the `db` service*
- The information here states that the Docker Composer should grab a PostgreSQL image from online to create the database and/or know what the database structure should look like (ie version 12). This is where the "not technically running" comes into play. There isn't a PostgreSQL database running within the container, but the information here is needed because the webapp that is running depends on the connection. (More on that later)
- It then states what port that database will be accessed by (ie 5432), if the database is found within the container; otherwise it is not needed.
- And then it states the variables needed to access the database.
*Under the `web` service*
- The information here tells the Docker Composer to build from the `Dockerfile`
- Then to run the server. NOTE: I designated port 3100 as 3000 was running the Rails app on my machine rather than the Docker container; but, you can change that to 3000 if you wish.
- Then it states what ports to release for access to the webapp (Should be the same as you stated in the above step)
- Then it states any ENV values needed within the app.
- Then it states what the app depends on, ie a database and the Redis data store. If these things are not accessible, the container and web app will fail.
So, my final `docker-compose.yml` file looks like this:
version: "3"
services:
web:
build: .
command: bundle exec rails s -p 3100 -b '0.0.0.0'
ports:
- "3100:3100"
environment:
RAILS_MASTER_KEY: ${RAILS_MASTER_KEY}
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
RAILS_ENV: production
DEPLOYMENT_BRANCH: main
BUNDLE_WITHOUT: development,test
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
PRIMARY_DB_NAME: ${PRIMARY_DB_NAME}
PRIMARY_DB_USERNAME: ${PRIMARY_DB_USERNAME}
PRIMARY_DB_PASSWORD: ${PRIMARY_DB_PASSWORD}
MEMBER_DB_NAME: ${MEMBER_DB_NAME}
MEMBER_DB_USERNAME: ${MEMBER_DB_USERNAME}
MEMBER_DB_PASSWORD: ${MEMBER_DB_PASSWORD}
ACCESS_KEY_ID_AWS: ${ACCESS_KEY_ID_AWS}
SECRET_ACCESS_KEY_AWS: ${SECRET_ACCESS_KEY_AWS}
AVATAR_BUCKET_AWS: ${AVATAR_BUCKET_AWS}
MAILGUN_API_KEY: ${MAILGUN_API_KEY}
MAILGUN_DOMAIN: ${MAILGUN_DOMAIN}
RECAPTCHA_SECRET_KEY: ${RECAPTCHA_SECRET_KEY}
RECAPTCHA_SITE_KEY: ${RECAPTCHA_SITE_KEY}
depends_on:
- db_primary
- db_member
- redis
db_primary:
image: postgres:12
environment:
POSTGRES_HOST: ${DB_HOST}
POSTGRES_PORT: 5432
POSTGRES_NAME: ${PRIMARY_DB_NAME}
POSTGRES_USER: ${PRIMARY_DB_USERNAME}
POSTGRES_PASSWORD: ${PRIMARY_DB_PASSWORD}
db_member:
image: postgres:12
environment:
POSTGRES_HOST: ${DB_HOST}
POSTGRES_PORT: 5432
POSTGRES_NAME: ${MEMBER_DB_NAME}
POSTGRES_USER: ${MEMBER_DB_USERNAME}
POSTGRES_PASSWORD: ${MEMBER_DB_PASSWORD}
redis:
image: redis:7.0.0
**Conclusion**
Making these changes allowed my app to actually run and deploy to Azure, even though I am now getting a different error. But, on my local machine and when I log into the shell, I am able to run a Rails console and see the database data; so I know this issue is fixed. Now onto the next that I posted [here][1]. LOL.
**Happy Coding!**
[1]: https://stackoverflow.com/questions/75620376/getting-a-failed-to-open-tcp-connection-to-localhost35729-error-after-deployi
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论