There is plenty of information about this. The basic idea goes like so -
Create a script that does the database migration, but make sure that it only adds tables and fields - never removes, renames, or changes the type of existing tables or fields.
The new version of the application will start using the new tables/fields when it is an existing field from the previous version that needed a change - the app must continue the previous version as it used to, and start using the new version as well.
In some cases, before the newly created field can be used it needs to be populated based on the previous field - the application can do this when it first starts.
If some functionality depends on the new field, and it is not yet ready, opening it to users can be hidden behind a feature flag that is toggled when ready to expose the new functionality.
When yet another version is released, the application can finally stop writing to the old field you were using and start using the new field exclusively.
The above mostly explains what happens when fields need to be renamed or type changed. For new tables or fields, it is much simpler since the existing version is not using these.