diff --git a/apps/docs/content/guides/platform/migrating-within-supabase.mdx b/apps/docs/content/guides/platform/migrating-within-supabase.mdx index 3d1ac9f9d51..8ec89cd668b 100644 --- a/apps/docs/content/guides/platform/migrating-within-supabase.mdx +++ b/apps/docs/content/guides/platform/migrating-within-supabase.mdx @@ -7,26 +7,23 @@ If you are on a Paid Plan and have physical backups enabled, you should instead to another project feature](/docs/guides/platform/clone-project). ### Caveats -- Project migration is primarily for changing regions or upgrading to new major versions of the platform in some scenarios. If you need to move your project to a different organization without touching the infrastructure, see [project transfers](/docs/guides/platform/project-transfer). -- **Project migration only migrates the Postgres database** which means that everything that is stored in your database will be migrated. However, here is a non-exhaustive list of things to re-configure: - - Edge Functions - - Auth Settings and API keys - - Realtime settings - - Database extensions and settings - - Read Replicas - - Storage objects in S3 buckets ([Migration guide](/docs/guides/platform/migrating-within-supabase#migrate-storage)) +- If you need to move your project to a different organization without touching the infrastructure, see [project transfers](/docs/guides/platform/project-transfer). -### Before you begin +- **Project migration only migrates the Postgres database** and anything else will need to be re-configured. + +### Pre-Migration Checklist + + +
Install postgres and psql} @@ -37,15 +34,16 @@ to another project feature](/docs/guides/platform/clone-project).
+Here are some items to note down your changes made to re-configure in the new project: + + - Auth Settings and API keys + - Edge Functions + - Read Replicas + - Realtime configuration ### Project backup -If you already have a project backup, skip to the Restore project step. You can get the project backup file from sources such as: - -- (For Pro Plan and higher) [Database backups page](https://supabase.com/dashboard/project/_/database/backups/scheduled) -- 90 day paused projects page - -If you do not have a project backup yet, you can do a manual database dump following the guide below: +If you already have the database backup, skip to the Restore project step. - On your project dashboard, click [Connect](https://supabase.com/dashboard/project/_?showConnect=true). - - - - Use the Session pooler connection string by default. If your ISP supports IPv6 or you have the IPv4 add-on enabled, use the direct connection string. - - - - Session pooler connection string: + Get your Session pooler connection string from your [Connect page](https://supabase.com/dashboard/project/_?showConnect=true). Example connection string: ```bash - postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres - ``` - - Direct connection string: - ```bash - postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.com:5432/postgres + postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[PROJECT-REGION].pooler.supabase.com:5432/postgres ``` @@ -98,10 +83,7 @@ If you do not have a project backup yet, you can do a manual database dump follo - Reset the password in the [Database Settings](/dashboard/project/_/settings/database). - - Replace ```[YOUR-PASSWORD]``` in the connection string with the database password. - + Reset and copy the password in the [Database Settings](/dashboard/project/_/settings/database). Replace ```[YOUR-PASSWORD]``` in step 3 with the database password. @@ -112,13 +94,7 @@ If you do not have a project backup yet, you can do a manual database dump follo ```bash supabase db dump --db-url [CONNECTION_STRING] -f roles.sql --role-only - ``` - - ```bash supabase db dump --db-url [CONNECTION_STRING] -f schema.sql - ``` - - ```bash supabase db dump --db-url [CONNECTION_STRING] -f data.sql --use-copy --data-only ``` @@ -129,46 +105,23 @@ If you do not have a project backup yet, you can do a manual database dump follo - ### Restore project backup - - Create a [new project](https://database.new) + + Create a [new project](https://database.new). In the new project: + - If Webhooks were used in the old database, enable [Database Webhooks](/dashboard/project/_/database/hooks). + - If any non-default extensions were used in the old database, enable the [Extensions](/dashboard/project/_/database/extensions). - - In the new project: - - - If Webhooks were used in the old database, enable [Database Webhooks](/dashboard/project/_/database/hooks). - - If any non-default extensions were used in the old database, enable the [Extensions](/dashboard/project/_/database/extensions). - - If Replication for Realtime was used in the old database, enable [Publication](/dashboard/project/_/database/publications) on the tables necessary - - - - - - - Go to the [project page](/dashboard/project/_/) and click the "**Connect**" button at the top of the page for the connection string. - - - - Use the Session pooler connection string by default. If your ISP supports IPv6, use the direct connection string. - - - - Session pooler connection string: - ```bash - postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres - ``` - - Direct connection string: - ```bash - postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.com:5432/postgres - ``` + + Get your Session pooler connection string from your [Connect page](https://supabase.com/dashboard/project/_?showConnect=true). Example connection string: + ```bash + postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[PROJECT-REGION].pooler.supabase.com:5432/postgres + ``` @@ -176,16 +129,13 @@ If you do not have a project backup yet, you can do a manual database dump follo - Reset the password in the [project connect page](/dashboard/project/_?showConnect=true). - - Replace ```[YOUR-PASSWORD]``` in the connection string with the database password. - + Reset and copy the password in the [Database Settings](/dashboard/project/_/settings/database). Replace ```[YOUR-PASSWORD]``` in step 2 with the database password. - Run these commands after replacing ```[CONNECTION_STRING]``` with your connection string from the previous steps: + Replace ```[CONNECTION_STRING]``` with your connection string from the previous steps and run the following command: ```bash psql \ @@ -198,71 +148,92 @@ If you do not have a project backup yet, you can do a manual database dump follo --dbname [CONNECTION_STRING] ``` + ### Migrate Storage -The new project has the old project's Storage buckets, but the Storage objects need to be migrated manually. - -If you have your storage objects locally (eg 90 day paused projects), migrate the storage objects to the new project using this [google colab script](https://colab.research.google.com/github/PLyn/supabase-storage-migrate/blob/main/Supabase_Storage_migration.ipynb). +The new project has the old project's Storage buckets, but the Storage objects need to be migrated manually. If you have your storage objects locally (eg 90 day paused projects), migrate the storage objects to the new project using this [google colab script](https://colab.research.google.com/github/PLyn/supabase-storage-migrate/blob/main/Supabase_Storage_migration.ipynb). If the old project is still active, use this script to move storage objects from one project to another: -```js -// npm install @supabase/supabase-js@1 -const { createClient } = require('@supabase/supabase-js') + +
+ Storage migration script} + id="backup-project" + > + ```js + // npm install @supabase/supabase-js@1 + const { createClient } = require('@supabase/supabase-js') -const OLD_PROJECT_URL = 'https://xxx.supabase.co' -const OLD_PROJECT_SERVICE_KEY = 'old-project-service-key-xxx' + const OLD_PROJECT_URL = 'https://xxx.supabase.co' + const OLD_PROJECT_SERVICE_KEY = 'old-project-service-key-xxx' -const NEW_PROJECT_URL = 'https://yyy.supabase.co' -const NEW_PROJECT_SERVICE_KEY = 'new-project-service-key-yyy' + const NEW_PROJECT_URL = 'https://yyy.supabase.co' + const NEW_PROJECT_SERVICE_KEY = 'new-project-service-key-yyy' -;(async () => { - const oldSupabaseRestClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY, { - schema: 'storage', - }) - const oldSupabaseClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY) - const newSupabaseClient = createClient(NEW_PROJECT_URL, NEW_PROJECT_SERVICE_KEY) + ;(async () => { + const oldSupabaseRestClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY, { + schema: 'storage', + }) + const oldSupabaseClient = createClient(OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY) + const newSupabaseClient = createClient(NEW_PROJECT_URL, NEW_PROJECT_SERVICE_KEY) - // make sure you update max_rows in postgrest settings if you have a lot of objects - // or paginate here - const { data: oldObjects, error } = await oldSupabaseRestClient.from('objects').select() - if (error) { - console.log('error getting objects from old bucket') - throw error - } + // make sure you update max_rows in postgrest settings if you have a lot of objects + // or paginate here + const { data: oldObjects, error } = await oldSupabaseRestClient.from('objects').select() + if (error) { + console.log('error getting objects from old bucket') + throw error + } - for (const objectData of oldObjects) { - console.log(`moving ${objectData.id}`) - try { - const { data, error: downloadObjectError } = await oldSupabaseClient.storage + for (const objectData of oldObjects) { + console.log(`moving ${objectData.id}`) + try { + const { data, error: downloadObjectError } = await oldSupabaseClient.storage .from(objectData.bucket_id) .download(objectData.name) - if (downloadObjectError) { + if (downloadObjectError) { throw downloadObjectError - } + } - const { _, error: uploadObjectError } = await newSupabaseClient.storage - .from(objectData.bucket_id) - .upload(objectData.name, data, { - upsert: true, - contentType: objectData.metadata.mimetype, - cacheControl: objectData.metadata.cacheControl, - }) - if (uploadObjectError) { - throw uploadObjectError - } - } catch (err) { - console.log('error moving ', objectData) - console.log(err) - } - } -})() -``` + const { _, error: uploadObjectError } = await newSupabaseClient.storage + .from(objectData.bucket_id) + .upload(objectData.name, data, { + upsert: true, + contentType: objectData.metadata.mimetype, + cacheControl: objectData.metadata.cacheControl, + }) + if (uploadObjectError) { + throw uploadObjectError + } + } catch (err) { + console.log('error moving ', objectData) + console.log(err) + } + + } + })() + ``` + + +
+
### Troubleshooting notes - If you have created any custom roles with login attribute, you have to manually set their passwords in the new project. -- If you get this error: **"...received invalid response to GSSAPI negotiation..."**. You are likely using psql and Postgres version 15 or lower. Install the latest version to resolve this issue. \ No newline at end of file +- If you get this error: **"...received invalid response to GSSAPI negotiation..."**. You are likely using psql and Postgres version 15 or lower. Install the latest version to resolve this issue. + +``` + +```