<p>Obviously, we don't recommend anyone modify core Craft files, but I can't think of any recent changes around this on the Craft 3 branch (Craft 4 did make some changes).</p>
<p>I can't tell from your comment if it started to <em>not</em> work on 3.7.28, or 3.7.28 was the last one it worked on and it broke on 3.7.29 and later.</p>
<p>Assuming it's the latter, you can see a list of changed files between the releases that might help you narrow it down via <a href="https://github.com/craftcms/cms/compare/3.7.28...3.7.29" rel="nofollow noreferrer">https://github.com/craftcms/cms/compare/3.7.28...3.7.29</a></p>

CC BY-SA 4.0
2022-05-13T01:43:16.820Z
Thank you.  Obviously I totally agree on modifying core Craft files.  Is there a clean way to do this?
John
CC BY-SA 4.0
2022-05-13T19:35:09.603Z
Maybe I'm not following, but if you set the full DSN with all of your SSL settings directly in https://craftcms.com/docs/3.x/config/db-settings.html#dsn, then Craft should use it directly.
Brad Bell
CC BY-SA 4.0
2022-05-13T20:52:27.633Z
Thanks again for the response @BradBell.  The first code snippet in my post is of the DSN I construct in `config/db.php`.  Are you saying that what I have there should just work?  It only seems to work with the hack in the second code snippet above, and that only when building with `composer create-project craftcms/craft "1.1.6"` and pinning Craft to version 3.7.38.
John
CC BY-SA 4.0
2022-05-19T21:51:33.623Z
"Are you saying that what I have there should just work?" - I think so, yeah. If this is reproducible on a public box and you can share some SSH credentials, shoot an email over to support@craftcms.com and we can poke around a bit.
Brad Bell
CC BY-SA 4.0
2022-05-13T01:23:10.273Z
2022-05-13T01:23:10.273Z
Brad Bell
<p>Struggling to configure this correctly and cleanly.  When I upgrade to latest 3.x Craft on staging, Craft can no longer connect to the Postgres DB, which uses SSL.  Have had success up until CraftCMS version 3.7.28 by overwriting <code>vendor/craftcms/cms/src/config/DbConfig.php</code> and with a <code>config/db.php</code> as follows:</p>
<pre><code>&lt;?php
return [
    'dsn' =&gt; 'pgsql:host=' . getenv('DB_SERVER') .
         ';port=' . getenv('DB_PORT') . 
         ';dbname=' . getenv('DB_DATABASE') .
         ';sslmode=require' . 
         ';sslcert=/etc/ssl/certs/ssl-cert-pg.pem' . 
         ';sslkey=/etc/ssl/private/ssl-cert-pg.key' .
         ';sslrootcert=/etc/ssl/certs/ssl-cert-pg.pem' .
         ';user=' . getenv('DB_USER') .
         ';password=' . getenv('DB_PASSWORD'),
    'attributes' =&gt; []
];
</code></pre>
<p>The <code>vendor/craftcms/cms/src/config/DbConfig.php</code> override that functioned previously is summarized here:</p>
<pre><code>public function init()
{
    if ($this-&gt;dsn) {
        if (($pos = strpos($this-&gt;dsn, ':')) === false) {
            throw new InvalidConfigException('Invalid DSN: ' . $this-&gt;dsn);
        }
        $this-&gt;driver = substr($this-&gt;dsn, 0, $pos);
        $params = substr($this-&gt;dsn, $pos + 1);
        foreach (explode(';', $params) as $param) {
            if (($pos = strpos($param, '=')) === false) {
                throw new InvalidConfigException('Invalid DSN param: ' . $param . 'in - params: ' . $params);
            }
            $paramName = substr($param, 0, $pos);
            $paramValue = substr($param, $pos + 1);
            switch ($paramName) {
                case 'host':
                    $this-&gt;server = $paramValue;
                    break;
                case 'port':
                    $this-&gt;port = $paramValue;
                    break;
                case 'dbname':
                    $this-&gt;database = $paramValue;
                    break;
                case 'unix_socket':
                    $this-&gt;unixSocket = $paramValue;
                    break;
                case 'charset':
                    $this-&gt;charset = $paramValue;
                    break;
                case 'user': // PG only
                    $this-&gt;user = $paramValue;
                    break;
                case 'password': // PG only
                    $this-&gt;password = $paramValue;
                    break;
                case 'sslmode': // PG only
                    $this-&gt;sslmode = $paramValue;
                    break;
                case 'sslcert': // PG only
                    $this-&gt;sslcert = $paramValue;
                    break;
                case 'sslkey': // PG only
                    $this-&gt;sslkey = $paramValue;
                    break;
                case 'sslrootcert': // PG only
                    $this-&gt;sslrootcert = $paramValue;
                    break;
</code></pre>
<p>The <code>.env</code> file looks something like this:</p>
<pre><code>CRAFT_ENVIRONMENT=production
LANG=C.UTF-8
REDIS_HOST=******
DB_DRIVER=pgsql
DB_DSN=pgsql:host=******;port=5432;dbname=******
DB_SERVER=******
DB_DATABASE=******
DB_PASSWORD=******
DB_SCHEMA=public
DB_PORT=5432
DB_USER=******
ENVIRONMENT=production
</code></pre>

<database><config><postgresql>
Postgres SSL PDO config for config/db.php
# Postgres SSL PDO config for config/db.php

(Asked by: username_0 on 2022-05-12)

Struggling to configure this correctly and cleanly.  When I upgrade to latest 3.x Craft on staging, Craft can no longer connect to the Postgres DB, which uses SSL.  Have had success up until CraftCMS version 3.7.28 by overwriting vendor/craftcms/cms/src/config/DbConfig.php and with a config/db.php as follows:
 'pgsql:host=' . getenv('DB_SERVER') .
         ';port=' . getenv('DB_PORT') . 
         ';dbname=' . getenv('DB_DATABASE') .
         ';sslmode=require' . 
         ';sslcert=/etc/ssl/certs/ssl-cert-pg.pem' . 
         ';sslkey=/etc/ssl/private/ssl-cert-pg.key' .
         ';sslrootcert=/etc/ssl/certs/ssl-cert-pg.pem' .
         ';user=' . getenv('DB_USER') .
         ';password=' . getenv('DB_PASSWORD'),
    'attributes' => []
];

The vendor/craftcms/cms/src/config/DbConfig.php override that functioned previously is summarized here:
public function init()
{
    if ($this->dsn) {
        if (($pos = strpos($this->dsn, ':')) === false) {
            throw new InvalidConfigException('Invalid DSN: ' . $this->dsn);
        }
        $this->driver = substr($this->dsn, 0, $pos);
        $params = substr($this->dsn, $pos + 1);
        foreach (explode(';', $params) as $param) {
            if (($pos = strpos($param, '=')) === false) {
                throw new InvalidConfigException('Invalid DSN param: ' . $param . 'in - params: ' . $params);
            }
            $paramName = substr($param, 0, $pos);
            $paramValue = substr($param, $pos + 1);
            switch ($paramName) {
                case 'host':
                    $this->server = $paramValue;
                    break;
                case 'port':
                    $this->port = $paramValue;
                    break;
                case 'dbname':
                    $this->database = $paramValue;
                    break;
                case 'unix_socket':
                    $this->unixSocket = $paramValue;
                    break;
                case 'charset':
                    $this->charset = $paramValue;
                    break;
                case 'user': // PG only
                    $this->user = $paramValue;
                    break;
                case 'password': // PG only
                    $this->password = $paramValue;
                    break;
                case 'sslmode': // PG only
                    $this->sslmode = $paramValue;
                    break;
                case 'sslcert': // PG only
                    $this->sslcert = $paramValue;
                    break;
                case 'sslkey': // PG only
                    $this->sslkey = $paramValue;
                    break;
                case 'sslrootcert': // PG only
                    $this->sslrootcert = $paramValue;
                    break;

The .env file looks something like this:
CRAFT_ENVIRONMENT=production
LANG=C.UTF-8
REDIS_HOST=******
DB_DRIVER=pgsql
DB_DSN=pgsql:host=******;port=5432;dbname=******
DB_SERVER=******
DB_DATABASE=******
DB_PASSWORD=******
DB_SCHEMA=public
DB_PORT=5432
DB_USER=******
ENVIRONMENT=production

**Tags:** database, config, postgresql

---

## 1 answers

### Answer by username_1 on 2022-05-13. Score: 0

Obviously, we don't recommend anyone modify core Craft files, but I can't think of any recent changes around this on the Craft 3 branch (Craft 4 did make some changes).

I can't tell from your comment if it started to *not* work on 3.7.28, or 3.7.28 was the last one it worked on and it broke on 3.7.29 and later.

Assuming it's the latter, you can see a list of changed files between the releases that might help you narrow it down via <https://github.com/craftcms/cms/compare/3.7.28...3.7.29>

> **Comments:**
> **username_0**: Thank you.  Obviously I totally agree on modifying core Craft files.  Is there a clean way to do this?  
> **username_1**: Maybe I'm not following, but if you set the full DSN with all of your SSL settings directly in https://craftcms.com/docs/3.x/config/db-settings.html#dsn, then Craft should use it directly.  
> **username_0**: Thanks again for the response @BradBell.  The first code snippet in my post is of the DSN I construct in `config/db.php`.  Are you saying that what I have there should just work?  It only seems to work with the hack in the second code snippet above, and that only when building with `composer create-project craftcms/craft "1.1.6"` and pinning Craft to version 3.7.38.  
> **username_1**: "Are you saying that what I have there should just work?" - I think so, yeah. If this is reproducible on a public box and you can share some SSH credentials, shoot an email over to support@craftcms.com and we can poke around a bit.  

---

