Symfony/PHP拒绝数据库连接 [英] Database connection refused with Symfony / PHP

查看:123
本文介绍了Symfony/PHP拒绝数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试将Symfony 3.2/Doctrine应用程序部署到Swisscom PaaS.

已安装了Buildpack(PHP 7,httpd等),composer正在运行并安装依赖项,但是在调用composer后命令(例如cache:clear)时,我得到了:

[Doctrine\DBAL\Exception\ConnectionException]                              
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused

我的 manifest.yml :

applications:
- services:
 - dbservice
buildpack: php_buildpack
host: myapp
name: MyApp
instances: 1
memory: 640M
env:
 SYMFONY_ENV: prod
 PHP_INI_SCAN_DIR: .bp-config/php/conf.d

我的options.json:

"WEB_SERVER": "httpd",
"COMPOSER_INSTALL_OPTIONS": ["--no-dev --optimize-autoloader --no-progress --no-interaction"],
"COMPOSER_VENDOR_DIR": "vendor",
"SYMFONY_ENV": "prod",
"WEBDIR": "web",
"PHP_MODULES": "fpm",
"PHP_VERSION": "{PHP_70_LATEST}",
"PHP_EXTENSIONS": [
 "bz2",
 "zlib",
 "curl",
 "mcrypt",
 "openssl",
 "mbstring",
 "pdo",
 "pdo_mysql"
],
"ZEND_EXTENSIONS": [
 "opcache"
]

这就是我从VCAP读取数据库凭据并在Symfony中设置参数的方式(与VCAPSERVICES env vars的本地设置完美配合):

$vcapServices = json_decode($_ENV['VCAP_SERVICES']);

$container->setParameter('database_driver', 'pdo_mysql');

$db = $vcapServices->{'mariadb'}[0]->credentials;

$container->setParameter('database_host', $db->host);
$container->setParameter('database_port', $db->port);
$container->setParameter('database_name', $db->name);
$container->setParameter('database_user', $db->username);
$container->setParameter('database_password', $db->password);

// Just for debug:

echo 'User: ';
var_dump($container->getParameter('database_user'));

echo 'Db: ';
var_dump($db);

服务正在运行,两个var_dump均提供期望值.但是仍然拒绝连接.

我在做什么错了?

****编辑**** 似乎存在类似的问题,但没有解决方案: Cloud Foundry p-mysql

****编辑****

我直接调试到调用PDO构造函数的语句.

使用以下参数调用它:

$dsn = mysql:host=10.0.20.18;port=3306;dbname=CF_DB922DD3_CACB_4344_9948_746E585732B5;
$username = "myrealusername"; // as looked up in VCAP_SERVICES
$password = "myrealpassword"; // as looked up in VCAP_SERVICES
$options = array();

任何内容看起来都可以在Web控制台中看到,用于服务绑定.

是否需要 unix_socket 才能成功连接?

****编辑****

由于Symfony正在使用一些composer post-install命令(在这种情况下,例如,用于清除和预热缓存),这些命令已经需要有效的数据库连接,只要容器是Cloudfoundry的DB服务都不支持此连接.还没有完全构建和部署?

我的想法已经用光了.

解决方案

对不起,感谢您的反馈. Swisscom修改了安全组.有关更多信息,请参见应用程序安全组.

Cloud Foundry阻止了来自应用程序的所有出站网络连接 容器默认情况下.管理员可以覆盖此 应用程序安全组(ASG)的默认阻止行为.

ASG是指定一个或多个出口规则的集合 单独的协议,端口和目的地,以允许网络访问

Cloud Foundry有两个默认的ASG集:default-stagingdefault-running. Cloud Foundry中的所有应用程序容器都使用 其中之一的基本政策.

Galera即服务(MariaDB)的规则仅在running中完成.我们也将规则添加到了staging.

Trying to deploy a Symfony 3.2/Doctrine application to Swisscom PaaS.

Buildpack (PHP 7, httpd etc.) are installed, composer is running and installing dependencies, but when calling the composer after-commands, like cache:clear I get an:

[Doctrine\DBAL\Exception\ConnectionException]                              
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused

my manifest.yml:

applications:
- services:
 - dbservice
buildpack: php_buildpack
host: myapp
name: MyApp
instances: 1
memory: 640M
env:
 SYMFONY_ENV: prod
 PHP_INI_SCAN_DIR: .bp-config/php/conf.d

my options.json:

"WEB_SERVER": "httpd",
"COMPOSER_INSTALL_OPTIONS": ["--no-dev --optimize-autoloader --no-progress --no-interaction"],
"COMPOSER_VENDOR_DIR": "vendor",
"SYMFONY_ENV": "prod",
"WEBDIR": "web",
"PHP_MODULES": "fpm",
"PHP_VERSION": "{PHP_70_LATEST}",
"PHP_EXTENSIONS": [
 "bz2",
 "zlib",
 "curl",
 "mcrypt",
 "openssl",
 "mbstring",
 "pdo",
 "pdo_mysql"
],
"ZEND_EXTENSIONS": [
 "opcache"
]

And this is how I read database credentials from VCAP and set parameters in Symfony (which is perfectly working with a local setup of VCAPSERVICES env vars):

$vcapServices = json_decode($_ENV['VCAP_SERVICES']);

$container->setParameter('database_driver', 'pdo_mysql');

$db = $vcapServices->{'mariadb'}[0]->credentials;

$container->setParameter('database_host', $db->host);
$container->setParameter('database_port', $db->port);
$container->setParameter('database_name', $db->name);
$container->setParameter('database_user', $db->username);
$container->setParameter('database_password', $db->password);

// Just for debug:

echo 'User: ';
var_dump($container->getParameter('database_user'));

echo 'Db: ';
var_dump($db);

Service is running, both var_dump deliver the expected values. But still connection is refused.

What am I doing wrong?

****EDIT**** A similar problem seems to be here, but without a solution: Cloud foundry p-mysql

****EDIT****

I debugged down right to the statement where PDO constructor is called.

It is called with the following parameters:

$dsn = mysql:host=10.0.20.18;port=3306;dbname=CF_DB922DD3_CACB_4344_9948_746E585732B5;
$username = "myrealusername"; // as looked up in VCAP_SERVICES
$password = "myrealpassword"; // as looked up in VCAP_SERVICES
$options = array();

Anything looks exactly like it can be seen in the web console for the service binding.

Is an unix_socket required to successfully connect?

****EDIT****

As Symfony is using some composer post-install-commands (in this case e.g. to clear and warm up the cache) which require already a working database connection that this is not supported with DB services by cloudfoundry as long as the container is not fully built and deployed?

Am running out of ideas.

解决方案

Sorry for the issue and thanks for feedback. Swisscom modified the security groups. See Application Security Groups for more info.

Cloud Foundry blocks all outbound network connections from application containers by default. Administrators can override this block-by-default behavior with Application Security Groups (ASGs).

ASGs are a collection of egress rules that specify one or more individual protocols, ports, and destinations to allow network access to.

Cloud Foundry has two default sets of ASGs: default-staging and default-running. All application containers in Cloud Foundry use a base policy from one of these.

The rule for Galera as a Service (MariaDB) was only done in running. We added the rule also to staging.

这篇关于Symfony/PHP拒绝数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆