Heroku Run via Custom Crystal Buildpack

I’m deploying a Kemal web service to Heroku using the Crystal Heroku Buildpack (github) Brian and the team have provided.

It works great, deployed successfully, and serves the Kemal app correctly. Very much appreciate the work done to enable this for everyone, thanks!

Once I added a DB (PostgreSQL), and the jennifer.cr shard for DB ORM similar to ActiveRecord, I got stuck. Jennifer uses sam.cr for rake tasks similar to rake db:create db:migrate, etc. Which is great! Unfortunately I’m not sure how to run them on the heroku dynos. I can do heroku run SOME_SCRIPT.sh etc, so tried doing heroku run make sam db:create as I would use locally (make sam db:create). This doesn’t work though because it uses crystal to run the sam tasks. If I just run bash in a heroku dyno using heroku run bash I can see crystal isn’t installed:

~ $ heroku run bash
Running bash on ⬢ tabster... up, run.7101 (Free)
~ $ crystal
bash: crystal: command not found

Perhaps it’s just not available via PATH but I’m guessing it’s not using the custom heroku-buildpack-crystal buildpack. So how can I use heroku run to use that buildpath?

$ heroku buildpacks
=== tabster Buildpack URL
https://github.com/crystal-lang/heroku-buildpack-crystal.git

Or how can I run a script to execute crystal on the heroku dyno? Or if that’s not possible (would totally understand) how should I approach creating and migration the database to match my db/structure.cr. I could manually create the DB using PostgreSQL commands, but wouldn’t be able to create the table structures/columns, as Jennifer/Sam do that programmatically via the migrations.

Any insight would be much appreciated!

This is just a hobby guitar web app, so no rush here. Very excited to be working with crystal, I’ve loved it so far. Great to be working with a compiled language, with the awesome style/syntax of ruby. I’ve previously been messing with it for 2D and 3D game development, which has been fun.

I’ve written a few apps for AWS fargate and had similar problems.
The whole init a microservice or distributed app can be challenging.

The quick and easy approach would be to have a protected route that performs the task

We’ve also put together containers that can be used to launch tasks

If you can run commands against your executable you could add a command line flag

I’ve not had much experience with heroku but hope that helps

Ha I recently did have a similar thought to make a temporary/protected route to do what was needed, this confirms it would work and isn’t too crazy of an idea. This makes sense, thanks a lot for sharing! At least with this approach I can move forward for now.

Somebody should update the buildpack to invoke shards build and expect the app being configured as a target in shard.yml. Then you could just add your sam.cr as a target to the shard.yml and then something like heroku run bin/sam db:create should work.

3 Likes

Thanks @jhass, that would be great, ultimately what I’m looking for. I can look at forking the heroku buildpack repo myself, to see if I could try to accomplish that.

1 Like