Dify 0.x to 1.0 upgrade and plugin migration

Moving an older self-hosted Dify Community Edition onto the 1.0 plugin architecture is a data and dependency change, not an image pull. This page sets out the steps, risks and effort drivers so you can plan it before you start.

On this page

Why a Dify 0.x to 1.0 upgrade is a platform migration

A Dify 0.x to 1.0 upgrade is a platform migration, not an image swap. Models and tools that older Community Editions loaded from the core codebase must be extracted, installed as plugins and then bound to the database schema through migrations. The supported path is the one the Dify 1.0.0 release notes describe: run flask extract-plugins to write every model and tool in use to a plugins.jsonl file, run flask install-plugins to install them, then run flask db upgrade. Skipping the extraction or the plugin installation leaves apps that reference providers the new version no longer loads from the core.

The install step needs network access to the Dify marketplace, so the plan has to say how that access is granted. Confirm which hosts the plugin daemon can reach, whether your egress proxy allows them, and who approves any new outbound path. If the environment is air-gapped, the plugin packages must be prepared and moved in before the cutover, and that work needs its own owner and test window. The release notes also describe flask migrate-data-for-plugin, which prefixes vendor names with langgenius. Any scripts, exports or documentation that match old provider names should be reviewed before and after that step.

Two constraints shape the plan. The self-hosted Community edition is limited to a single workspace, so an older instance serving several business units will not be consolidated by the upgrade and needs a separate decision. Second, Dify's Docker Compose guidance says to follow the upgrade guide for the target version on the GitHub Releases page, to take a backup before every upgrade, and to compare .env.example for new variables afterward. Treat the backup of the metadata database, file storage and SECRET_KEY as the rollback point, and record which version and configuration you are leaving.

What changes in 1.0 and what each change means for operators

This table maps each step of the 0.x to 1.0 move to what it changes on your server and what you must do before or after it. Read it as a sequence: back up first, extract the plugins in use, install them with marketplace access, then run database migrations. The main takeaway is that the 1.0 jump is not only an image pull, and the exact breaking behavior should be confirmed against the 1.0.0 release notes before you schedule the change.

ChangeWhat it means for operatorsAction needed
Backup before upgradeThe Compose docs recommend a backup before every upgrade, and the 1.0 move alters the database schema and plugin setup.Back up PostgreSQL, storage volumes and the .env file, and confirm a restore works on a separate host.
flask extract-pluginsWrites a plugins.jsonl file listing the models and tools your apps currently use.Run it on the 0.x instance and keep the output file with your change record.
flask install-pluginsInstalls the listed models and tools as plugins and needs network access to marketplace.dify.ai.Confirm outbound access to the marketplace, or plan an offline plugin source for air-gapped installs. Confirm the offline method in the 1.0.0 notes.
flask db upgradeRuns the database migrations that the 1.0 release requires.Run after plugins are installed, and confirm the required order in the 1.0.0 notes.
flask migrate-data-for-pluginPrefixes vendor names with langgenius for future compatibility, which can change how existing model references resolve.Test each model provider and tool after the run, and check app configurations that reference them by name.
Environment variables (.env.example)New variables can be added between releases, and missing ones can change behavior after the upgrade.Diff your .env against .env.example and add any new keys before starting containers.
Confirming breaking behaviorThe release notes are the authority for exact breaking changes, command order and any manual steps.Read the 1.0.0 release notes in full and record any step that applies to your version and edition.

Which upgrade path Dify supports from 0.x to 1.0

The documented path from a 0.x Community Edition to 1.0 has five stages: back up the deployment, extract the models and tools the instance actually uses, install those as plugins, run database migrations, and then verify the result. The Dify 1.0.0 release notes describe the extraction step as flask extract-plugins, which writes the inventory to a plugins.jsonl file, followed by flask install-plugins, which fetches each entry from the marketplace, and then flask db upgrade. The release notes also describe flask migrate-data-for-plugin, which prefixes vendor names with langgenius for future compatibility. Read those notes in full before you start, because the exact command sequence and any ordering rules are defined there, not in this summary. Check them against the Dify 1.0.0 release notes and against the Compose upgrade guide for the version you are leaving.

Your starting version decides how much of this path applies. Identify the exact 0.x tag that is running, not the one you remember deploying, by checking the image tags in your Compose file and the values in your .env. Then confirm whether the upgrade guide for your target release expects any intermediate release. Do not assume that one jump is safe. If the documentation names a required stop, plan that stop as a separate, backed-up upgrade with its own verification. Where the docs are silent on a step for your starting version, ask Dify's documentation team or your support channel to confirm it in writing before the change window.

Treat the install step as the most likely point of failure. The plugin install needs network access to the marketplace, so confirm that path in advance and record any proxy or egress rules that apply. Compare the plugins.jsonl inventory against the models and tools your applications call, and keep a list of anything that did not install. Once the migration completes, test each provider credential, each tool and each workflow that depends on them, because a successful database migration does not prove that every model still answers. Keep the pre-upgrade backup until those tests pass and the business owners of each application have signed off.

How to prepare backups, inventory and a test environment before touching production

Six preparation items sit between a running Community Edition and the plugin architecture. Each one gives you a way back, a complete list of what the upgrade must restore, or a place to find breakage before users do. Work through them in order, and treat the test copy as the place where every later step is rehearsed.

Back up the database and volumes

Take a backup of the PostgreSQL metadata database and the storage volumes before any change, including the vector store data if it runs on a local volume. Dify's Compose docs recommend a backup before every upgrade, and this migration rewrites plugin and model records, so a database dump is your only clean rollback. Confirm you can restore the dump into a scratch instance and that the restored app count matches production.

Copy the env file and SECRET_KEY

Copy the .env file to a location outside the deployment directory and record the current SECRET_KEY value. That key signs session cookies and JWTs and encrypts OAuth credentials, and changing it logs every user out. It also protects stored provider credentials, so a new or regenerated key after migration can leave them unreadable. Store the copy with the same access controls as the production secrets.

Inventory apps and their dependencies

List every app and knowledge base, then record the model providers, tools and plugins each one calls. The extraction step reads what is in use, so anything missing from your list is easy to miss in testing. Note the apps that depend on API keys or external tool endpoints, since those credentials are not carried in DSL exports and must be re-entered.

Record customized Compose changes

Diff your current docker-compose.yaml against the stock file and write down every override, such as changed ports, mounted certificates, resource limits or extra services. Upgrading to a newer release means reapplying these changes by hand, and an override you forget will fail silently or disappear. Keep the diff in version control so the reapplied file can be reviewed line by line.

Build a test copy of the instance

Stand up a separate instance from a restored backup and an identical .env, on infrastructure that matches production in image versions and Compose layout. Run the extraction, plugin install and migration there first, then test representative workflows, knowledge base queries and model calls. Record how long each step took on the copy, since that is the only timing evidence you will have before the production window.

Confirm marketplace access for the install

The plugin install step downloads packages from the Dify marketplace, so the host running it needs outbound access to the marketplace endpoint. Confirm that the egress rules, proxy settings and any firewall policy allow that connection from the exact host and network path used for the upgrade. In an air-gapped network, plan how the packages will be obtained and loaded before the window opens.

The upgrade sequence, with checks and rollback points

This sequence moves an older Dify Community Edition onto the plugin architecture in an order where every step has a verifiable output and a point you can return to. Each step ends with a check, so a failure is caught before the next change is made.

  1. Take and verify a full pre-upgrade backup

    Before anything changes, the operator stops nothing yet but captures a complete copy of the PostgreSQL database, the file storage volumes, the vector store data, and the current .env and docker-compose.yaml files. Store the copies outside the host being upgraded. The step is done when the database dump restores into a scratch instance and the volume archives list the expected files. This is your primary rollback point: if any later step fails, restoring this set returns the database and volumes to the pre-upgrade state. Confirm the exact backup commands for your database and storage backend with the Dify docs for your installed version.

  2. Freeze changes to apps, models and tools

    Ask app owners to stop editing apps, knowledge bases and model provider settings for the duration of the upgrade, and pause any scheduled jobs that write to Dify. Record the current version, the list of model providers and tools each app uses, and a screenshot or export of critical app DSL files. The step is done when the change freeze is communicated in writing and the current running version is recorded. Without this, the backup from the previous step will not match the state you test against.

  3. Extract the models and tools in use

    On the older instance, run the Dify 1.0 extraction command, flask extract-plugins, which writes the models and tools referenced by existing apps into a plugins.jsonl file. Keep this file with the backup. The step is done when plugins.jsonl exists and lists every provider and tool you expect. Compare the list with the providers you know are configured. Missing entries usually mean an app references a tool that was removed, so decide now whether to keep or replace it.

  4. Review the plugin list before installing

    Read plugins.jsonl line by line with the app owners. Confirm each plugin is one your organization approves, check the vendor names, and mark any plugin that is deprecated, custom or built in-house for separate handling. Confirm with your security team how the marketplace is reached, since the install step requires network access to the Dify marketplace. The step is done when each entry has an approved, rejected or deferred status in your change record. Rejected entries should not be installed, and their dependent apps need a replacement plan before go-live.

  5. Install plugins with marketplace access

    Run flask install-plugins against the reviewed list from an environment that can reach the marketplace. The installs are fetched and registered through the plugin daemon. The step is done when the command reports success for each approved plugin and the plugin management screen shows them as installed. Record the installed versions. If the host has no marketplace access, the install step will fail, and this is where air-gapped planning must already be resolved: you need a source for plugin packages that your team can verify.

  6. Migrate vendor names and upgrade the database

    Run flask migrate-data-for-plugin, which prefixes vendor names with langgenius for future compatibility, and then run flask db upgrade to apply the schema migrations. Run them in that order as described in the 1.0.0 release notes. The step is done when both commands finish without errors and a database query confirms the migration version has advanced. If either command fails, stop and restore the database from the pre-upgrade backup before retrying, because partial schema changes are the hardest state to recover from.

  7. Diff .env.example and start services

    Compare your existing .env with the .env.example file for the target version and add any new variables you need, keeping SECRET_KEY unchanged so existing sessions and encrypted OAuth credentials remain valid. Then pull the target images and start the services with Docker Compose. The step is done when the api, worker, web, plugin daemon and other core containers report healthy and the console loads. If the services fail to start, restore the volumes from the backup and revert the image tags. Changing SECRET_KEY at this point would log out all users.

  8. Test each model and tool before reopening

    Test every model provider and every tool that appears in plugins.jsonl, using a test call or a debug run of an app that depends on it. Check that credentials are accepted, that responses return, and that knowledge base retrieval still works on the upgraded instance. Record the result for each item. The step is done when every entry on the list has a passing test or a documented exception with an owner. Only then reopen editing to app owners. Any provider that fails here is the signal to return to the database and volume backup rather than patch in production.

How air-gapped installs change the plugin step

In a connected environment, the 1.0 migration runs in the order the release notes describe. The team extracts the models and tools in use with flask extract-plugins into a plugins.jsonl file, then runs flask install-plugins, which downloads each plugin from the Dify marketplace. The command needs outbound access to marketplace.dify.ai from the API container, so the egress rules of the production network must allow it before the change window opens. Once plugins are installed, flask db upgrade runs the schema changes, and flask migrate-data-for-plugin prefixes vendor names with langgenius.

  • Egress path: Confirm the API container can reach marketplace.dify.ai through any corporate proxy or firewall rule.
  • Plugin list: Review plugins.jsonl before installing so every model provider and tool in use is present.
  • Version match: Install plugin versions that match the Dify release you are moving to.
  • Rehearsal: Run the sequence on a copy of production data to catch failed downloads early.
  • Rollback point: Take a backup before extraction so a failed install can be reversed.

Before leaving this step, check that every plugin reports as installed and that a test call to each model provider succeeds.

What makes a 0.x to 1.0 upgrade take longer

This table lists the factors that expand or shrink the work of moving an older Community Edition onto the plugin architecture. Read each row as a direction: the more of a driver you have, the more time the extraction, installation, testing and sign-off steps will usually take. Models and tools in use, private tools and customized Compose files are the factors most worth counting before you ask for a quote.

Effort driverWhy it changes effortHow to keep it down
Models and tools in useEach model provider and tool found by the extraction step must be installed as a plugin and checked, so more entries means more installs and tests.Remove unused apps and retired providers before extracting, and confirm the list in plugins.jsonl with the app owners.
Custom or private tools with no marketplace pluginTools without a marketplace plugin cannot be installed by the standard install step and need a separate packaging and testing path.Inventory private tools early and decide whether each is rebuilt as a plugin or retired before the upgrade window.
Customized Compose filesLocal edits to docker-compose.yaml and environment files must be reapplied to the new release, and each edit needs a check against the new defaults.Keep overrides in a separate file where possible and document every change so it can be replayed.
Database sizeLarger metadata databases take longer to back up, restore and run through flask db upgrade, and a rollback takes longer too.Clean up old logs and unused data where your retention rules allow, and measure a restore on a copy before the window.
Number of apps and knowledge basesApps and knowledge bases are checked for broken model references and retrieval behavior after the move, so each one adds review work.Group apps by owner and test the highest-use ones first, with an agreed list of must-pass checks.
Air-gapped constraintsThe install step needs network access to the marketplace, so an isolated network needs an approved route for plugin packages before work can start.Ask early how plugin packages will reach the network and who approves the transfer.
Amount of provider testing neededEach provider's credentials, model types and parameters must be tested after the jump, and some configurations need repeated runs.Agree a short test matrix per provider with the business owners, covering the calls each app actually makes.

What do teams ask before upgrading Dify from 0.x to 1.0?

What does a Dify 0.x to 1.0 upgrade cost, and who pays for what?

The cost comes from labor, not from the software, since Dify Community Edition is free to self-host under the Dify Open Source License. Your team or a partner pays for the backup, the inventory of models and tools in use, plugin installation, database migration, testing of every model provider and app, and documentation. Infrastructure is a recurring cost you already carry, and the Docker Compose stack needs at least 2 CPU cores, 4 GB of RAM and Docker Compose 2.24.0 or later. Ask any quote to split one-time migration work from recurring retainers for support and upgrades, and to name which apps and providers are in scope. DeployOpen does not publish prices; a quote follows from the written scope.

How long does the upgrade take, and what drives the duration?

Duration depends mostly on how many models, tools and apps your instance uses and how many of them must be re-tested after the jump. The main drivers are the number of distinct model providers and third-party tools to extract and install as plugins, the size of the metadata database that the migration must upgrade, whether you run custom Docker Compose changes that need reapplying, and how many workflows depend on tool and model behavior. Network access to the Dify marketplace and your change-control window also set the pace. Ask for a timeline built from an inventory of your deployment, not from a generic estimate.

What does the upgrade need from our internal team?

You need someone who owns the running instance, can take and verify backups, and can approve changes to the production environment. Engineers should be comfortable with Docker Compose, environment files and PostgreSQL, and a product owner should be ready to test each app against its expected output. Security or compliance staff should review the security-related changes in the release notes, such as the agent sandbox network isolation and token-based service authentication introduced in 1.16.1, before cutover. Your team also needs access to the Dify GitHub releases and marketplace during the window, and a named owner for sign-off.

Can our own team do the upgrade without a partner?

Yes, if your team has the Docker and database skills above and enough time for a staged rehearsal. The work is documented: you extract the models and tools in use with the flask extract-plugins command into a plugins.jsonl file, install them with flask install-plugins, and then run flask db upgrade, as described in the 1.0.0 release notes. The harder part is judgment: deciding which plugins to pin, testing each provider credential, and checking that workflows still behave as before. Ask a partner only for the parts your team cannot staff, and confirm which of those steps the written scope covers.

Do our existing apps need to be rebuilt after moving to 1.0?

Most apps do not need a full rebuild, but they do need testing, because the move to the plugin architecture changes how models and tools are referenced. The 1.0.0 release notes describe flask migrate-data-for-plugin, which prefixes vendor names with langgenius for future compatibility, so configurations that point at older vendor names must be checked after migration. Each workflow that calls a model or tool should be run against representative inputs and compared with its previous output. If an app fails, the fix is usually a provider or plugin reconfiguration, but confirm this against your own apps before planning. Exported DSL files keep app configuration and prompts but not third-party API keys, so keep credentials under your own control.

How do we plan an air-gapped install for the 1.0 upgrade?

Plan for the marketplace dependency first, because flask install-plugins needs network access to marketplace.dify.ai. In an air-gapped network, you must stage the plugin packages and images in advance, through an approved transfer path, and confirm with Dify which artifacts your version needs before the change window. Check which container images, the Weaviate or other vector store version, and the code sandbox and SSRF proxy components must be mirrored into your internal registry. Also rehearse the database migration on a copy of production. Ask your vendor or partner to confirm the exact offline procedure for your target release, since this is not fully covered by the supplied migration notes.

What should we back up and verify before starting?

Back up the PostgreSQL database, the file storage location, the environment file and any customized docker-compose.yaml, and the vector store data before every upgrade, as the Dify Docker Compose docs recommend. Record the current Dify version, the list of installed models and tools, and the secret key handling, because changing SECRET_KEY after deployment logs out all users. Restore the backup to a separate environment and confirm that you can start it. A backup you have not restored is not yet a rollback plan.

What the internal team owns and what a partner can take on

The internal team should keep ownership of decisions that depend on knowing the business: which apps, workflows and knowledge bases must survive the jump, who approves a cutover, and which data may leave the environment during the upgrade. A partner can take on the mechanical and verifiable work around those decisions: taking the backup and proving it restores, extracting the plugins.jsonl inventory with flask extract-plugins, running the install and migration steps in a staging copy, and writing the test evidence. Backups belong to the operator of the running instance, so the internal owner should confirm where the database, file storage and .env copies are kept, who can restore them, and how long they are retained before anyone starts the work.

Plugin inventory and marketplace access are the decisions most often left unowned. The internal team should confirm which models, tools and vendor names the instance uses today, whether the install host can reach the marketplace at all, and whether a proxy or allow list must be changed first. If the environment is air-gapped, the team must decide how plugin packages will be obtained and approved before the engagement starts, because the install step cannot complete without that access. Change control and sign-off should stay with the internal change board, which should approve the staging results, the production window and the rollback plan. A partner can prepare the change record and the test evidence for that board.

A fixed-scope engagement fits where the deliverables can be written down before work starts: an inventory of the plugins in use, a staging upgrade with recorded results, a production runbook, and handover notes for the internal operators. The written scope should name what is excluded, such as application redesign, custom plugin development or changes to model contracts, and who signs each deliverable. Ask any partner to state in writing which tasks need access to production, which credentials they will use, and how those credentials are removed at the end. Note that DeployOpen prepares evidence for reviews but does not issue audit reports or certifications, so any external assurance still comes from the organization's own assessor.

How DeployOpen works on this

DeployOpen plans and delivers the move of an older self-hosted Dify Community Edition onto the plugin architecture inside your own infrastructure. The work starts with a written scope that names the models and tools in use, the backup and rollback path, and the air-gapped requirements, then moves through a tested build and a documented handover.

How we scope

  • Inventory the current Dify version, deployment method and every model provider and tool in use before any change.
  • Confirm whether the instance can reach the Dify marketplace or needs an offline plugin path, and record that decision in the scope.
  • Agree in writing which environments, apps, knowledge bases and plugins are covered, since engagements are fixed-scope.
  • Define backup, rollback and acceptance criteria so the client knows what done means before work begins.

How we build

  • Take and verify a backup of the database, file storage and environment configuration before the first change.
  • Run the plugin extraction and installation steps in a staging copy, then check each model provider and tool reconnects.
  • Run the database migrations and the vendor name migration in staging, and record every error and its fix.
  • Test representative apps, workflows and knowledge base queries against the upgraded instance before production cutover.

How we hand over

  • Deliver a runbook covering the exact upgrade sequence, the plugin list with versions and the rollback steps used.
  • Document the air-gapped installation path, including how plugin packages are sourced, stored and approved.
  • Walk your platform and security teams through the verification results and the open items that remain.
  • Provide a record of changes to environment variables, provider credentials and access settings for your audit file.

How we support

  • Agree a retainer if you want ongoing help with later Dify minor releases, plugin updates and database migrations.
  • Plan how plugin versions will be tested before they reach production, since marketplace updates can change behavior.
  • Review each later release's notes and upgrade guide against your deployment before scheduling the change.
  • Keep the runbook current so the next upgrade can be run by your own team or by DeployOpen under a new written scope.

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.