I’m starting to use Preview Environments, and would like to seed the database.
initialDeployHook on the official docs and in community posts.
- Does the
initialDeployHook script only run for preview environments or all does this field affect all environments?
- When does initialDeployHook run? Some of the posts I found say after startCommand some say before. For the first deploy is the flow: initialDeployHook → buildCommand → startCommand?
- Most examples I see sets initialDeployHook on a service, can it be set on the database config in render.yaml?
- name: postgres
My stack and current flow for context on my questions:
- Django Backend
- Postgres DB
I have a cron that stores db backups in S3 forked and modified from this: GitHub - render-examples/postgres-s3-backups. I’ve written my initialDeployScript to download and backfill my postgres db with the daily backup.
The next step I’m trying to understand is if my initialDeployHook needs to re-run my django migrations, which currently run in my buildCommand (as suggested here: Getting Started with Django on Render | Render), and if I need to add safety checks in my script to only run if it’s a render preview environment.
My understanding is initialDeployHook runs on all environments, including Preview Environments.
Our initialDeployHook is setup to sync the database from S3 for preview environments only and run migrations for all environments.
initialDeployHook: "bundle exec rails sync_database; bundle exec rails db:migrate;"
render-build.sh has code like this:
# If this is not the master branch, enforce the REVIEW_APP to be true
if [ "$RENDER_GIT_BRANCH" != "master" ]; then
printf "\n==> Setting REVIEW_APP=enabled since deploying to a non-master branch\n\n"
if [ "$REVIEW_APP" != "enabled" ]; then
printf "\n==> Running pending database migrations\n\n"
bundle exec rake db:migrate
printf "\n==> Skipping db:migrate\n\n"
sync_database has code to skip any sync if it’s a production environment.
So if you look at the above, when you first launch a preview environment, we will grab our DB snapshot from S3 and sync it. Then run any DB migrations that preview environment might have for it.
For any subsequent to preview environments (like pushes to PR),
render-build.sh runs any DB migrations that might be outstanding.
My understanding is the following run order:
So technically, the web server is running in a preview environment while the seed database is being restored. We tell our developers to not touch the preview environment until the seed database is done restoring, else you write to the DB while it’s being restored – and usually breaks the app and you have to start all over again.
We’re working on a new enhancement to display a maintenance page while the database is still being restored.
Forgot to ask, if you’re open to sharing here, how do you handle environment variables for your preview branch?
Unfortunately, we have to overload both development and production environmental variables into the preview apps. So imagine you have a two API keys for dev and production for some service. Our preview environments carry both of them and are just suffixed
Not very elegant. Ideally, these staging environments should not carry production keys.
We only do this approach with one API. In general, we limit the number of APIs that get this and just have a single key that shared between staging/production and we restrict access through other means.