From 99579975fc13d01b6eee91cacbe6fa867b71b11c Mon Sep 17 00:00:00 2001 From: danciaclara Date: Thu, 9 Jul 2026 18:50:23 +0530 Subject: [PATCH 1/5] Migrate data to external Postgres and storage --- docs/.vitepress/config.mts | 1 + .../migrate-data-to-external-services.md | 130 ++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 docs/self-hosting/manage/migration/migrate-data-to-external-services.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 2f17635..50f38f0 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -475,6 +475,7 @@ export default extendConfig( { text: "View Logs", link: "/self-hosting/manage/view-logs" }, { text: "Health checks", link: "/self-hosting/manage/health-checks" }, { text: "Migrate Plane", link: "/self-hosting/manage/migrate-plane" }, + { text: "Migrate to external services", link: "/self-hosting/manage/migration/migrate-data-to-external-services" }, { text: "Prime CLI", link: "/self-hosting/manage/prime-cli" }, { text: "Manage users", link: "/self-hosting/manage/manage-instance-users" }, ], diff --git a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md new file mode 100644 index 0000000..99cbc3b --- /dev/null +++ b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md @@ -0,0 +1,130 @@ +--- +title: Migrate to external services +description: Move your Plane data from the default local Postgres and MinIO containers to managed cloud services for a production ready deployment. +--- + +# Migrate to external Postgres and storage + +The default Plane installation includes a local PostgreSQL container and a local MinIO container for storage. These are convenient for getting started, but not recommended for production. For production deployments, use a managed database service and an S3-compatible object store. + +This guide walks through moving your existing data from the local containers to your cloud-managed services. Follow these steps during a maintenance window as the migration requires Plane to be offline. + +## Before you begin + +You need: + +- Docker and Docker Compose installed on the host running Plane +- The PostgreSQL client `psql` and `pg_restore` installed on your local machine +- Your cloud Postgres connection details: host, username, database name, and password +- Your cloud storage connection details: endpoint URL, access key, secret key, and bucket name + +## Stop Plane + +Take Plane offline before starting. This prevents new writes during the migration. + +```bash +docker compose down +``` + +Do not stop the database and MinIO containers yet, you still need them running to export data. + +Start only the database and MinIO: + +```bash +docker compose up -d plane-db plane-minio +``` + +## Export the database +Run `pg_dump` inside the running database container. This creates a compressed binary dump file in your current directory. + +```bash +docker exec \ + -e PGPASSWORD=plane \ + -e PGUSER=plane \ + -e PGDATABASE=plane \ + plane-app-plane-db-1 \ + pg_dump -Fc > plane-backup.dump +``` + +Verify the file was created and is not empty: + +``` +ls -lh plane-backup.dump +``` + +## Restore the database to your cloud Postgres +Use `pg_restore` on your local machine to load the dump into your cloud database. Replace the placeholder values with your actual connection details. + +```bash +pg_restore \ + -h "your-cloud-host.com" \ + -U "cloud-username" \ + -d "cloud-database-name" \ + plane-backup.dump +``` + +You will be prompted for your cloud database password. + +## Sync storage to your cloud bucket +MinIO ships with the `mc` client. Use it from inside the MinIO container to sync your local uploads to your cloud storage. + +1. Create an alias for your local MinIO. + +Your MinIO credentials are in plane.env as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. + +```bash +docker compose --env-file plane.env exec plane-minio \ + mc alias set localminio http://localhost:9000 \ + +``` + +2. Create an alias for your cloud storage. + +```bash +docker compose --env-file plane.env exec plane-minio \ + mc alias set cloudminio \ + +``` + +3. Mirror local data to your cloud bucket. +```bash +docker compose --env-file plane.env exec plane-minio \ + mc mirror localminio/uploads cloudminio/ --overwrite +``` + +This copies all files from the local uploads bucket to your cloud bucket. The `--overwrite` flag replaces any existing files in the destination with the same name. + +Wait for the sync to complete before continuing. + +## Update your environment configuration +Open plane.env and update the database and storage settings to point to your cloud services. + +### Database + +```bash +DATABASE_URL=postgresql://cloud-username:cloud-password@your-cloud-host.com:5432/cloud-database-name +``` + +### Storage + +```bash +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_S3_ENDPOINT_URL= +AWS_S3_BUCKET_NAME= +AWS_REGION = +``` + +## Restart Plane +Bring all services back up + +```bash +docker compose up -d +``` + +Open Plane in a browser and verify that your data, attachments, and pages are intact. + +## After migration +Keep plane-backup.dump in a safe location as a point-in-time backup. + + From 0041986dddbda4474f1e6f5c41c50b92b77c5852 Mon Sep 17 00:00:00 2001 From: danciaclara Date: Thu, 9 Jul 2026 18:51:37 +0530 Subject: [PATCH 2/5] formatting fixes --- docs/.vitepress/config.mts | 5 ++++- .../migration/migrate-data-to-external-services.md | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 50f38f0..ecd2f02 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -475,7 +475,10 @@ export default extendConfig( { text: "View Logs", link: "/self-hosting/manage/view-logs" }, { text: "Health checks", link: "/self-hosting/manage/health-checks" }, { text: "Migrate Plane", link: "/self-hosting/manage/migrate-plane" }, - { text: "Migrate to external services", link: "/self-hosting/manage/migration/migrate-data-to-external-services" }, + { + text: "Migrate to external services", + link: "/self-hosting/manage/migration/migrate-data-to-external-services", + }, { text: "Prime CLI", link: "/self-hosting/manage/prime-cli" }, { text: "Manage users", link: "/self-hosting/manage/manage-instance-users" }, ], diff --git a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md index 99cbc3b..b83bb7e 100644 --- a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md +++ b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md @@ -35,6 +35,7 @@ docker compose up -d plane-db plane-minio ``` ## Export the database + Run `pg_dump` inside the running database container. This creates a compressed binary dump file in your current directory. ```bash @@ -53,6 +54,7 @@ ls -lh plane-backup.dump ``` ## Restore the database to your cloud Postgres + Use `pg_restore` on your local machine to load the dump into your cloud database. Replace the placeholder values with your actual connection details. ```bash @@ -66,6 +68,7 @@ pg_restore \ You will be prompted for your cloud database password. ## Sync storage to your cloud bucket + MinIO ships with the `mc` client. Use it from inside the MinIO container to sync your local uploads to your cloud storage. 1. Create an alias for your local MinIO. @@ -87,6 +90,7 @@ docker compose --env-file plane.env exec plane-minio \ ``` 3. Mirror local data to your cloud bucket. + ```bash docker compose --env-file plane.env exec plane-minio \ mc mirror localminio/uploads cloudminio/ --overwrite @@ -97,6 +101,7 @@ This copies all files from the local uploads bucket to your cloud bucket. The `- Wait for the sync to complete before continuing. ## Update your environment configuration + Open plane.env and update the database and storage settings to point to your cloud services. ### Database @@ -116,6 +121,7 @@ AWS_REGION = ``` ## Restart Plane + Bring all services back up ```bash @@ -125,6 +131,5 @@ docker compose up -d Open Plane in a browser and verify that your data, attachments, and pages are intact. ## After migration -Keep plane-backup.dump in a safe location as a point-in-time backup. - +Keep plane-backup.dump in a safe location as a point-in-time backup. From 9bb2f5302456af4e005e2c797ea88f9776c3c60e Mon Sep 17 00:00:00 2001 From: akshat5302 Date: Thu, 9 Jul 2026 20:35:31 +0530 Subject: [PATCH 3/5] Improve migration guide for external services: enhance clarity, add PostgreSQL version compatibility, and update MinIO instructions --- .../migrate-data-to-external-services.md | 102 ++++++++++++++---- 1 file changed, 84 insertions(+), 18 deletions(-) diff --git a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md index b83bb7e..5c27bf1 100644 --- a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md +++ b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md @@ -1,7 +1,8 @@ --- + title: Migrate to external services description: Move your Plane data from the default local Postgres and MinIO containers to managed cloud services for a production ready deployment. ---- +--------------------------------------------------------------------------------------------------------------------------------------------------- # Migrate to external Postgres and storage @@ -13,10 +14,11 @@ This guide walks through moving your existing data from the local containers to You need: -- Docker and Docker Compose installed on the host running Plane -- The PostgreSQL client `psql` and `pg_restore` installed on your local machine -- Your cloud Postgres connection details: host, username, database name, and password -- Your cloud storage connection details: endpoint URL, access key, secret key, and bucket name +* Docker and Docker Compose installed on the host running Plane +* The PostgreSQL client `psql` and `pg_restore` installed on your local machine +* Your cloud Postgres connection details: host, username, database name, and password +* Your cloud storage connection details: endpoint URL, access key, secret key, and bucket name +* Your cloud PostgreSQL version should ideally match your source PostgreSQL version ## Stop Plane @@ -49,16 +51,33 @@ docker exec \ Verify the file was created and is not empty: -``` +```bash ls -lh plane-backup.dump ``` ## Restore the database to your cloud Postgres -Use `pg_restore` on your local machine to load the dump into your cloud database. Replace the placeholder values with your actual connection details. +Before restoring, clear the existing schema in your cloud database. + +```bash +psql \ + -h "your-cloud-host.com" \ + -U "cloud-username" \ + -d "cloud-database-name" \ + -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;" +``` + +Restore the dump using `pg_restore`. + +The `--no-owner` flag prevents ownership errors when the source database roles do not exist in your cloud database. + +The `--no-privileges` flag skips grants for roles that may not exist in the target database. ```bash pg_restore \ + --no-owner \ + --no-privileges \ + --verbose \ -h "your-cloud-host.com" \ -U "cloud-username" \ -d "cloud-database-name" \ @@ -67,13 +86,28 @@ pg_restore \ You will be prompted for your cloud database password. +### PostgreSQL version compatibility + +Use a `pg_restore` version that matches your target PostgreSQL version when possible. + +For example, if your cloud database is PostgreSQL 15, use PostgreSQL 15 client tools. + +If you use a newer `pg_restore` version, you may see: + +```text +ERROR: unrecognized configuration parameter "transaction_timeout" +Command was: SET transaction_timeout = 0; +``` + +This warning can be ignored if the restore continues successfully. Using matching PostgreSQL client tools avoids this warning. + ## Sync storage to your cloud bucket MinIO ships with the `mc` client. Use it from inside the MinIO container to sync your local uploads to your cloud storage. -1. Create an alias for your local MinIO. +### 1. Create an alias for your local MinIO -Your MinIO credentials are in plane.env as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. +Your MinIO credentials are in `plane.env` as `MINIO_ROOT_USER` and `MINIO_ROOT_PASSWORD`. ```bash docker compose --env-file plane.env exec plane-minio \ @@ -81,28 +115,56 @@ docker compose --env-file plane.env exec plane-minio \ ``` -2. Create an alias for your cloud storage. +### 2. Create an alias for your cloud storage + +For AWS S3, use the S3 endpoint. + +Default AWS endpoint: + +```bash +docker compose --env-file plane.env exec plane-minio \ + mc alias set cloudminio https://s3.amazonaws.com \ + +``` + +Regional AWS S3 endpoint: ```bash docker compose --env-file plane.env exec plane-minio \ - mc alias set cloudminio \ + mc alias set cloudminio https://s3..amazonaws.com \ ``` -3. Mirror local data to your cloud bucket. +For other S3-compatible providers, replace the endpoint with your provider's S3 endpoint. + +Verify the connection: + +```bash +docker compose --env-file plane.env exec plane-minio \ + mc ls cloudminio +``` + +### 3. Mirror local data to your cloud bucket ```bash docker compose --env-file plane.env exec plane-minio \ mc mirror localminio/uploads cloudminio/ --overwrite ``` -This copies all files from the local uploads bucket to your cloud bucket. The `--overwrite` flag replaces any existing files in the destination with the same name. +Example: + +```bash +docker compose --env-file plane.env exec plane-minio \ + mc mirror localminio/uploads cloudminio/my-plane-bucket --overwrite +``` + +This copies all files from the local uploads bucket to your cloud bucket. The `--overwrite` flag replaces existing files with the same name. Wait for the sync to complete before continuing. ## Update your environment configuration -Open plane.env and update the database and storage settings to point to your cloud services. +Open `plane.env` and update the database and storage settings to point to your cloud services. ### Database @@ -112,17 +174,21 @@ DATABASE_URL=postgresql://cloud-username:cloud-password@your-cloud-host.com:5432 ### Storage +For AWS S3: + ```bash AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= -AWS_S3_ENDPOINT_URL= +AWS_S3_ENDPOINT_URL=https://s3.amazonaws.com AWS_S3_BUCKET_NAME= -AWS_REGION = +AWS_REGION= ``` +For other S3-compatible providers, replace `AWS_S3_ENDPOINT_URL` with your provider endpoint. + ## Restart Plane -Bring all services back up +Bring all services back up: ```bash docker compose up -d @@ -132,4 +198,4 @@ Open Plane in a browser and verify that your data, attachments, and pages are in ## After migration -Keep plane-backup.dump in a safe location as a point-in-time backup. +Keep `plane-backup.dump` in a safe location as a point-in-time backup. \ No newline at end of file From ee04b58bf8f6197756646a15e4d2ec8887bd59da Mon Sep 17 00:00:00 2001 From: danciaclara Date: Fri, 10 Jul 2026 15:35:14 +0530 Subject: [PATCH 4/5] formatting fixes --- .../migrate-data-to-external-services.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md index 5c27bf1..85275b8 100644 --- a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md +++ b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md @@ -1,8 +1,7 @@ --- - title: Migrate to external services description: Move your Plane data from the default local Postgres and MinIO containers to managed cloud services for a production ready deployment. ---------------------------------------------------------------------------------------------------------------------------------------------------- +--- # Migrate to external Postgres and storage @@ -14,11 +13,11 @@ This guide walks through moving your existing data from the local containers to You need: -* Docker and Docker Compose installed on the host running Plane -* The PostgreSQL client `psql` and `pg_restore` installed on your local machine -* Your cloud Postgres connection details: host, username, database name, and password -* Your cloud storage connection details: endpoint URL, access key, secret key, and bucket name -* Your cloud PostgreSQL version should ideally match your source PostgreSQL version +- Docker and Docker Compose installed on the host running Plane +- The PostgreSQL client `psql` and `pg_restore` installed on your local machine +- Your cloud Postgres connection details: host, username, database name, and password +- Your cloud storage connection details: endpoint URL, access key, secret key, and bucket name +- Your cloud PostgreSQL version should ideally match your source PostgreSQL version ## Stop Plane @@ -198,4 +197,4 @@ Open Plane in a browser and verify that your data, attachments, and pages are in ## After migration -Keep `plane-backup.dump` in a safe location as a point-in-time backup. \ No newline at end of file +Keep `plane-backup.dump` in a safe location as a point-in-time backup. From fefaf4dae6720c06d98f838a9c4ae9dc9bd4f4ae Mon Sep 17 00:00:00 2001 From: danciaclara Date: Fri, 10 Jul 2026 15:36:54 +0530 Subject: [PATCH 5/5] coderabbit fixes --- .../manage/migration/migrate-data-to-external-services.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md index 85275b8..fb39182 100644 --- a/docs/self-hosting/manage/migration/migrate-data-to-external-services.md +++ b/docs/self-hosting/manage/migration/migrate-data-to-external-services.md @@ -1,6 +1,7 @@ --- title: Migrate to external services description: Move your Plane data from the default local Postgres and MinIO containers to managed cloud services for a production ready deployment. +keywords: Plane migration, external Postgres, cloud storage, MinIO migration, self-hosted Plane, production deployment, pg_dump, pg_restore, S3-compatible storage --- # Migrate to external Postgres and storage