Data initialization
When shipping Casdoor as part of a larger product, preload organizations, applications, users, and other data so users get a working setup without manual configuration. Data initialization uses a JSON or YAML file that you provide or generate.
The same file can also be the source of truth for the configuration: Casdoor can watch it and apply every change without a restart, see Configuration as code.
This page describes how to import and export configuration data.
Import
By default, Casdoor looks for init_data.json in the project root at startup and loads it if present. To use a different path, set initDataFile in conf/app.conf:
initDataFile = /path/to/your/init_data.json
A template is available at init_data.json.template. Copy and rename it to init_data.json and customize as needed. A file ending in .yaml or .yml is read as YAML, with the same structure.
By default, every object of the file that already exists is deleted and re-created from the file at each startup, so changes made in the web UI to those objects are lost on restart. Two settings change that:
initDataNewOnly = true: only objects that don't exist yet are added, existing ones are left untouched.initDataMerge = true: existing objects are updated with only the fields written in the file, see Configuration as code.
Docker
Mount the file into the container with a volume:
docker run ... -v /path/to/init_data.json:/init_data.json
Kubernetes
With the Helm chart, put the objects under initData.data in your values file and set initData.enabled: true, see Configuration as code.
Without the chart, store the file in a Secret (it usually holds passwords and client secrets) or a ConfigMap and mount it into the Casdoor pod:
apiVersion: v1
kind: Secret
metadata:
name: casdoor-init-data
stringData:
init_data.yaml: |
organizations:
- owner: admin
name: acme
displayName: Acme
Mount it as a directory and point initDataFile to the file in it:
apiVersion: apps/v1
kind: Deployment
...
spec:
template:
...
spec:
containers:
...
env:
- name: initDataFile
value: /init-data/init_data.yaml
- name: initDataMerge
value: "true"
- name: initDataWatchInterval
value: "30"
volumeMounts:
- mountPath: /init-data
name: casdoor-init-data-volume
readOnly: true
volumes:
- secret:
secretName: casdoor-init-data
name: casdoor-init-data-volume
Don't mount the file with subPath: Kubernetes doesn't update a subPath mount when the Secret or ConfigMap changes, so Casdoor would never see the new content.
Configuration as code
To keep organizations, applications, users, providers, roles and permissions in Git and roll changes out like any other configuration, similar to authentik blueprints, let Casdoor apply the file continuously:
initDataFile = ./init_data.yaml
initDataMerge = true
initDataWatchInterval = 30
The settings can also be passed as environment variables of the same names.
- Merge: an object that already exists is updated with only the fields written in the file. Its other fields keep their current values, so the file can manage a few settings of an object (e.g. the redirect URIs of an application) while the rest is edited in the web UI.
- Watch: Casdoor checks the file every
initDataWatchIntervalseconds and applies it again when its content changed, without a restart. - A user's
passwordis only used when the user is created, so users can change their own passwords afterwards. Organization secrets such asmasterPasswordare written on every apply when they are in the file. - Objects removed from the file are not deleted from Casdoor.
recordsandsessionsare skipped in merge mode, they are runtime data.- If an object fails to apply, the error is logged once and Casdoor keeps running with the objects applied up to that point; the file is retried on every check until it applies.
Example init_data.yaml:
organizations:
- owner: admin
name: acme
displayName: Acme
passwordType: bcrypt
applications:
- owner: admin
name: app-acme
organization: acme
displayName: Acme Portal
redirectUris:
- https://portal.acme.example.com/callback
users:
- owner: acme
name: alice
displayName: Alice
password: change-me
signupApplication: app-acme
roles:
- owner: acme
name: admins
displayName: Admins
users: [acme/alice]
isEnabled: true
With the Helm chart, the same objects go under initData.data; the chart stores them in a Secret and enables merge and watch by default:
initData:
enabled: true
data:
organizations:
- owner: admin
name: acme
displayName: Acme
A helm upgrade that changes initData.data is applied by the running pods within initData.watchInterval seconds plus the time kubelet takes to update the mounted Secret (about a minute).
If you prefer terraform plan, import of existing objects and drift detection, the Terraform provider manages the same objects through the API.
Export
Export all Casdoor config data to a JSON file for backup or migration.
Using the binary (recommended)
Run Casdoor with the -export flag to dump the database to JSON:
# Export to default location (init_data_dump.json)
./casdoor -export
# Export to a custom path
./casdoor -export -exportPath /path/to/backup.json
Export runs after DB init and then the process exits. It works with binary, Docker, or Kubernetes and does not require the Go toolchain.
Using Go test (from source)
From the Casdoor source tree:
go test ./object -v -run TestDumpToFile
This creates init_data_dump.json in that directory.
Migrating to another instance
Rename init_data_dump.json to init_data.json, put it in the root of the target Casdoor instance, and start Casdoor; the data will be loaded automatically.
Supported objects
The following object types can be included in the init file:
| Object | Go Struct | Documentation |
|---|---|---|
| organizations | struct | doc |
| applications | struct | doc |
| users | struct | doc |
| certs | struct | doc |
| providers | struct | doc |
| ldaps | struct | doc |
| models | struct | |
| permissions | struct | doc |
| payments | struct | doc |
| products | struct | doc |
| resources | struct | doc |
| roles | struct | doc |
| syncers | struct | doc |
| tokens | struct | doc |
| webhooks | struct | doc |
| groups | struct | doc |
| adapters | struct | doc |
| enforcers | struct | |
| plans | struct | doc |
| pricings | struct | doc |
| invitations | struct | doc |
| records | struct | |
| sessions | struct | |
| subscriptions | struct | doc |
| transactions | struct |
For the exact JSON shape, call the REST API or inspect GetXXX responses in the browser; they match the structure expected in init_data.json.