Operating System: Some Ubuntu on Digital Ocean App platform, can’t really tell
Database: PostgreSQL v15 database cluster
Node Version: v17.9.1
NPM Version: v8.11.0
Yarn Version: -
Hi Strapi Team!
I followed the official docs on deploying Strapi to DigitalOcean, but I’ve run into this problem:
Error: self-signed certificate in certificate chain
I eventually figured out why this was happening after adding some console logs to my config files. It turns out that the production config files are not being read, which produces the above error.
The documentation above tells you to create a file: config/env/production/database.ts I created this file and also added a console log to it console.log('production config file loaded');.
I also added a console log to the main config file, which gets merged with every other environment-specific config file:
Another documentation page states, Everything defined in the production configuration will override the default configuration. but the production config is not being processed at all. NODE_ENV is defined as an App-Level environment variable.
Since this is such a basic functionality, I’m sure I missed something trivial.
Thanks, @pierreburgy. I could technically remove everything from config/database.js and just put there my production config, but my issue is that the config file config/env/production/database.js is not being processed.
It already has the correct SSL options (suggested in the post you shared) "ssl": { "rejectUnauthorized": false }. Here’s what the file looks like:
If you have files in both ‘config’ and ‘config/env/production’, I believe only the former will get processed. I avoided this by moving all my config files into ‘config/env/development’, and then copying the ones that I wanted to be common to production into the ‘config/env/production’ folder - along with those specific to production. It does seem better, even if there’s duplication of files, because you can see the whole config for a given environment in one place. Messier to maintain, though, if there’s more shared than different.
Thanks for this great video. I wasn’t aware of this register function.
In the meantime, I figured out a couple of things too.
config/database always run before config/env/production/database.
I had the console.log(‘final configuration’, connections[client]); in the config/database file, so that’s the reason why it was always printing the default values.
After realizing this, I put a console log into the config/env/production/database files as well, and that had the correct configuration:
Above I’m logging the entire connection object and inside that connection.ssl to make sure it’s set to { rejectUnauthorized: false }
I also tried:
downgrading pg to version 7
using ssl: { ca: env('DATABASE_CA') } - with the right certificate set, this was visible in the logs too
using ssl: { ca: env('DATABASE_CA'), rejectUnauthorized: false }
But none of these worked. I also tried various combinations of these in the 36 deployments that I did.
If you think logging in the register callback has the potential to show us something we don’t know, I could set up the entire stack again and give it another shot.
It appears that if you set ‘rejectUnauthorized’ to ‘true’ but don’t provide a valid certificate chain then you get this cryptic error from pg. Have you tried creating a self-signed certificate and providing that as both the ‘server’ and ‘root’. Here’s an example from the pg docs: