Skip to content
SHC Docs

shc export / import

The shc export and shc import commands provide app-defined, selective data extraction. Unlike backups which capture all DATA mounts, exports let apps define custom extraction logic for specific data items.

Exports are different from backups:

FeatureBackupExport
DefinitionBuilt into SHCApp-defined (*.exporters.yaml)
GranularityAll DATA mountsParameterized (one DB, one realm)
ExecutionConverters (post-snapshot)Jobs (live access)
IsolationNetwork-isolatedFull stack access
Use caseDisaster recoveryData migration, selective extract
  • Export one Keycloak realm (not all realms)
  • Export one PostgreSQL database (not all databases)
  • Export with custom format (JSON, CSV, custom dump)
  • Migrate specific data between environments

Export data using an app-defined exporter:

Terminal window
# Export a specific database
shc export postgres --export-stack mydb -p database=customers
# Export with custom format
shc export postgres --export-stack mydb -p database=orders -p format=plain
# Export to specific directory
shc export postgres --export-stack mydb -p database=mydb -d /tmp/mydb-export
# Export Keycloak realm
shc export realm --export-stack keycloak -p realm=my-realm

Import data using an app-defined importer:

Terminal window
# Import to a database
shc import postgres --stack mydb -p target_database=customers_copy
# Import with overwrite
shc import postgres --stack mydb -p target_database=staging -p overwrite=true
# Import from specific directory
shc import postgres --stack mydb -i /tmp/mydb-export
# Import Keycloak realm
shc import realm --stack keycloak -i /tmp/realm-export

Apps define exporters in *.exporters.yaml files:

postgres.exporters.yaml
schema:
export:
database:
type: string
required: true
format:
type: string
default: "custom"
import:
target_database:
type: string
required: true
overwrite:
type: bool
default: false
exporter_jobs:
- name: dump-postgres
context: container
image: postgres:15-alpine
command: |
pg_dump -h {{ stack.host }} \
-U {{ stack.username }} \
-F {{ params.export.format }} \
{{ params.export.database }} \
> /output/{{ params.export.database }}.dump
volumes:
- output:/output
environment:
PGPASSWORD: !ref+vault://postgres_password
importer_jobs:
- name: restore-postgres
context: container
image: postgres:15-alpine
command: |
pg_restore -h {{ stack.host }} \
-U {{ stack.username }} \
-d {{ params.import.target_database }} \
/input/*.dump
volumes:
- input:/input
environment:
PGPASSWORD: !ref+vault://postgres_password

Exports create .exp files using AR archive format:

export-{id}.exp (AR archive)
├── manifest.json # Export manifest
└── data.tar.gz # Exported data (compressed)
{
"id": "exp-abc123",
"timestamp": "2025-01-15T12:00:00Z",
"version": "1",
"tenant": "acme",
"stack": "myapp",
"environment": "production",
"exporter": "postgres",
"params": {
"database": "mydb",
"format": "custom"
},
"archives": {
"data": { "size": 12345 }
},
"size": 12345
}
Terminal window
# Export a single database
$ shc export postgres --export-stack mydb -p database=customers
Exporting customers from mydb
v Running dump-postgres job
v Creating export artifact
Export complete: /var/lib/shc/exports/exp-20250115-abc123.exp (45 MB)
Terminal window
# Import to a new database name
$ shc import postgres --stack mydb -p target_database=customers_archive -i /tmp/customers-export
Importing to customers_archive
v Running restore-postgres job
Import complete
Terminal window
# Export specific realm configuration
$ shc export realm --export-stack keycloak -p realm=my-company
Exporting realm my-company from keycloak
v Running export-realm job
Export complete: /var/lib/shc/exports/exp-20250115-def456.exp (2.3 MB)

Read the manifest without extracting:

Terminal window
# Inspect export artifact
ar p export.exp manifest.json | jq .
# Output:
{
"id": "exp-abc123",
"exporter": "postgres",
"params": {
"database": "customers"
},
...
}

Export/import parameters are defined in the exporter’s schema:

Terminal window
# Single parameter
shc export postgres --export-stack mydb -p database=mydb
# Multiple parameters
shc export postgres --export-stack mydb -p database=mydb -p format=plain
# Using --param
shc export postgres --export-stack mydb --param database=mydb --param format=custom
TypeExample
string-p database=mydb
bool-p overwrite=true
int-p limit=1000
FlagDefaultDescription
<exporter>Exporter name (from app)
--export-stackcontextSource stack to export from
-p, --paramParameter (can repeat)
--output-dirautoOutput directory path
-edefaultEnvironment
FlagDefaultDescription
<exporter>Exporter name (from app)
--stackTarget stack (required)
-i, --inputInput directory or .exp file path
-p, --paramParameter (can repeat)
-edefaultEnvironment

List exporters available for a stack:

Terminal window
# Show exporters defined by an app
shc export --export-stack postgres --list
# Output:
Available exporters for postgres:
postgres - Export PostgreSQL database (params: database, format)

Apps can define exporters in {app}.exporters.yaml:

myapp.exporters.yaml
schema:
export:
item_id:
type: string
required: true
import:
target_id:
type: string
required: true
exporter_jobs:
- name: export-item
context: container
image: myapp-tools:latest
command: myapp-cli export {{ params.export.item_id }} -o /output/
volumes:
- output:/output
importer_jobs:
- name: import-item
context: container
image: myapp-tools:latest
command: myapp-cli import {{ params.import.target_id }} -i /input/
volumes:
- input:/input