From e49577f3d1d94f676a93dd0caba36f73cea61ca6 Mon Sep 17 00:00:00 2001 From: Luis Ibarra Date: Thu, 17 Sep 2026 12:22:18 -0500 Subject: [PATCH 1/3] docs: document non-interactive instance restores --- .../setup/instance-management/appsmithctl.mdx | 18 +++- .../backup-and-restore/restore-instance.mdx | 93 ++++++++++++++++++- 2 files changed, 107 insertions(+), 4 deletions(-) diff --git a/website/docs/getting-started/setup/instance-management/appsmithctl.mdx b/website/docs/getting-started/setup/instance-management/appsmithctl.mdx index 94246a6edc..db32499018 100644 --- a/website/docs/getting-started/setup/instance-management/appsmithctl.mdx +++ b/website/docs/getting-started/setup/instance-management/appsmithctl.mdx @@ -90,9 +90,23 @@ For [Appsmith paid plans](https://www.appsmith.com/pricing), backups can be uplo ```bash appsmithctl restore ``` -- The `restore` command restores the Appsmith instance, including the internal database, `docker.env`, and Git data, from an encrypted backup file. You will need the password used during the backup process to decrypt the backup. Without this password, the restore process will fail. +- The `restore` command restores the Appsmith instance, including the internal database, `docker.env`, and Git data. For encrypted backups, you need the password used during the backup process to decrypt the archive. - The restore process assumes that the backup file is located at `/appsmith-stacks/data/backup/` within the container. - - The backup file should follow the naming pattern `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz.enc`. + - The backup file should follow the naming pattern `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz.enc` for encrypted archives, or `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz` for unencrypted archives. + +Starting with Appsmith v2.4.1, use the following options to automate restores: + +```bash +appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc +``` + +| Option | Description | +| --- | --- | +| `--backup-file=` | Selects an exact archive filename, including its extension, without the selection prompt. Requires `=` and a filename, not a path or index. Checks local backups and, on eligible instances, configured S3 backups, preferring the local copy. | +| `--non-interactive` | Disables all prompts. Requires `--backup-file=` and the appropriate secrets in the restore process environment. Missing or invalid inputs exit with status `1`. | +| `--force` | Allows a version mismatch only when used with `--non-interactive`. Other validation still applies. | + +For encrypted archives, supply `APPSMITH_BACKUP_ARCHIVE_PASSWORD` as a temporary environment variable for the invocation. For unencrypted archives, supply the source instance's `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`. See [Automate restores](/getting-started/setup/instance-management/backup-and-restore/restore-instance#automate-restores) for Docker and Kubernetes examples, secret handling, and pipeline failure behavior. For more information about restoring an Appsmith instance, see [Restore Instance](/getting-started/setup/instance-management/backup-and-restore/restore-instance) guide. diff --git a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx index de7d28b00e..57a5f54fe6 100644 --- a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx +++ b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx @@ -7,7 +7,7 @@ import TabItem from '@theme/TabItem'; # Restore Instance -This page explains how to restore your self-hosted Appsmith instance backup using the `appsmithctl` utility. +This page explains how to restore your self-hosted Appsmith instance backup using the `appsmithctl` utility. You can restore interactively or [automate restores](#automate-restores) in a deployment pipeline. ## Prerequisites @@ -91,6 +91,95 @@ Follow these steps to restore your Appsmith instance for Kubernetes-based instal +## Automate restores + +Starting with Appsmith **v2.4.1**, you can run `appsmithctl restore` without prompts for automated disaster recovery or environment rebuilds. Pin your pipeline's Appsmith image to v2.4.1 or later. Older images may ignore these flags and wait for interactive input. + +```bash +appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc +``` + +### Select the backup + +Use `--backup-file=` with the exact archive filename, including its extension. The `=` is required. Supply a filename, not a path, URL, or interactive list index. The command does not automatically select the latest backup. + +Copy the archive to `/appsmith-stacks/data/backup/` inside the container or pod using the steps above. For instances with [S3 backups configured](/getting-started/setup/instance-management/backup-and-restore/sync-backup-to-s3) and an active paid plan, the command also checks S3. It uses the local archive when the filename exists in both locations; otherwise, it downloads the matching S3 archive before restoring it. + +### Supply the required secrets + +The required environment variables depend on the archive format: + +| Archive | Required secrets | +| --- | --- | +| Encrypted (`.tar.gz.enc`) | Set `APPSMITH_BACKUP_ARCHIVE_PASSWORD` to the password used when creating the archive. Appsmith restores the instance encryption keys from the encrypted backup. | +| Unencrypted (`.tar.gz`) | Set both `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` to the values from the instance that created the backup. The archive password is not required. | + +Supply the archive password as a temporary secret for the restore invocation, using your CI/CD secret store. Do not save it in `docker.env`, Helm values, or source control. If `APPSMITH_BACKUP_ARCHIVE_PASSWORD` is set, Appsmith uses it for one decryption attempt, even in interactive mode. + +For an unencrypted backup from the same instance, you can use its existing encryption password and salt. When restoring another instance's backup, supply that source instance's values before running the command. The command checks that both values are present; you must ensure they match the source instance. + +### Run the restore + +The following examples restore an encrypted archive. Replace `TIMESTAMP`, the container or pod name, and the namespace with your values. + + + + + +Configure your pipeline to inject `APPSMITH_BACKUP_ARCHIVE_PASSWORD` into the runner's environment, then pass it to the restore process: + +```bash +docker exec \ + -e APPSMITH_BACKUP_ARCHIVE_PASSWORD \ + appsmith appsmithctl restore \ + --non-interactive \ + --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc +``` + +Do not allocate a TTY (`-t`) for pipeline execution. To use Docker Compose, replace `docker exec` with `docker-compose exec -T` in this example. + +For an unencrypted archive, use the `.tar.gz` filename and omit `-e APPSMITH_BACKUP_ARCHIVE_PASSWORD`. If supplying the source instance's encryption keys from the runner, pass them with `-e APPSMITH_ENCRYPTION_PASSWORD -e APPSMITH_ENCRYPTION_SALT`. + + + + + +Make `APPSMITH_BACKUP_ARCHIVE_PASSWORD` available to the restore process in the target pod through your Kubernetes secret management workflow. Setting it only on the machine running `kubectl` does not pass it into the pod. Limit its availability to the recovery operation and remove the temporary secret configuration afterward. + +```bash +kubectl exec -n APPSMITH_NAMESPACE ANY_APPSMITH_POD_NAME -- \ + appsmithctl restore \ + --non-interactive \ + --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc +``` + +For an unencrypted archive, use the `.tar.gz` filename and ensure the restore process has the source instance's `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`. + +After a successful restore, if autoscaling is turned on, restart the Appsmith deployment: + +```bash +kubectl rollout restart deployment appsmith -n APPSMITH_NAMESPACE +``` + +With autoscaling turned off, or on Community Edition, the restore command restarts the Appsmith server. + + + + + +### Handle failures in a pipeline + +Make your pipeline stop when the restore command returns a nonzero exit status. Missing or unknown backup filenames, paths supplied as filenames, missing secrets, failed decryption, and version mismatches return exit code `1` without prompting. These checks occur before the restore stops services or changes the database. A failure during the restore itself can leave the instance partially restored. + +By default, non-interactive restore stops if the backup's Appsmith version differs from the running instance. Use a matching version when possible. To deliberately proceed despite a version mismatch, add `--force`: + +```bash +appsmithctl restore --non-interactive \ + --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc --force +``` + +`--force` only bypasses the version check in non-interactive mode. It does not bypass archive or secret validation, and it does not guarantee compatibility between versions. Without `--non-interactive`, the version confirmation prompt still appears. + ## Troubleshooting If you encounter any issues during the restore process, consider the following: @@ -102,4 +191,4 @@ If you encounter any issues during the restore process, consider the following: - If using encrypted backups, confirm that the encryption password and salt match the original values used during backup creation. - If restarting the pods fails, check the logs for errors. For more information, see [Get Container logs](/getting-started/setup/instance-management/how-to-get-container-logs) guide. -If you continue to face issues, contact support using the chat widget available in the bottom-right corner of this page. \ No newline at end of file +If you continue to face issues, contact support using the chat widget available in the bottom-right corner of this page. From 7308df9a0024754f19b2fbc5567f7426880bb567 Mon Sep 17 00:00:00 2001 From: Luis Ibarra Date: Fri, 18 Sep 2026 18:22:02 -0500 Subject: [PATCH 2/3] docs: simplify automated restore guidance --- .../backup-and-restore/restore-instance.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx index 57a5f54fe6..d63d7a150e 100644 --- a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx +++ b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx @@ -7,7 +7,7 @@ import TabItem from '@theme/TabItem'; # Restore Instance -This page explains how to restore your self-hosted Appsmith instance backup using the `appsmithctl` utility. You can restore interactively or [automate restores](#automate-restores) in a deployment pipeline. +This page explains how to restore your self-hosted Appsmith instance backup using the `appsmithctl` utility. ## Prerequisites @@ -93,7 +93,7 @@ Follow these steps to restore your Appsmith instance for Kubernetes-based instal ## Automate restores -Starting with Appsmith **v2.4.1**, you can run `appsmithctl restore` without prompts for automated disaster recovery or environment rebuilds. Pin your pipeline's Appsmith image to v2.4.1 or later. Older images may ignore these flags and wait for interactive input. +Starting with Appsmith **v2.4.1**, you can run `appsmithctl restore` without prompts for automated disaster recovery or environment rebuilds. ```bash appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc @@ -101,7 +101,7 @@ appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.ta ### Select the backup -Use `--backup-file=` with the exact archive filename, including its extension. The `=` is required. Supply a filename, not a path, URL, or interactive list index. The command does not automatically select the latest backup. +Use `--backup-file=` with the exact archive filename, including its extension. The command does not automatically select the latest backup. Copy the archive to `/appsmith-stacks/data/backup/` inside the container or pod using the steps above. For instances with [S3 backups configured](/getting-started/setup/instance-management/backup-and-restore/sync-backup-to-s3) and an active paid plan, the command also checks S3. It uses the local archive when the filename exists in both locations; otherwise, it downloads the matching S3 archive before restoring it. From a340130c5383e675464992a9f075734f57cf115f Mon Sep 17 00:00:00 2001 From: Luis Ibarra Date: Tue, 22 Sep 2026 11:10:55 -0300 Subject: [PATCH 3/3] docs: tighten automated restore guidance and secret handling Move the restore option table out of the appsmithctl subcommand index into the guide it defers to, and drop the duplicated pod-restart block. Replace the Kubernetes command-line password example with a Secret-based procedure. kubectl exec arguments travel as query parameters in the request URI, so kube-apiserver audit logs would record the archive password in plaintext, and an encrypted archive's docker.env carries the instance encryption keys. Correct three points about the secrets themselves. The archive password is transient and must not be persisted; APPSMITH_ENCRYPTION_PASSWORD and APPSMITH_ENCRYPTION_SALT are durable and do belong in the instance's docker.env. Appsmith checks only that the latter two are present, not that they match the source instance. Document APPSMITH_BACKUP_ARCHIVE_PASSWORD in the environment variable reference, and record on the backup pages that appsmithctl backup writes an unencrypted archive when no terminal is attached, which is where the restore guide's unencrypted path comes from. Co-Authored-By: Claude Opus 5 --- .../setup/environment-variables.md | 10 ++ .../setup/instance-management/appsmithctl.mdx | 19 +--- .../backup-and-restore/backup-instance.mdx | 4 + .../backup-and-restore/restore-instance.mdx | 102 ++++++++++-------- 4 files changed, 73 insertions(+), 62 deletions(-) diff --git a/website/docs/getting-started/setup/environment-variables.md b/website/docs/getting-started/setup/environment-variables.md index 713fd0817c..79708634bc 100644 --- a/website/docs/getting-started/setup/environment-variables.md +++ b/website/docs/getting-started/setup/environment-variables.md @@ -555,6 +555,16 @@ Controls how many recent backup archives are retained. Backups use a count-based +##### `APPSMITH_BACKUP_ARCHIVE_PASSWORD` + +
+ +Supplies the password that `appsmithctl restore` uses to decrypt an encrypted backup archive, so the restore can run without prompting. Available from Appsmith v2.4.1. Only `appsmithctl restore` reads this variable. It has no effect on `appsmithctl backup`, which takes an encryption password from an interactive prompt and can't encrypt an archive without one. Set it only for the restore invocation, from your CI/CD secret store. Appsmith strips it from the `docker.env` it writes into a backup archive, and it isn't needed outside a restore. When it's set, Appsmith makes a single decryption attempt with it and doesn't fall back to prompting, even in interactive mode. + +For more information, see [Automate restores](/getting-started/setup/instance-management/backup-and-restore/restore-instance#automate-restores). + +
+
diff --git a/website/docs/getting-started/setup/instance-management/appsmithctl.mdx b/website/docs/getting-started/setup/instance-management/appsmithctl.mdx index db32499018..4209f4a626 100644 --- a/website/docs/getting-started/setup/instance-management/appsmithctl.mdx +++ b/website/docs/getting-started/setup/instance-management/appsmithctl.mdx @@ -47,9 +47,9 @@ To create a backup of the Appsmith instance, use the following command: ```bash appsmithctl backup ``` - - The `backup` command creates a backup of your Appsmith instance, including the internal database, `docker.env`, and Git data. The backup file is encrypted using a password that you provided. This password is essential for restoring the backup later, so make sure to store it securely. If the password is forgotten, the backup cannot be restored. + - The `backup` command creates a backup of your Appsmith instance, including the internal database, `docker.env`, and Git data. Run interactively in a terminal, it prompts for a password and encrypts the backup file with it. This password is essential for restoring the backup later, so make sure to store it securely. If the password is forgotten, the backup cannot be restored. - The backup file is stored in the `/appsmith-stacks/data/backup/` directory within the container. On your local machine, it is accessible at `./stacks/data/backup/`. - - The backup file follows the naming pattern `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz.enc`. + - The backup file follows the naming pattern `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz.enc`. Run with `--non-interactive`, or without a terminal attached, the command skips the password prompt and writes an unencrypted `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz` instead. For more information about creating an Appsmith instance backup, see [Backup Instance](/getting-started/setup/instance-management/backup-and-restore/backup-instance) guide. @@ -93,20 +93,7 @@ For [Appsmith paid plans](https://www.appsmith.com/pricing), backups can be uplo - The `restore` command restores the Appsmith instance, including the internal database, `docker.env`, and Git data. For encrypted backups, you need the password used during the backup process to decrypt the archive. - The restore process assumes that the backup file is located at `/appsmith-stacks/data/backup/` within the container. - The backup file should follow the naming pattern `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz.enc` for encrypted archives, or `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz` for unencrypted archives. - -Starting with Appsmith v2.4.1, use the following options to automate restores: - -```bash -appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc -``` - -| Option | Description | -| --- | --- | -| `--backup-file=` | Selects an exact archive filename, including its extension, without the selection prompt. Requires `=` and a filename, not a path or index. Checks local backups and, on eligible instances, configured S3 backups, preferring the local copy. | -| `--non-interactive` | Disables all prompts. Requires `--backup-file=` and the appropriate secrets in the restore process environment. Missing or invalid inputs exit with status `1`. | -| `--force` | Allows a version mismatch only when used with `--non-interactive`. Other validation still applies. | - -For encrypted archives, supply `APPSMITH_BACKUP_ARCHIVE_PASSWORD` as a temporary environment variable for the invocation. For unencrypted archives, supply the source instance's `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`. See [Automate restores](/getting-started/setup/instance-management/backup-and-restore/restore-instance#automate-restores) for Docker and Kubernetes examples, secret handling, and pipeline failure behavior. + - From Appsmith v2.4.1, the `--backup-file`, `--non-interactive`, and `--force` options run a restore without prompts. For more information, see [Automate restores](/getting-started/setup/instance-management/backup-and-restore/restore-instance#automate-restores). For more information about restoring an Appsmith instance, see [Restore Instance](/getting-started/setup/instance-management/backup-and-restore/restore-instance) guide. diff --git a/website/docs/getting-started/setup/instance-management/backup-and-restore/backup-instance.mdx b/website/docs/getting-started/setup/instance-management/backup-and-restore/backup-instance.mdx index 60c1c50f80..908377c3ef 100644 --- a/website/docs/getting-started/setup/instance-management/backup-and-restore/backup-instance.mdx +++ b/website/docs/getting-started/setup/instance-management/backup-and-restore/backup-instance.mdx @@ -81,6 +81,10 @@ You can create a backup archive of your Appsmith instance, including the databas +:::caution Unencrypted archives +`appsmithctl backup` only asks for an encryption password when it runs interactively in a terminal. Run with `--non-interactive`, or from a pipeline or scheduled job where no terminal is attached, and it writes an unencrypted `appsmith-backup-DATE_AND_TIMESTAMP.tar.gz` instead. That archive holds a plaintext database dump, so protect it at rest and don't keep it as a pipeline artifact. Restoring it also requires the source instance's `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`, which an unencrypted archive doesn't carry — save both values when you create one. For more information, see [Restore Instance](/getting-started/setup/instance-management/backup-and-restore/restore-instance#automate-restores). +::: + ## Troubleshooting If you encounter any issues during the restore process, consider the following: diff --git a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx index d63d7a150e..b9670518a7 100644 --- a/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx +++ b/website/docs/getting-started/setup/instance-management/backup-and-restore/restore-instance.mdx @@ -93,40 +93,40 @@ Follow these steps to restore your Appsmith instance for Kubernetes-based instal ## Automate restores -Starting with Appsmith **v2.4.1**, you can run `appsmithctl restore` without prompts for automated disaster recovery or environment rebuilds. +Starting with Appsmith **v2.4.1**, you can run `appsmithctl restore` without prompts for automated disaster recovery or environment rebuilds: ```bash appsmithctl restore --non-interactive --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc ``` -### Select the backup - -Use `--backup-file=` with the exact archive filename, including its extension. The command does not automatically select the latest backup. - -Copy the archive to `/appsmith-stacks/data/backup/` inside the container or pod using the steps above. For instances with [S3 backups configured](/getting-started/setup/instance-management/backup-and-restore/sync-backup-to-s3) and an active paid plan, the command also checks S3. It uses the local archive when the filename exists in both locations; otherwise, it downloads the matching S3 archive before restoring it. - -### Supply the required secrets +| Option | Description | +| --- | --- | +| `--backup-file=` | Selects an exact archive filename, including its extension. The command doesn't pick the latest backup for you. Requires `=` and a filename, not a path or an index. Checks local archives first, then S3 archives on an active paid plan with [S3 sync configured](/getting-started/setup/instance-management/backup-and-restore/sync-backup-to-s3), downloading the S3 copy only when the filename isn't already local. Also works without `--non-interactive` to skip the selection prompt. | +| `--non-interactive` | Disables all prompts. Requires `--backup-file=` and the secrets below in the restore process environment. | +| `--force` | Continues when the backup's Appsmith version differs from the running instance. Applies only with `--non-interactive`, where a mismatch otherwise stops the restore. Interactive restores ask for confirmation instead, with or without this option. It doesn't bypass archive or secret validation, and it doesn't make the two versions compatible. | -The required environment variables depend on the archive format: +The secrets the restore process needs depend on the archive format: | Archive | Required secrets | | --- | --- | -| Encrypted (`.tar.gz.enc`) | Set `APPSMITH_BACKUP_ARCHIVE_PASSWORD` to the password used when creating the archive. Appsmith restores the instance encryption keys from the encrypted backup. | -| Unencrypted (`.tar.gz`) | Set both `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` to the values from the instance that created the backup. The archive password is not required. | +| Encrypted (`.tar.gz.enc`) | `APPSMITH_BACKUP_ARCHIVE_PASSWORD`, set to the password used when creating the archive. Appsmith restores the instance encryption keys from the archive itself. | +| Unencrypted (`.tar.gz`) | `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`, set to the values from the instance that created the backup. The archive password isn't required. | -Supply the archive password as a temporary secret for the restore invocation, using your CI/CD secret store. Do not save it in `docker.env`, Helm values, or source control. If `APPSMITH_BACKUP_ARCHIVE_PASSWORD` is set, Appsmith uses it for one decryption attempt, even in interactive mode. +The archive password is a transient secret. Supply it from your CI/CD secret store for a single restore invocation, and never keep it in `docker.env`, Helm values, or source control. The encryption password and salt are durable instance secrets: keep them out of CI configuration and source control, but expect the restore to write them into the instance's `docker.env`, where they belong. -For an unencrypted backup from the same instance, you can use its existing encryption password and salt. When restoring another instance's backup, supply that source instance's values before running the command. The command checks that both values are present; you must ensure they match the source instance. +Appsmith checks only that the encryption password and salt are present, not that they're correct. Values that don't match the source instance let the restore finish while leaving every stored datasource credential undecryptable. -### Run the restore +When `APPSMITH_BACKUP_ARCHIVE_PASSWORD` is set, Appsmith uses it for a single decryption attempt and doesn't fall back to the prompt, even in interactive mode. -The following examples restore an encrypted archive. Replace `TIMESTAMP`, the container or pod name, and the namespace with your values. +`appsmithctl backup` writes an unencrypted archive when it runs with `--non-interactive` or without a terminal, which is the usual case in a pipeline. An unencrypted archive holds a plaintext database dump, so protect it at rest and don't keep it as a pipeline artifact. For more information, see [Backup Instance](/getting-started/setup/instance-management/backup-and-restore/backup-instance). - +The following examples restore an encrypted archive that you copied to `/appsmith-stacks/data/backup/` using the steps above. Replace `TIMESTAMP` and the container or pod name with your values. For an unencrypted archive, use the `.tar.gz` filename and deliver `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` the same way instead of the archive password. - + -Configure your pipeline to inject `APPSMITH_BACKUP_ARCHIVE_PASSWORD` into the runner's environment, then pass it to the restore process: + + +Inject `APPSMITH_BACKUP_ARCHIVE_PASSWORD` into the runner's environment, then pass the variable name, not its value, through to the container: ```bash docker exec \ @@ -136,49 +136,59 @@ docker exec \ --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc ``` -Do not allocate a TTY (`-t`) for pipeline execution. To use Docker Compose, replace `docker exec` with `docker-compose exec -T` in this example. - -For an unencrypted archive, use the `.tar.gz` filename and omit `-e APPSMITH_BACKUP_ARCHIVE_PASSWORD`. If supplying the source instance's encryption keys from the runner, pass them with `-e APPSMITH_ENCRYPTION_PASSWORD -e APPSMITH_ENCRYPTION_SALT`. +Writing `-e VARIABLE` without a value sends the password in the request body instead of on a command line, so it stays out of process lists and shell history. Don't allocate a TTY (`-t`) in a pipeline. On Compose v2, replace `docker exec` with `docker compose exec -T`. - + -Make `APPSMITH_BACKUP_ARCHIVE_PASSWORD` available to the restore process in the target pod through your Kubernetes secret management workflow. Setting it only on the machine running `kubectl` does not pass it into the pod. Limit its availability to the recovery operation and remove the temporary secret configuration afterward. +Deliver the password to the pod through a Kubernetes Secret. Setting it only on the machine that runs `kubectl` has no effect, and passing it on the `kubectl exec` command line writes it in plaintext to the kube-apiserver audit log, because exec arguments travel as query parameters in the request URI. -```bash -kubectl exec -n APPSMITH_NAMESPACE ANY_APPSMITH_POD_NAME -- \ - appsmithctl restore \ - --non-interactive \ - --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc -``` +1. Create a Secret holding `APPSMITH_BACKUP_ARCHIVE_PASSWORD` through your cluster's secret management. With plain `kubectl`, read the password from a file rather than from the command line, which would leave it in the runner's process list and shell history: -For an unencrypted archive, use the `.tar.gz` filename and ensure the restore process has the source instance's `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT`. + ```bash + kubectl create secret generic appsmith-restore \ + --from-file=APPSMITH_BACKUP_ARCHIVE_PASSWORD=./archive-password + ``` -After a successful restore, if autoscaling is turned on, restart the Appsmith deployment: + Create `./archive-password` with mode `0600`, and delete it once the Secret exists. -```bash -kubectl rollout restart deployment appsmith -n APPSMITH_NAMESPACE -``` +2. Reference the Secret from the Appsmith deployment: -With autoscaling turned off, or on Community Edition, the restore command restarts the Appsmith server. + ```yaml + envFrom: + - secretRef: + name: appsmith-restore + ``` - +3. Apply the change and wait for the rollout to finish. The replacement pod doesn't carry the backup archive, so copy it now. Replace `ANY_APPSMITH_POD_NAME` with the new pod name: - + ```bash + kubectl cp appsmith-backup-TIMESTAMP.tar.gz.enc ANY_APPSMITH_POD_NAME:/appsmith-stacks/data/backup/ + ``` -### Handle failures in a pipeline +4. Run the restore: -Make your pipeline stop when the restore command returns a nonzero exit status. Missing or unknown backup filenames, paths supplied as filenames, missing secrets, failed decryption, and version mismatches return exit code `1` without prompting. These checks occur before the restore stops services or changes the database. A failure during the restore itself can leave the instance partially restored. + ```bash + kubectl exec ANY_APPSMITH_POD_NAME -- \ + appsmithctl restore \ + --non-interactive \ + --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc + ``` -By default, non-interactive restore stops if the backup's Appsmith version differs from the running instance. Use a matching version when possible. To deliberately proceed despite a version mismatch, add `--force`: +5. Remove the `envFrom` entry and apply again. The resulting rollout both withdraws the password and restarts the pods. Then delete the Secret, which removing the reference leaves in place: -```bash -appsmithctl restore --non-interactive \ - --backup-file=appsmith-backup-TIMESTAMP.tar.gz.enc --force -``` + ```bash + kubectl delete secret appsmith-restore + ``` + +This procedure narrows the password's exposure rather than removing it. Between the rollout in step 2 and the one in step 5, `envFrom` puts the password in the environment of every process in the pod, including the running Appsmith server, and the Secret itself is readable by anyone holding `get secrets` in the namespace and stored base64-encoded in etcd unless the cluster encrypts secrets at rest. Because an encrypted archive carries the instance encryption keys, this password ultimately protects every stored datasource credential, so rotate it after the restore. + + + + -`--force` only bypasses the version check in non-interactive mode. It does not bypass archive or secret validation, and it does not guarantee compatibility between versions. Without `--non-interactive`, the version confirmation prompt still appears. +Make your pipeline stop when `appsmithctl restore` returns a nonzero exit status. In non-interactive mode, unknown filenames, paths supplied as filenames, missing secrets, failed decryption, and version mismatches all exit with status `1` before the command stops services or changes the database. A failure during the restore itself can leave the instance partially restored. ## Troubleshooting @@ -188,7 +198,7 @@ If you encounter any issues during the restore process, consider the following: - Ensure the S3 bucket has appropriate permissions to list the backup archives from the bucket. - Verify that you are on an [Appsmith paid plan](https://www.appsmith.com/pricing) and your plan is active to list backup archives from S3 bucket. For more information, see [License & plans](/getting-started/setup/instance-configuration/admin-settings#license--plans). - Verify that you have the required permissions to execute `docker-compose` or `kubectl` commands. -- If using encrypted backups, confirm that the encryption password and salt match the original values used during backup creation. +- If restoring an unencrypted archive, confirm that `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` match the values from the instance that created the backup. An encrypted archive carries these values, so it needs only the archive password. - If restarting the pods fails, check the logs for errors. For more information, see [Get Container logs](/getting-started/setup/instance-management/how-to-get-container-logs) guide. If you continue to face issues, contact support using the chat widget available in the bottom-right corner of this page.