我正在对Rails应用进行docker化,该应用中有一个运行psql命令的脚本。 在docker外部可以正常工作,但是当docker容器正在运行时,Web应用程序和数据库是不同的服务。
因此,当Rails服务中的脚本具有psql命令时,它将引发错误。在这种情况下,它将引发“ dropdb:找不到命令”。
如何使Rails应用程序能够运行包含psql
命令的脚本?
我认为可以通过将Postgres的位置添加到PATH来解决此问题。
ENV PATH $PATH:/usr/pgsql-9.6/bin:$PATH
但是我认为我需要为其他服务做到这一点。
我还看到可以link进行两项服务,例如
web:
build: .
links:
- "db:database"
db:
image: postgres
从容器运行轨道内部访问psql命令的最佳实践是什么?
答案 0 :(得分:3)
首先,我不认为像使用psql
命令所要求的那样运行迁移是一个好主意。我建议考虑以下内容:
我建议使用可以运行数据库迁移的本机Rails库。该工具将使用您自己的数据库凭据,并将使用应用程序提供的数据库驱动程序。我不知道this documentation from rubyonrails.org是否足够,但这是一个很好的起点。
迁移是您以结构化和有组织的方式更改数据库的便捷方法。您可以手动编辑SQL片段,但是然后负责告诉其他开发人员他们需要运行它们。您还必须跟踪下次部署时需要对生产机器进行哪些更改。
但是无论如何,我会回答您的问题,因为您可以在知道先前的建议后询问。
完成您想要的事情需要三个步骤。
首先,这是正确的,您可以像说的那样链接容器:
web:
build: .
links:
- "db:db"
db:
image: postgres
这意味着您可以在Web应用程序中将“ db”用作数据库的主机名。
第二个是允许从Rails容器到PostgreSQL容器的连接。
如果PostgreSQL已经接受连接,则可能不需要此步骤。
为此,您必须编辑PostgreSQL数据目录中的pg_hba.conf
文件。为什么?因为需要从容器外部批准连接,所以需要从Rails应用程序批准连接。
pg_hba.conf
文件如下:
# Allow any user on the local system to connect to any database with
# any database user name using Unix-domain sockets (the default for local
# connections).
#
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
您可以遵循官方文档here (for 9.6 version)。
您的样子:
# TYPE DATABASE USER ADDRESS METHOD
host all all all md5
或者:
# TYPE DATABASE USER ADDRESS METHOD
host database_name username docker_network md5
其中database_name是应用程序数据库名称,用户名是数据库用户名,而docker_network是Docker网络IP(例如172.17.0.0/24
)
这将允许您的Rails容器访问数据库。
如果您不想在移除容器后放松此配置,请查看Docker卷:Volumes on docs.docker.com和docker-compose volumes also on docs.docker.com。
第三步,也是最后一步,为了在PostgreSQL容器以外的其他地方运行psql
命令,您需要在容器中安装该工具。这意味着您需要将其安装在Docker映像中。
如果您的Rails映像基于Ubuntu / Debian / Mint / ...,则可以执行以下操作:
sudo apt-get install postgresql-client
sudo ln -s /usr/lib/libpq.so.5.4 /usr/lib/libpq.so # adapt to the actual postgres version
找到上一行here (Install PostgreSQL Client driver)。
您必须像这样运行psql
:
PGPASSWORD=<yourpass> psql -U username -H db < script.sql
# For manual usage, prompt the password
psql -U username -H db < script.sql
这是非常不安全的。这就是为什么我建议在回答开始时避免使用此解决方案的原因。
答案 1 :(得分:1)
您的Ruby容器缺少PostgreSQL客户端工具,您必须为所使用的任何Linux发行版找到合适的软件包(例如Alpine的postgresql-client),并将其安装在运行Rails的容器中。如果有一个“客户端”软件包可供使用,因为不需要整个服务器,但是并非所有发行版都具有这种区别。另外,PostgreSQL offers package repositories适用于许多发行版。