atscalectl restore
The restore command restores the AtScale PostgreSQL databases from a backup directory created by atscalectl backup.
The restore command is destructive. It drops and recreates the target databases. All existing data in those databases will be removed. The command asks for confirmation before starting, unless the --yes flag is specified.
Prerequisites
restore requires the following Kubernetes permissions:
podsget/listpods/execcreatesecretsget/listconfigmapslistsecretslist. Required only when the--release-nameflag isn't specified. This is required to detect the Helm release.- (External PostgreSQL only)
podscreate/delete. Required to create and delete the temporary utility pod used to restore the external database. - (External PostgreSQL only)
pod/exec. Required in the PostgreSQL namespace if the--pg-namespaceflag is specified.
The CLI does not require local PostgreSQL tools. Database utilities such as pg_dump and pg_restore are executed inside the Kubernetes environment.
Usage
atscalectl restore --backup-dir <path> [flags]
Flags
restore can be used with all global flags, as well as the following command-specific flags.
| Flag | Default | Description |
|---|---|---|
--backup-dir | Required. The path to the backup directory created by atscalectl backup. | |
--databases | atscale,keycloak,pgwire | The databases to restore. |
--grant-ownership | false | Grants database privileges and restores expected ownership after restoring. |
-y, --yes | false | Skips the confirmation prompt. |
External PostgreSQL flags
If you are restoring an external PostgreSQL database, you can use the following additional flags to configure the temporary utility pod that performs the restoration. For more information, see External PostgreSQL restoration below.
| Flag | Description |
|---|---|
--pg-host | The external PostgreSQL host. |
--pg-port | The external PostgreSQL port. Defaults to 5432. |
--pg-connection-string | The full PostgreSQL connection URI. Mutually exclusive with --pg-host. |
--pg-secret-name | The Kubernetes secret that contains PostgreSQL credentials. |
--pg-user-key | The username key inside the --pg-secret-name secret. Defaults to POSTGRES_USER. |
--pg-password-key | The password key inside the secret. Defaults to POSTGRES_PASSWORD. |
--pg-image | The image for the utility pod. Defaults to postgres:16. |
--pg-pod | Targets a specific database pod and skips discovery. |
--pg-namespace | The namespace of the PostgreSQL pod, if different from AtScale's. |
--pg-pod-timeout | Determines how long the utility pod stays alive. Defaults to 1h. |
Pod hardening flags are also supported.
The temporary utility pod runs as a non-root user by default (UID/GID 999). Use the --pg-run-as-user and --pg-run-as-group flags to override the default identity when your PostgreSQL utility image requires a different non-root user or group.
| Flag | Description |
|---|---|
--pg-service-account | The ServiceAccount for the utility pod. |
--pg-image-pull-secret | The image pull secret name. |
--pg-node-selector | The node selector as key=value. |
--pg-pod-label | Additional pod labels. |
--pg-pod-annotation | Additional pod annotations. |
--pg-run-as-user | Overrides the default utility pod UID (999). |
--pg-run-as-group | Overrides the default utility pod UID (999). |
--pg-fs-group | fsGroup GID. |
Before restoring
Before running restore, you should do the following:
- Create a fresh backup of the current environment, if possible.
- Scale down the AtScale services to prevent applications from writing to databases during the restore.
- Verify the target Kubernetes cluster and namespace.
You should always specify --context when working with multiple Kubernetes clusters.
For example:
atscalectl restore \
--context <context> \
--backup-dir <dir>
Running destructive operations such as restore against the wrong cluster may cause data loss. A restore operation against the wrong cluster cannot be undone.
Database targeting
When restoring internal PostgreSQL instances, restore always targets the primary PostgreSQL database pod, as it performs write operations. This is different from the backup command, which prefers a Ready replica (when available) to reduce load on the primary database.
By default, restore targets the database pod with index 0. If your PostgreSQL topology requires a different target, specify:
--pg-pod <pod-name>
External PostgreSQL restoration
As with backup operations, atscalectl uses a short-lived utility pod inside the Kubernetes cluster to restore external PostgreSQL databases. You can adjust this pod using the PostgreSQL-specific flags described above.
By default, the utility pod runs as UID/GID 999 to satisfy Kubernetes non-root security requirements. If your custom PostgreSQL utility image requires a different non-root UID or GID, you can override the defaults as follows:
atscalectl restore \
--backup-dir <dir> \
--pg-host <host> \
--pg-run-as-user <UID> \
--pg-run-as-group <UID>
Ownership handling
By default, restore loads database contents from the backup. Database ownership is handled as follows.
| Database | Owner |
|---|---|
atscale | atscale |
keycloak | keycloak |
pgwire | atscale_metadata |
You can use the --grant-ownership flag when restoring into an environment where roles exist but ownership and privileges need to be recreated; for example, if you are restoring into a newly provisioned environment or moving backups between clusters, or if database ownership differs from the original environment.
To use --grant-ownership:
atscalectl restore \
--backup-dir <dir> \
--grant-ownership
Restore verification
Restore operations are verified before reporting success. The command will fail if any of the following occur:
- Global objects restore fails.
- The database stream is interrupted before completion.
- The remote PostgreSQL command does not confirm successful completion.
A partially completed restore operation must never be reported as successful because it can leave the environment inconsistent. Always verify the restore output before considering recovery complete.
After restoring
After the restore operation completes, you should do the following:
-
Scale the AtScale services back up.
-
Check deployment health with the
statuscommand:atscalectl status -
Confirm all pods become ready.
-
Verify authentication.
If the Keycloak database was restored, the Keycloak database and Kubernetes secrets must come from the same backup point in time.
Restore usage examples
Interactive restore
The following command asks for confirmation before dropping databases.
atscalectl restore \
--backup-dir <dir>
Non-interactive restore
For automation or disaster recovery procedures, you can include the --yes flag to skip the confirmation prompt.
atscalectl restore \
--backup-dir <dir> \
--yes
Restore selected databases only
atscalectl restore \
--backup-dir <dir> \
--databases atscale,keycloak
Restore to an external PostgreSQL instance
atscalectl restore \
--backup-dir <dir> \
--pg-host <host> \
--pg-secret-name <secret>
Troubleshooting restore operations
Backup directory not found
The path must point to the timestamped backup directory itself. For example:
./atscale-backup-20260727-143000
Restore fails partway through
The target databases may be left in a partial state. Fix the underlying issue and run restore again.
The restore process recreates the databases, so repeating the operation from the same backup is supported.
Authentication fails after restore
The Keycloak database and Keycloak-related Kubernetes secrets must match the same backup snapshot. Authentication may fail after restoring in the following cases:
- You restored an older Keycloak database with newer secrets.
- You restored newer secrets with an older Keycloak database.
To avoid authentication issues, restore both from the same backup.
Kubernetes access denied
If you are restoring to an external PostgreSQL instance, verify your permissions:
kubectl auth can-i create pods -n <namespace>
kubectl auth can-i delete pods -n <namespace>
kubectl auth can-i create pods/exec -n <namespace>