Release Command for DB Migrations

I’ve just migrated from Heroku and I’m very pleased with render.

One thing I’m missing are release-commands.

Heroku offers a very simple way to run only-once one-off commands during the release of a new version. Those commands are entries in the Procfile like:

release: bundle exec rake db:migrate
...

As the example shows, those release-commands can be used to run migrations before the new version is released.

We don’t currently offer release commands, precisely like that, but do you think adding the command to your service’s startCommand would help? This will make sure that the command is run, every time you have a new build. For instance, the following will first run the copy command and then start the application. Let me know if this helps.
startCommand: cp file.txt src/ ; yarn start

No, this won’t guarantee the “only once” character of the command if I run on more than one instance.

Actually, it should be “exactly once”

Looks like the intended use is to add this to a build-script. Seen in the Rails example https://render.com/docs/deploy-rails#create-a-build-script

Does the build script work for migrations with the Docker environment?

Yes- the build phase is a good place for migrations with Docker as well. It’s not quite the same in that it’s not an actual “build script” field like in other languages, but you can just put it in your Dockerfile as it will be built with every deploy.

Wait I do the DB migrations in the Dockerfile build? That doesn’t seem normal or secure as then I would need to pass the DB connect as a build arg which is saved in the final docker image. It does look like you pass environment args to build args so I will go ahead and do that for now but it is a bummer as local dev will now have to have a different container vs render one. Also, that image now will always have those values in its metadata (A tableau of crimes and misfortunes: the ever-useful `docker history`). You would have to use the new Buildkit --secret for it not to be in the image history. So I hope you are running a very secure image repo locally.

In other pipelines, I have worked on, we normally have a step after the docker image build that runs the docker image with a different command to do the migrations of anything before spinning up the new images. Having a post-build step to run commands would really help here.

Also you all should really consider not passing all environment variables to the docker build as build args but instead support a different param for it to just be safe and use the Buildkit --secrets to use it.

We agree it’s pretty unusual. We’re aware of the need for some service lifecycle hooks for things like running migrations and that’s something we’re looking into building. That is to say, we don’t have a hook right now to run migrations. The workaround that many have done is to incorporate it into their build scripts, but that can be less-than-ideal for some use cases. Docker services is one of those. We’re happy to add this to feedback.render.com which we take into account when planning our work.

We also have an open issue of manually triggering jobs (e.g. migrations) which people have worked around by creating cron jobs that run extremely infrequently (or even are suspended). Perhaps this would work for you. The idea is to create a Docker cron job and add your migration command as its run command (no Dockerfile changes needed). Then you can control when you run your migrations.

As for BuildKit secrets, you might be happy to know that we do support them backed by secret files. We don’t have official docs on that yet, but you can see the approach in this short thread.