Dify backup and restore

A self-hosted Dify holds apps, workflows, knowledge bases and secrets across several stores, so a backup is only useful if it captures all of them consistently and a restore has been rehearsed. This page explains what to protect, how to take consistent copies and how to prove a restore works.

On this page

Dify backup and restore: what a self-hosted team must protect

When you self-host Dify, backup and restore is your job, not the platform's. Dify is an LLM application development platform for building AI workflows, RAG pipelines and agents, and its state lives in several places at once: the metadata database (PostgreSQL by default, or MySQL or OceanBase), file storage (local volumes or an S3-compatible or cloud object store), the vector store (Weaviate by default, or Qdrant, Milvus, pgvector, OpenSearch or Elasticsearch) and the configuration in your .env file. A restore that brings back only one of these leaves apps pointing at documents, embeddings or keys that no longer match.

Schedule this work before the first production use, before every upgrade and before any infrastructure move. The Docker Compose upgrade guidance recommends a backup before every upgrade and advises checking .env.example for new variables afterward, so your runbook should treat those two steps as one change. Pay particular attention to SECRET_KEY: the environment reference says it signs session cookies and JWTs and encrypts OAuth credentials, and changing it after deployment logs out all users. Store a copy of the exact value in your secrets vault alongside the backup, because a restored database paired with a different key will not behave as it did before.

Consistency matters as much as completeness. Take the database dump and the file and vector snapshots close enough together that apps, workflow runs and knowledge base documents agree with one another, and record the Dify version and image tags with each set. Keep at least one copy outside the host or cluster that runs Dify, and confirm that your encryption and retention rules cover the knowledge base content, which may include regulated data. Then perform a restore into a separate environment and check that a sample app answers and a knowledge base retrieves results. Confirm with your own infrastructure team which vector store and object storage options you have chosen, since the backup commands differ for each.

Which Dify data stores belong in the backup scope

A self-hosted Dify keeps its durable state across several stores, and each one fails differently when it is lost. The cards below separate the stores you must restore from the transient state you can rebuild, and they name the settings that decide which provider your deployment actually uses.

Metadata database

PostgreSQL is the default metadata database, with MySQL and OceanBase as other supported options. It holds the records that tie apps, workflows, accounts, workspaces and knowledge base configuration together, so it is the first store to back up and the one restores depend on most. Confirm which engine your version and environment variables select, and take a consistent dump or snapshot of that engine rather than copying its data directory while it is running.

File storage

Uploaded documents and generated files live in the file storage layer, which can be local volumes or a provider such as OpenDAL, S3-compatible storage, Azure Blob or Google Cloud Storage. Metadata in the database points to these objects, so a database restored without its matching files leaves knowledge base documents that cannot be read. Check the storage provider in your configuration and back up its volume or bucket on the same schedule as the database.

Vector store

Weaviate is the default vector store, and Qdrant, Milvus, pgvector, OpenSearch and Elasticsearch are listed as alternatives. Embeddings are derived from source documents, but rebuilding them means re-embedding content, which can take time and call model providers again. Confirm which store your version uses, then decide whether to back it up directly or document a re-indexing procedure with its cost and duration measured in a test restore.

The .env file

The .env file holds settings such as the SECRET_KEY, which signs session cookies and JWTs and encrypts OAuth credentials. Restoring data without the original key can leave stored credentials unusable, and changing the key after deployment logs out every user. Store a secured copy of .env alongside the other backups, and record the version it came from, because upgrades require checking .env.example for new variables.

Redis as transient state

Redis handles caching and task brokering between the api and worker services. Its contents are generally transient, so it is usually not a backup target, but queued tasks in flight at the moment of failure may need to be resubmitted or re-triggered. Confirm with the version you run whether any Redis data is persisted for your workloads before you exclude it from the scope.

Excluding rebuildable state deliberately

Restore scope is easier to test when each excluded item has a stated reason, such as a rebuildable cache or a re-indexable vector collection. Write those decisions into the runbook, along with the owner who approved them. Revisit the list at each upgrade, since the stores a release depends on can change.

Why the env file and SECRET_KEY are part of the backup

A database backup on its own does not capture everything a self-hosted Dify needs to run. The `SECRET_KEY` value in your environment file signs session cookies and JWTs and is used to encrypt OAuth credentials stored in the platform. If the database is restored onto a host with a different or missing key, stored credentials may not be usable afterward. The Dify environment variable reference is the place to confirm exactly which stored values depend on the key before you write your runbook. Treat the env file as part of the backup set, captured at the same time as the database and storage snapshots so the three stay matched to one deployment.

Changing SECRET_KEY after deployment logs out all users, so it is not a routine rotation step you can take casually during recovery. Workspace encryption keys add a second dependency. The docs say they can be stored locally or in Azure Key Vault, so your runbook needs to state which option you use and where that material lives. If it is local, it must be backed up with the env file. If it is in Azure Key Vault, confirm that the vault, its access policies and its own recovery settings are part of your restore plan rather than assumed. Ask the vendor or your own platform team to confirm any further dependencies in your version.

The env file and key material are secrets, so their backups need the same care as database credentials. Store them encrypted, in a location with restricted read access, and limit who can restore them to a named group of operators. Keep an access log for those copies and review it periodically. Separate the secrets backup from the general data backup where practical, so a broad storage permission does not expose keys. Record where each copy lives in your runbook, and test that a restore on a clean host can read those values before you depend on them.

How to take a consistent snapshot across database and storage

This sequence pauses writes, captures the metadata database, file storage, vector data and configuration from the same window, and then resumes services, so the copies can be restored together. Each step ends with a check you can record before the next one starts.

  1. Confirm the version and storage layout

    Before touching anything, the operator records the Dify version, the deployment type (Docker Compose or source), the metadata database (PostgreSQL, MySQL or OceanBase), the file storage provider and the vector store in use. Those four choices change which commands and paths apply. Check the backup steps against the docs for your exact version, since storage and vector choices change the commands. The output is a short written inventory that the restore runbook will reference.

  2. Announce the window and drain writes

    Tell users that the platform will be unavailable for writes during the backup window. Stop or scale down the api and worker containers so no new messages, workflow runs, dataset uploads or indexing jobs change the data during the copy. Leave the database and storage services running. The check is that the worker and API containers show as stopped and that no new rows appear in the message or run tables over a short interval.

  3. Dump the metadata database consistently

    With writes stopped, run the dump tool that matches your database engine, for PostgreSQL normally pg_dump in custom format, so the file captures one point-in-time view of the schema and data. Store the output in a dated location outside the container. Confirm the procedure for your version, because the command and connection details depend on your deployment. The check is that the dump file is non-empty and that the tool exits without errors. Restore testing comes later, but record the file size and checksum now.

  4. Copy file storage from the same window

    Copy uploaded documents and generated files from the storage location in use, such as the local volume for the default setup or the bucket for S3-compatible or cloud storage, while writes are still paused. Use a copy method that preserves names and does not skip hidden or nested paths. The check is that the object or file count and total size at the source match the destination, and that a sample of files opens correctly. If the store is an object bucket, record the bucket name and versioning state.

  5. Capture vector data and its configuration

    Back up the vector store that holds your knowledge base indexes, using the native snapshot or export method for the store you chose, such as Weaviate, Qdrant, Milvus, pgvector, OpenSearch or Elasticsearch. Keep the vector copy in the same window as the database and file copies, because the metadata rows point to indexes that must exist. Confirm the method in the docs for your version and store. The check is that the snapshot reports complete and that the collection or index names listed in the snapshot match those in the metadata database.

  6. Capture environment files and deployment configuration

    Copy the .env file, the compose file or overrides, any reverse proxy and TLS configuration, and for source deployments the configuration files that set database, storage and vector connections. Store the copy with restricted access, because it contains SECRET_KEY and other credentials, and losing SECRET_KEY means the restored system cannot read existing encrypted OAuth credentials. The check is that the copied files parse and that the stored SECRET_KEY value matches the one in the running system.

  7. Resume services and verify the snapshot

    Start the api and worker containers again and confirm they connect to the database, storage and vector store without errors. Then verify the snapshot itself: restore the database dump into a scratch instance, compare row counts for key tables against the source, and check that the object counts in the copied storage match. Log the results with the backup identifier. The check is that the platform answers normally and that the scratch restore reports matching counts, which confirms the set is usable before you rely on it.

Backup approach for Compose versus source deployments

A Docker Compose deployment keeps most of its state in named volumes attached to the PostgreSQL, Redis, Weaviate and storage containers, while the configuration lives in the .env file and the compose file on the host. The containers themselves are disposable, so a backup should capture the data and the configuration that produced them, not the images.

  • Named volumes: Back up the volumes that hold PostgreSQL data, Redis persistence files, Weaviate data and any local file storage used by Dify. Confirm the volume names with docker volume ls on your host before you write the job.
  • The `.env` file: Store a copy of the .env file, because it holds SECRET_KEY and the storage, database and vector store settings. Losing SECRET_KEY logs users out and can break access to encrypted data, so treat this copy as sensitive.
  • The compose file and overrides: Keep the compose file and any local override files under version control, along with the exact image tags in use.
  • Consistent database capture: Dump PostgreSQL with a logical tool while the database is running, or stop the stack before copying raw volume files, so the database and file storage describe the same point in time.
  • Restore order: Restore the configuration first, then the database and storage, and only then start the containers.

Before you rely on this approach, confirm with the Dify Compose documentation which volume names and environment keys apply to your release.

Backup options and when each fits

This table compares the backup methods that cover the parts of a self-hosted Dify deployment, from database dumps to vector store and filesystem copies. Read each row for what it protects, how consistent it is with the rest of the stack, and what your team must run and test. The main takeaway is that no single method covers Dify, so most teams combine a consistent database copy with storage and vector data captured at the same point in time.

Backup methodConsistency and restore speedWhat it missesWhat your team must provide
Logical database dump (PostgreSQL)Consistent within the dump's own snapshot. Restore replays SQL and is usually slower on large databases.Uploaded files, vector index contents and the env file. Dumps of a running database need a quiet window or a single transaction snapshot to stay coherent.Scheduled dump jobs, a restore rehearsal into a scratch database and retention rules. Confirm the dump tool and options against your PostgreSQL version.
Physical or provider snapshot of the database volumeFast to take and restore when the platform supports it. Consistency depends on quiescing writes or using crash-consistent snapshot features.Anything outside the volume, including object storage and vector data. Restores can carry the same faults as the source.Access to the storage platform, snapshot schedules and a restore test. Confirm snapshot consistency guarantees with your cloud or storage vendor.
Object storage versioning or cross-region replicationContinuous or near continuous copies of uploaded documents. Restoring individual files is quick, but full restores depend on object count.Database rows that point to those objects. A replica can hold objects that the restored database no longer references, or the reverse.Versioning or replication enabled on the bucket, lifecycle rules and a policy for deleted objects. Confirm the behavior with your provider.
Vector store snapshot (Weaviate or another configured store)Captures index state at a point in time. Rebuilding embeddings from source files is often slower and costlier than restoring the index.Consistency with the metadata database. An index restored from a different moment can disagree with document records and needs a reconciliation check.Knowing which vector store your deployment uses, its snapshot method and version compatibility. Confirm supported snapshot and restore steps with the vector store documentation.
Filesystem copy of the Compose volumes or bind mountsSimple to run. Copies taken while services write may be inconsistent unless containers are stopped or the copy is a point-in-time snapshot.Data held in external services such as managed PostgreSQL or external object storage. Copies can also capture secrets in plain form, so they need access control.Stop or quiesce services for consistent copies, or use a snapshot-capable volume. Restrict who can read the copy because it includes the env file contents.
Env file and secret backup (SECRET_KEY, encryption settings)Not a data copy, but restore fails without it. Changing SECRET_KEY after deployment logs out all users, so restoring with a different key changes sign-in behavior.Application data itself. Encrypted fields in the database may be unreadable if the key that protects them is lost.A secured, versioned store for the env file and key material, separate from the data backups. Record which values must match the original deployment.
Dify app DSL exportPortable copy of app configuration, workflow nodes, prompts and knowledge base connections. Not a full restore path.Third-party API keys, knowledge base content, usage logs and file contents. Re-entering credentials is a manual step after import.Routine exports of key apps, stored with change records. Treat this as a supplement to full backups, not a replacement.

Keeping offsite copies separate from the running Dify

An offsite copy only protects you if it survives the event that takes down the running Dify. Keep the copy outside the host, outside the cloud account and, where your risk model requires it, outside the administrative domain that runs Dify. A compromised account with rights to both the production database and its backup bucket can destroy both at once. Encrypt every copy before it leaves the host, using keys held separately from the backup storage, and test that a restore works into a separate environment that shares no credentials, network routes or secret stores with production. Confirm with your platform team how the backup tool handles key rotation and where the decryption keys are recorded.

Treat backup storage as production data. A dump of the metadata database contains prompts, workflow definitions, conversation records, knowledge base text and the values that SECRET_KEY protects, so the storage needs the same access controls as the live system: named roles, multi-factor authentication for administrators, object locking or versioning to resist deletion, and audit logs for reads and deletes. Limit restore rights to a small group, and record who can download a copy. Ask your provider to confirm which of these controls the object store supports and how retention locks are applied.

DSL exports do not replace a backup. The Dify docs say an app export carries configuration, workflow nodes, model parameters, prompts and knowledge base connections, but leaves out third-party API keys, knowledge base content and usage logs. A team that relies only on exported YAML would rebuild its apps and lose the data behind them. Use DSL files as a readable record of app design that can sit in version control, and keep the full backup set, including storage and vector data, in the protected offsite location described above.

A restore runbook you rehearse before you need it

The restore sequence brings a self-hosted Dify back in a fixed order, from a clean host at the backup's version through data restore to functional checks. Rehearsing it in a separate environment on a schedule shows whether the backups can actually rebuild the platform.

  1. Match the restore version to the backup

    Before touching a server, confirm the Dify version recorded with the backup, then pull that exact version of the images and the matching Compose files from the release tag. Restoring with a newer or older build than the one that wrote the data can fail on schema or configuration differences, so the version recorded in the backup manifest should be the one you deploy. Done when the manifest version, the image tags and the Compose checkout all agree.

  2. Provision a clean host and restore env files

    Build a fresh host that meets the documented minimums of 2 CPU cores, 4 GB of RAM and Docker Compose 2.24.0 or later, then place the backed-up .env file and any secret material before starting anything. The SECRET_KEY must be identical to the backup, because changing it after deployment logs out all users and affects encrypted OAuth credentials. Done when the restored .env matches the backup checksum and the host runs the expected Compose version.

  3. Restore the metadata database

    Start only the database service, load the most recent consistent database dump into PostgreSQL (or the MySQL or OceanBase instance you run), and confirm the restore completes without errors. Check row counts for core tables such as accounts, apps and datasets against the figures recorded at backup time. Done when the database accepts connections and those counts match.

  4. Restore file storage and vector data

    Restore the object storage or local volume that holds uploaded documents and generated files, then restore the vector store (Weaviate by default, or the alternative you configured) from its own backup. Both must come from the same backup point as the database, or knowledge bases will reference chunks and files that do not exist. Done when a sample of uploaded files opens from storage and the vector store reports the expected collections.

  5. Start the full service set

    Bring up the full Compose stack, including api, worker, web, plugin daemon, Redis, Nginx, the code sandbox and the SSRF proxy, and watch the api and worker logs for startup errors. Check that the worker starts cleanly, since background indexing depends on it. Done when every container reports healthy and the logs show no database, Redis or storage connection failures.

  6. Run functional checks against the restored platform

    Log in with a known administrator account, open a knowledge base and confirm its documents are listed and searchable, run a test workflow that calls a configured model, and retrieve a file that was uploaded before the backup point. Record each result in the runbook. Done when all four checks pass and the outputs match what the operator expected at backup time.

  7. Rehearse the runbook in a separate environment on a schedule

    Run this entire sequence in an isolated environment on a recurring schedule, not only after an incident, and record elapsed time, errors and any manual steps. Each rehearsal should use a backup taken by the production process, so the test covers the real backup jobs. Ask your provider or internal team to confirm how often rehearsals must run for your recovery objectives. Done when each rehearsal produces a dated record that the checks passed.

  8. Update the runbook after each Dify upgrade

    After each planned upgrade, reread the target version's upgrade guide and the .env.example file, then update the runbook for any new variables, changed services or altered storage paths. Restore a backup taken before the upgrade into the rehearsal environment to confirm the older data still rebuilds. Done when the runbook names the version it was tested against and the latest rehearsal passed on that version.

Security controls for backups that hold prompts, knowledge and secrets

A Dify backup holds prompts, workflow definitions, knowledge base content, uploaded files and the credentials needed to read them. The controls below apply the same care to every backup copy that the live system receives, and each one should be confirmed against your own environment and the Dify docs before you rely on it.

Encrypt backup copies in transit and at rest

Every database dump, file archive and env file copy should travel over encrypted channels and sit in encrypted storage. Dify stores prompts, model settings and knowledge content in the same database and file store you back up, so an unencrypted copy exposes the same material as the live system. Confirm the encryption method, key owner and rotation process with your backup platform and storage provider.

Restrict who can read backup storage

Limit read access to backup buckets, volumes and servers to the small group that performs restores, and separate write access from read access. Dify backups include workspace data from every app and dataset, so a broad read grant lets a single account browse content from all teams. Review the access list on a schedule and remove accounts that no longer run restores.

Use separate credentials for backup jobs

Backup jobs should authenticate with their own accounts, not with the database user or storage keys the running api and worker containers use. If an application credential leaks, a separate backup credential limits the damage, and the reverse holds too. Check that the backup account can read and write only the paths it needs, and that it cannot change Dify's own configuration.

Protect SECRET_KEY in every backup

Store the SECRET_KEY value from your .env file in a secrets manager, not alongside the database dump. The Dify environment reference says this key signs session cookies and JWTs and encrypts OAuth credentials, and changing it after deployment logs out all users. Restoring a database without the matching key can leave stored credentials unreadable, so the key must be backed up with the same care and kept in its own access group.

Handle workspace encryption keys separately

The environment reference says workspace encryption keys can be stored locally or in Azure Key Vault. If your deployment keeps these keys locally, the key material must be captured in a separate, restricted backup, and a restore that lacks it can fail to decrypt protected values. If you use a key vault, back up the vault according to its own process and record which keys belong to which workspace.

Log every restore and access event

Record who opened a backup, who copied it, who ran a restore, and when, in logs kept outside the Dify host. Restore access is the highest-risk action in the backup process because it can recreate data in an environment with weaker controls. Confirm with your security team where these logs are stored, how long they are retained, and who can alter them.

Questions teams ask before backing up a self-hosted Dify

Can our team back up a self-hosted Dify without outside help?

Yes, if you have people who already run Docker Compose or Kubernetes, PostgreSQL and object storage in production. The work is mostly inventory and discipline: listing every store Dify writes to, taking consistent snapshots, copying them offsite and proving a restore works. Teams without those skills usually struggle with the restore test rather than the backup job itself. Plan for an engineer to own the runbook, not just to configure a cron job, and confirm that someone can run a restore when the original owner is unavailable.

What does the team need to provide for a backup engagement?

Expect to provide access to the hosts or cluster running Dify, the cloud accounts that hold object storage and any managed database, and a non-production environment where restores can be tested. You also need the current .env file, the Dify version in use and a list of external vector stores or metadata databases if you have moved off the defaults. Ask the provider to confirm in writing which of these they need before work starts, and who approves access to secrets during the build.

What drives the cost of a Dify backup and restore project?

The main drivers are the number of stores in use, the volume of data in each, the storage provider and how often restores must be tested. A default Compose install has a PostgreSQL database, file storage and the vector store, while an external setup can add Redis, S3-compatible storage and Qdrant or another vector store. Each extra store needs its own snapshot method and its own restore step. Ask any quote to separate one-time runbook work from recurring restore tests, and to state what is included in each.

How long does it take to write a restore runbook?

Duration depends on how many stores you run, how standardized your infrastructure is and how much of the restore must be proven in a test environment. A simple Compose deployment with local storage and one database is a smaller job than a deployment spread across external PostgreSQL, object storage and a separate vector database. No duration is fixed here, so ask your provider for a timeline tied to the written scope, and check whether it includes at least one full restore rehearsal rather than only a documented procedure.

How often should we test a Dify restore?

Test a restore on a schedule you can keep, and always after a Dify upgrade, a change to storage configuration or a change to the SECRET_KEY. The Dify Docker Compose docs advise a backup before every upgrade, and a backup you have never restored is unproven. Frequency is a cost decision: more frequent rehearsals consume more engineer time and test infrastructure, so agree the cadence with your risk owner and record the result of each test as evidence.

Do we need a backup before every Dify upgrade?

Yes. The Dify Docker Compose documentation recommends a backup before every upgrade, and the upgrade guide for each target version on the GitHub Releases page should be followed. Minor releases arrive roughly monthly, so the backup routine should be part of the upgrade checklist rather than a separate project. After upgrading, check .env.example for new variables, because a backup of an old configuration may not capture settings the new version expects.

Is a backup of Dify enough for compliance evidence?

A backup routine helps, but it is one control among several. Auditors look for documented scope, access controls on backup copies, encryption, retention rules and evidence of restore tests. DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications; independent auditors and certification bodies do that. Ask your compliance lead which framework applies before the runbook is written, so the evidence matches what the assessor will request.

How DeployOpen scopes and delivers Dify backup and restore

DeployOpen plans, implements, backs up, documents and supports self-hosted open-source platforms inside your own infrastructure, so Dify backups run in your cloud accounts, data centers or air-gapped network. Each engagement starts from a written, fixed scope that names every data store to protect and the restore tests that prove it works.

How we scope

  • Inventory every data store for your deployment: PostgreSQL or MySQL, file storage, Weaviate or other vector data, Redis and env files.
  • Agree recovery expectations, retention periods and the systems that must return first, recorded in the written scope.
  • Confirm which secrets, including SECRET_KEY, must be stored separately from backups and who holds them.

How we build

  • Configure consistent database and file snapshots so metadata and stored documents match at the same point in time.
  • Set up offsite copies to storage you control, with access separated from the production Dify administrators.
  • Write a restore runbook and rehearse it in a separate environment before any production cutover.

How we hand over

  • Deliver the backup configuration, schedules, retention rules and the restore runbook as documentation your team can run.
  • Record restore test results, including what was restored, how long the steps took and open issues found.
  • Walk your operators through the upgrade step of backing up before every Dify version change, as the Docker Compose guidance recommends.

How we support

  • Offer ongoing support, upgrades and periodic restore testing as a retainer after the initial handover.
  • Review backup jobs and runbooks again when Dify releases change the data layout or the .env.example variables.
  • Agree the support boundary in writing, so your team knows which backup failures DeployOpen handles and which stay with you.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.