When deploying strapi on heroku using the postgres add-on, strapi requires individual config vars set for the db connection configuration and not just the DATABASE_URL. I have it setup and it all works fine. The problem is using the review app feature in a heroku pipeline. I cannot set static config vars for all review apps because Heroku provisions a new instance of the postgres add-on everytime a review app is created hence the review app gets a new DATABASE_URL. Im leaning towards using the root app.json file to specify a script that will read in the the auto generated DATABASE_URL config var and split it and set the strapi required config vars. Is that the best and/or only way to do it? what life cycle should the script be a part of? is it going to be a bash script? how would i go about reading and splitting the DATABASE_URL? thanks,
I managed to figure it out... I basically answered it in my actual question.
-go to account settings and get your HEROKU_API_TOKEN. -add it as a config var to your pipeline. -create an app.json file in the root which inherits the HEROKU_API_TOKEN and HEROKU_APP_NAME config vars. You need it in the script. -set the script you wish to run in the postdeploy event.
your app.json should have this basic structure:
{
"environments": {
"review": {
"scripts": {
"postdeploy": "node ./postdeployReviewapp.js"
},
"addons": [
"heroku-postgresql:hobby-dev"
]
}
},
"env":{
"HEROKU_APP_NAME": {
"required": true
},
"HEROKU_API_TOKEN":{
"required":true
}
}
}
-Then create the script... your script should read in the auto generated database_url and spilt it to get the individual dbconnection variables. -make a patch request to the heroku platform api config-vars endpoint passing your dbconnection variables in the body.
your node script should look something like this:
const https = require('https');
const url = require('url');
/**
* eg. DATABASE_URL = postgres://ebitxebvixeeqd:dc59b16dedb3a1eef84d4999sb4baf@ec2-50-37-231-192.compute-2.amazonaws.com: 5432/d516fp1u21ph7b
* It's read like so: postgres:// USERNAME : PASSWORD @ HOST : PORT : DATABASE_NAME
*/
let settings = {
client: 'postgres'
};
const parsed = url.parse(process.env.DATABASE_URL, true);
const [username, password] = parsed.auth.split(':');
settings.host = parsed.hostname;
settings.port = Number(parsed.port);
settings.database = parsed.pathname.substr(1);
settings.username = username;
settings.password = password;
settings.ssl = (parsed.query.ssl === 'true');
var options = {
'method': 'PATCH',
'hostname': 'api.heroku.com',
'path': '/apps/' + process.env.HEROKU_APP_NAME + '/config-vars',
'headers': {
'Content-Type': 'application/json',
'Accept': 'application/vnd.heroku+json; version=3',
'Authorization': 'Bearer ' + process.env.HEROKU_API_TOKEN
}
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = JSON.stringify(
{
"DATABASE_USERNAME": settings.username,
"DATABASE_PASSWORD": settings.password,
"DATABASE_HOST": settings.host,
"DATABASE_PORT": settings.port,
"DATABASE_NAME": settings.database
});
req.write(postData);
req.end();
your review app should now have new config vars that will be used by strapi to connect to postgres.