How to run migrations in Heroku after deploying? - heroku

I was hitting an endpoint on my deployed backend and saw some errors regarding errorMissingColumn. I realized Heroku hasn't ran migrations.
I'm using sequelize so I ran
heroku run sequelize db:migrate it recognized the command but for some reason it timed out:
Running sequelize db:migrate on ⬢ reeltime-server-development... !
▸ ETIMEDOUT: connect ETIMEDOUT 50.19.103.36:5000
This is my config.json for the database:
"development": {
"database": "reel_time_development",
"host": "127.0.0.1",
"dialect": "postgres",
"operatorsAliases": false
},
"test": {
"database": "reel_time_test",
"host": "127.0.0.1",
"dialect": "postgres",
"logging": false,
"operatorsAliases": false
},
"production": {
"use_env_variable": "DATABASE_URL",
"operatorsAliases": false
}
}
And I'm also using a Postgres Resource on Heroku.

heroku run:detached sequelize db:migrate worked.

Related

'Error: Self-signed Certificate' When Running Knex Migrations on Heroku

Update #1
Unfortunately, I cannot find a screenshot from when I was working on the issue using postgrator. I ended up going with knex to try and connect to heroku instead.
However, when I run 'heroku run npm run migrate' I run into the following issue:
heroku run knex migrate:latest
Running knex migrate:latest on ⬢ stormy-hollows-73700... up,
run.6282 (Free)
Error: self signed certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1507:34)
at TLSSocket.emit (events.js:376:20)
at TLSSocket._finishInit (_tls_wrap.js:932:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12)
package.json
{
"name": "express-boilerplate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"migrate": "knex migrate:latest",
"create-migration": "knex migrate:make $1",
"migrate:test": "env NODE_ENV=test npm run migrate",
"seed": "psql -d chirp-app -f seeds/seed.posts.sql; psql -d chirp-
app -f seeds/seed.replies.sql",
"test": "mocha --require test/setup.js",
"dev": "nodemon src/server.js",
"start": "node src/server.js",
"predeploy": "npm audit",
"deploy": "git push heroku main"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"helmet": "^4.2.0",
"knex": "^0.95.4",
"morgan": "^1.10.0",
"pg": "^8.0.3",
"postgrator-cli": "^3.3.0",
"uuid": "^8.3.2",
"xss": "^1.0.8"
},
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^8.2.1",
"nodemon": "^2.0.7",
"supertest": "^6.0.1"
}
}
knexfile.js
`const dotenv = require('dotenv')
dotenv.config()
module.exports = {
client: 'pg',
connection: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
};`
knex migration:
`exports.up = function (knex) {
return Promise.all(
[knex.schema.createTable('posts', table => {
table.string('id', 36)
table.string('title', 50)
table.string('content')
}),
knex.schema.createTable('replies', table => {
table.string('id', 36)
table.string('title', 50)
table.string('postid', 36)
})]
)
};
exports.down = function (knex) {
knex.schem.dropTable('posts')
knex.schema.dropTable('replies')
};`
Let me know if I should present this information differently, add or remove files as I am learning how to use this platform.
Thanks!
I ended up creating a knex migration and was able to validate my database on heroku.
I did have to make a "seed:live" script that runs seeds using postgres though.
ex:
"scripts": {..."seed:live": "heroku pg:psql -f seeds/seed.posts.sql; heroku pg:psql -f seeds/seed.replies.sql"...}
to validate seeding the database:
heroku pg:psql -f seeds/seed.posts.sql; heroku pg:psql -f seeds/seed.replies.sql --> Connecting to postgresql-cubed-11974 INSERT 0 3 --> Connecting to postgresql-cubed-11974 INSERT 0 2
but now it works!

Fastify with Heroku

I am having a simple Fastify server hosted with Heroku. But, it seems not working ! But, it seemed all right during the development! The error I get is: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch. Full error I am getting:
Here is the code I am using:
server.js:
const fastify = require("fastify")();
const path = require("path");
fastify.register(require("fastify-static"), {
root: path.join(__dirname, "/"),
});
fastify.get("/", function (req, reply) {
reply.sendFile("index.html");
});
fastify.listen(process.env.PORT || 5000, (err) => {
if (err) throw err;
console.log(`server listening on ${fastify.server.address().port}`);
});
package.json:
{
"name": "test1",
"version": "1.0.0",
"description": "",
"main": "server.js",
"engines": {
"node": "15.11.x"
},
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"fastify": "^3.14.0",
"fastify-static": "^4.0.1"
}
}
Sometimes, the site even doesn't load!
Any help is greatly appreciated !
Thanks !
That's an issue with the library. For other libraries (express, django, etc..) specifying the address is not necessary.
See https://github.com/fastify/fastify/issues/709
Change:
.listen(process.env.PORT)
to:
.listen(process.env.PORT, '0.0.0.0')
When I use both nodemon as local server and Heroku for production the following works for me:
await fastify.listen(process.env.PORT, process.env.HOST || '0.0.0.0');
and in package.json
"dev": "PORT=${PORT:=3000} HOST=${HOST:=localhost} nodemon"

Specify Postgres database plan in Heroku review apps

I am trying to use Heroku review apps for testing and demonstrating my site to my colleagues. The site has a large database that will not function with Heroku's free hobby-dev databases.
I am trying to use the app.json manifest file to specify the platform of my app, as per the guide. The code I'm using is below:
app.json
{
"name": "SiteName",
"description": "The website for SiteName",
"keywords": [
"mezzanine",
"django"
],
"image": "heroku/python",
"env": {
"EMAIL_SYSTEM": {
"description": "The email system to use, either console or mailgun",
"value": "mailgun"
},
"ENVIRONMENT": {
"description": "The dev environment, either production or test",
"value": "production"
},
"ALLOWED_HOSTS": {
"description": "Comma-separated list of hosts",
"value": ".herokuapp.com"
},
"DEFAULT_FROM_EMAIL": "noreply#example.com",
"SECRET_KEY": {
"description": "A secret key for verifying the integrity of signed cookies.",
"generator": "secret"
},
"WEB_CONCURRENCY": {
"description": "The number of processes to run.",
"value": "5"
},
"NODE_ENV": "production",
"DEBUG": "False",
"NPM_CONFIG_PRODUCTION": "false",
"CELERY_REDIS_MAX_CONNECTIONS": 3,
"S3_BUCKET": "my-s3-bucket",
"USE_CELERY_TASKS": "True"
},
"formation": {
"web": {
"quantity": 1,
"size": "Standard-1X"
},
"worker": {
"quantity": 1,
"size": "Standard-1X"
}
},
"addons": [
"heroku-redis",
{
"plan": "heroku-postgresql:standard-0",
"as": "DATABASE"
}
],
"buildpacks": [
{
"url": "https://github.com/heroku/heroku-buildpack-python.git"
}
],
"scripts": {
"postdeploy": "python manage.py migrate && python manage.py populate_db"
},
"environments": {
"test": {
"addons": [
"heroku-postgresql:in-dyno",
"heroku-redis:in-dyno"
],
"env": {
"APP_SKIP_DB_TEARDOWN": "True",
"DB_REQUIRE_SSL": "False",
"DEBUG": "True",
"S3_BUCKET": "my-s3-bucket",
"USE_CELERY_TASKS": "False"
},
"scripts": {
"test-setup": "python manage.py collectstatic --noinput",
"test": "python manage.py test"
}
}
}
}
This will build OK, but how can I explicitly specify the database plan I wish to use?
In case anyone else runs into this.
According to heroku support they have changed how they provision addons for review and CI apps to mean that by default they'll only provision the free / cheapest plan, regardless of what is in your app.json Here are some details and explanation of their reasoning
They can override this at an account level if you open a ticket (at time of writing this doesn't seem to be built into their admin area)
You just need to specify the plan using the sintax:
heroku-postgresql:<plan_you_select>
"addons": [
{
"plan": "heroku-postgresql:<plan_you_select>",
"as": "DATABASE"
}
]
For a list of the available plans, checkout this link:
https://devcenter.heroku.com/articles/heroku-postgres-plans#hobby-tier
You can also use this link: https://elements.heroku.com/addons/heroku-postgresql
Select a plan on it, and you'll see the plan name on the CLI
If you don't/can't open a ticket like Pete's answer suggests, here's some bash code I just wrote to upgrade my Postgres DB. It's complicated since:
Heroku always starts review apps with a hobby db, ignoring app.json and other settings
heroku pg:upgrade only works on non-hobby dbs
after creating a new db there's no simple way to learn its ALL_CAPS name for use in later commands
# there's no easy way to grab the DATABASE_NAME so we have to grep the output here :-(
# see https://devcenter.heroku.com/articles/upgrading-heroku-postgres-databases
# and https://help.heroku.com/SY28FR6H/why-aren-t-i-seeing-the-add-on-plan-specified-in-my-app-json-in-my-review-or-ci-app
echo
echo "Upgrading Postgres."
heroku maintenance:on --app $app
addon_name=`heroku addons:create heroku-postgresql:standard-0 --app $app | grep "is being created" | awk '{print $1}'`
db_name=`heroku addons:info $addon_name --app $app | grep "Attachments" | awk -F :: '{print $2}'`_URL
echo $app $addon_name $db_name
heroku pg:wait --app $app
heroku pg:copy DATABASE_URL $db_name --app $app --confirm $app
heroku addons:destroy $addon_name --app $app --confirm $app
heroku pg:promote $db_name --app $app
heroku maintenance:off --app $app

procfile no changing from web to worker

I'm trying to Host my bot "chompbot" in Heroku.
But when i change Procfile from web to worker, does not change anything.
I've tried
Here is my package.json
"name": "chompbot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"discord.js": "^11.5.1",
"mysql": "^2.17.1"
}
}
And here is my Procfile
worker: index.js
When i commit and push, anything happens on "Web", and do not appears "Worker" option
( Ps.: The MySql database is fully working on cloud, so, can't be the dependencies )
Can someone help me to change from Web to Worker?
http://prntscr.com/pb21qs
Your worker should be the script that starts you server, index.js is only the file name. What you want to do is to use your npm start script instead of index.js

Heroku CI with Postgres postgis extension

I'm using a postgis extension to my database on Heroku. In production this works just fine; I'm mapping like a boss.
But, I can't get my app to build on HerokuCI because the database addon in the test environment doesn't have GDAL installed (part of the postgis extension):
django.core.exceptions.ImproperlyConfigured: Could not find the GDAL library (tried "gdal", "GDAL", "gdal2.3.0", "gdal2.2.0", "gdal2.1.0", "gdal2.0.0", "gdal1.11.0"). Is GDAL installed? If it is, try setting GDAL_LIBRARY_PATH in your settings.
-----> test command `python manage.py migrate --noinput && python manage.py test` failed with exit status 1
I can't find out how to create extensions in the heroku CI environment. Heroku's app json schema say nothing about how to create extensions on the test databases.
I know that I can't use in-dyno database for CI, as postgis is not an available extension for that, but I'm not using an in-dyno one, I'm using a plan...
Here's my app schema:
{
"name": "mymegaapp",
"scripts": {
"heroku-prebuild": "create extension postgis",
"heroku-postbuild": "echo heroku-postbuild script runs here."
},
"env": {
},
"formation": {
},
"addons": [
],
"buildpacks": [
{
"url": "heroku/python"
},
{
"url": "heroku/nodejs"
}
],
"environments": {
"test": {
"scripts": {
"test": "python manage.py migrate --noinput && python manage.py test"
},
"env": {
"DJANGO_DEBUG": "1"
},
"addons":[
{
"plan": "heroku-postgresql",
"options": {
"version": "11"
}
},
"heroku-redis:hobby-dev"
]
}
}
}
Note that I've tried to create the postgis extension in the prebuild script, which doesn't make a difference.
I've also tried invoking the creation before the test script:
"scripts": {
"test": "heroku create extension postgis && python manage.py migrate --noinput && python manage.py test"
},
which doesn't work because the heroku cli isn't installed in the dyno.
The key questions:
How can I create extensions in HerokuCI?
Is postgis an allowable extension at all in HerokuCI?
You've almost got it. There's no first class support for creating pg extensions directly from the CLI. However, you can pass a statement into psql.
Try this in your postdeploy or test setup script:
psql -c "create extension postgis" $DATABASE_URL As you're aware, you'll need to do this with a real database, not in-dyno. If you've attached the database as something other than DATABASE_URL, you will need to update that in the script.
[Edit by OP to add useful info] In this case, GDAL libraries will also be needed, which can be installed by setting the BUILD_WITH_GEO_LIBRARIES environment variable to 1. The final working solution in app.json will be:
"environments": {
"test": {
"scripts": {
"postdeploy": "psql -c \"create extension postgis\" $DATABASE_URL",
"test": "python manage.py migrate --noinput && python manage.py test"
},
"env": {
"DJANGO_DEBUG": "1",
"BUILD_WITH_GEO_LIBRARIES": "1"
},
"addons":[
{
"plan": "heroku-postgresql",
"options": {
"version": "11"
}
}
]
}
}
Here a 2021 update as the setting BUILD_WITH_GEO_LIBRARIES is now deprecated and unsupported by Heroku:
This app.json worked for my CI setup with Django / Heroku:
{
"buildpacks": [
{
"url": "https://github.com/heroku/heroku-geo-buildpack.git"
},
{
"url": "heroku/python"
}
],
"environments": {
"test": {
"scripts": {
"test": "python3 manage.py migrate --noinput && python3 manage.py test --keepdb"
},
"env": {
"DJANGO_DEBUG": "1"
}
}
}
}

Resources