Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-13T01:43:16.820Z
Answers.Text: Thank you.  Obviously I totally agree on modifying core Craft files.  Is there a clean way to do this?
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-13T19:35:09.603Z
Answers.Text: 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.
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-13T20:52:27.633Z
Answers.Text: 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.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-19T21:51:33.623Z
Answers.Text: "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.
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-13T01:23:10.273Z
Answers.LastActivityDate: 2022-05-13T01:23:10.273Z
Answers.UserDisplayName: Brad Bell
Body: <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>
  
Tags: <database><config><postgresql>
Title: Postgres SSL PDO config for config/db.php
ThreadText: # 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:
  
  ```
  <?php
  return [
      'dsn' => '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 @username_1.  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.  
  
  ---
  
  