The first thing we'll need is a database. subZero service runs in AWS us-east-1 so that's where we'll create our PostgreSQL RDS instance to have low latency between the database and subZero (other regions will be available).
Create the database¶
To create the database we'll use a handy cloudformation stack that will spin up a free tier RDS instance in your AWS account. Just click the button below and fill in all the fields.
If you prefer to customize the database instance, follow this link to create one. Make sure you select PostgreSQL, make it publicly available and then add a rule in it's security group to allow subzero to connect to it.
The database creation process will take about 5 minutes, so until it's ready you can skip for a moment "connect to the database" part and continue with creating a subzero account the you can come back later to get the connection info for your database.
Connect to the database¶
When the stack creation completes, click on the
Outputs tab where you will find connection information for the database.
The database is ready; let's move to the next step.
Prepare the migrations folder¶
During the development process, we worked with files from
db/src/ to define our schema. Whenever we changed something,
subzero cli dropped and recreated the local development database to reflect those changes, however, when we want to deploy the changes we can not just drop the database since we would lose the data in the tables. This is where the migrations come in. We'll maintain a
db/migrations folder that will contain simple sql scripts that migrate our database schema from state A to state B. Don't worry, this process is almost entirely automated, you won't have to create those files manually, they will be created by
subzero cli based on the files from
db/src/. Let's start the process.
In the root of your project execute
subzero migrations init --with-roles
The output will look similar to this
Created sqitch.conf Created sqitch.plan Created deploy/ Created revert/ Created verify/ Starting temporary PostgreSQL database with the version matching your dev database (postgres:13) on port 42585 with SQL from /db/src 1e35351fa92ac1aab67293dedd6234f572fa790c8a7b4f2833c01a9ee7f215ed Waiting for temp_postgres_ihmku container to load PostgreSQL init process complete; ready for start up. Writing database dump to /db/migrations/tmp/20210223104353-dev-initial.sql Writing database roles dump to /db/migrations/tmp/20210223104353-dev-initial.sql.roles Starting temporary PostgreSQL database with the version matching your dev database (postgres:13) on port 40073 with SQL from /db/migrations/deploy bec371d797e883b93278ec36c8890aaa4bd81db8132c4b860ff6fab414983ea0 Waiting for temp_postgres_3i5cg container to load PostgreSQL init process complete; ready for start up. Diffing databases using migra Writing the result to /db/migrations/tmp/20210223104353-revert-initial.sql Created deploy/20210223104353-initial.sql Created revert/20210223104353-initial.sql Created verify/20210223104353-initial.sql Added "20210223104353-initial" to sqitch.plan Copying /db/migrations/tmp/20210223104353-dev-initial.sql to /db/migrations/deploy/20210223104353-initial.sql
Commit the changes to git
git add db/migrations/
git commit -m "initial database migration"
A word to the wise
We've chosen to perform the first deploy as a step immediately after setting up our project locally to be able to illustrate later how one would iterate on a project running in production (implement a feature -> push to production). In practice however you want to postpone this first deploy for when you have something closer to an MVP. The reason is that during the early stages you will have a lot of changes in your database schema and it will be a lot of work creating migrations (even though it's mostly automated) for all those changes and checking their correctness. At this stage it's better to avoid having migrations altogether. However, it you still need a common staging deployment until you go to production, we recommend working locally on your application and adapt your deploy script to recreate the
db/migrations/ folder each time and reset your test database before deploying the new schema changes.
In a later tutorial, we'll see how we can create a new migrations after we've added a few changes to our database schema
Configure GitHub secrets¶
subZero's deploy process is implemented using GitHub Actions
If you are interested in the exact deploy steps, look at
.github/workflows/test_deploy.yml configuration file.
Create the following encrypted secrets in your github repository (Settings > Secrets > New repository secret). Detailed steps are described here
|SUBZERO_EMAIL||The email you used to create a subzero.cloud account|
|SUBZERO_PASSWORD||subzero.cloud account password|
|APP_DOMAIN||The desired application domain. For free accounts you can only use subdomains in the form
|APP_DB_HOST||Production database host name (or IP)|
|APP_DB_PORT||Database port (usually it's 5432)|
|APP_DB_NAME||The database name|
|APP_DB_MASTER_USER||Database user with SUPERUSER privileges. This user is only used by the deploy scripts to deploy the database migrations, It's not sent or stored in subzero.cloud|
|APP_DB_MASTER_PASSWORD||Master user password|
|APP_DB_AUTHENTICATOR_USER||Database user that subzero.cloud uses to connect to your database when executing API requests. Use
|APP_DB_AUTHENTICATOR_PASSWORD||Authenticator user password|
|APP_JWT_SECRET||The JWT secret used by subzero.cloud (and some functions in your database) to sign and verify JWT tokens.
Make sure the secret is at least 32 characters long!
git push to deploy¶
Whenever we are ready to deploy new changes, we just tag our revision and push the tag.
First make sure all your local changes are committed and pushed.
The output should be similar to
On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean
Now let's tag our current version
git tag v1.0
And push this tag
git push --tags
The new git tag will trigger the test and deploy jobs that will run all the database migrations and create (and later update) the subzero.cloud configuration for your application.