DevelopingSpace / starchart

A self-serve tool for managing custom domains and certificates
MIT License
20 stars 13 forks source link

Prepare for, document, and automate our database migration and deployment strategy #291

Closed humphd closed 1 year ago

humphd commented 1 year ago

In order to ship the app to staging(#43) we need to get ready to handle database migrations.

Currently, we are working with a development database locally, which can be blown away whenever we need to fix something. That won't work as soon as we move this to staging and production (hopefully in 0.5). In those cases, we'll have to create migrations and run them.

I am not an expert on this, but here is my current understanding of the problem and solution. Hopefully others will help with the research and implementation. I am basing this largely on the Prisma Migrate Mental Model:

  1. In development, we use prisma db push to force the local development database to use our schema. This has been fine for development up to now, but won't work going forward
  2. In staging and production (henceforth referred to as "prod"), we need to use prisma migrate deploy to run migrations against the database and synchronize it with our desired schema.
  3. Doing 2. requires us to first create a set of migrations in prisma/migrations, which are SQL files that describe transformations from one database state to another (e.g., adding a table, creating an index, etc). We do that using prisma migrate dev --name init.
  4. Now we can use prisma migrate deploy in prod to update our database (i.e., push schema and/or apply migrations).
  5. Whenever we need to alter our schema after we establish our baseline migration, we need to create a new migration SQL file using prisma migrate dev --name <name_of_migration>. This SQL migration would then be applied in prod using prisma migrate deploy
  6. We need to include prisma migrate deploy in our webhook deploy step
  7. Running prisma migrate deploy automatically in prod will require updates to our Dockerfile, in order to create an image layer that has the necessary dependencies and migrations
  8. This entire process needs to be carefully document in our CONTRIBUTING and DEPLOY docs

What else am I missing?

If we want to do any significant database schema changes before 1.0, it might be nice to do them before we set this baseline.

cc @cychu42, @dadolhay, @sfrunza13, @shawnyu5, who might all be interested in parts of this, or have thoughts. Anyone else is also welcome to take bits of this.

ghost commented 1 year ago

@humphd I agree with the above, for multiple reasons

TL;DR I agree, but I'd put it off as long as possible

P.S. Could we do a full export (db dump) of the prod database before a migration is run, and keep it in a secure storage for like 1 month?

humphd commented 1 year ago

@dadolhay maybe we should avoid automating the migrations with Prisma, and if we need to do one, we have to do it manually? Then we can bring down the instances, run a backup, migrations, test manually, etc. We'll still have a problem, though. In staging, our idea was to deploy when we land on main. If we ever land a schema change on main, it will cause issues. So we'd have to somehow come-up with a work around for this. With production, we can do it when we tag, so it requires manually opt-in. It's still a bit complicated. Thoughts?

I agree with leaving the baseline as long as possible. I don't want to deal with migrations any more often than we have to. While we're still pre 1.0, it would be good to not get into this.

cychu42 commented 1 year ago

Agree. If we can put it off, we should. I like only triggering deployment on certain tags, as long as we keep clear documentation so people know what to do. The only two additional things on my mind now are:

humphd commented 1 year ago

I think you're both making great points. I wonder if we should decide to avoid all automatic schema updates pre-1.0, try hard to nail down the schema ASAP, and ask ourselves how to approach ongoing maintenance when we get to 1.0 (i.e, don't assume we'll do it).

This leaves another question that I need to answer ASAP: what does the manual process for creating/updating the databases on staging and production look like?

The Docker image we build for staging/production currently doesn't include the Prisma tools, schema, etc. I could add a build stage that does include this, and we could use that stage's image to manually run prisma db push or whatever.

Help me think through the flow we'll use, since I need to do it in the next two weeks in order to get this up on staging.

ghost commented 1 year ago

I think it is going to be needed to do an automated (pre-scripted to be precise) migration method post-1.0

humphd commented 1 year ago

OK, I'll leave this open for 1.0, and wrote https://github.com/DevelopingSpace/starchart/pull/325 to try and do a manual solution for the 0.6-1.0.

humphd commented 1 year ago

Adding this to the 0.9 milestone, assigning to @cychu42

humphd commented 1 year ago

Plan/TODO:

cychu42 commented 1 year ago

I'm think we might want to turn the prisma migrate dev command into a script for future users. Also, definitely tell people that they need to create migration files to affect staging and production in documentation, once migration is in place.

humphd commented 1 year ago

We've tested this on staging, and it's all working. Well done @cychu42.