Dify Docker Compose upgrade procedure: when to upgrade and which path to follow
If your Compose-based Dify has drifted several releases behind, the upgrade is a runbook, not a pull. The supported path is the upgrade guide for the target version on the Dify releases page, followed step by step, with a backup taken first. Minor releases have arrived roughly monthly: 1.16.0 on July 17, 2026, 1.17.0 on August 25, 2026 and 1.17.1 on September 10, 2026. A deployment that skips several of these carries several sets of changes at once, so the gap, not the calendar, should drive the decision to act.
Each release can add services Dify needs, change defaults or introduce new variables, which is why a bare docker compose pull can leave a stack that starts but misbehaves. The Dify Docker Compose docs tell operators to compare each .env.example against their live .env and to reapply local edits onto the new docker-compose.yaml. Before you schedule anything, read the release notes for every version between your current tag and the target, and confirm whether the target needs a particular Compose version. Dify's self-hosting docs set Docker Compose 2.24.0 or later as the minimum, so check that on the host early. This page covers Community Edition Compose deployments only; Enterprise on Kubernetes follows a different path.
Some jumps change the architecture itself and have their own runbooks. Moving from 0.x to 1.0 brings the plugin architecture, the Weaviate client change starts at 1.9.2, and instances older than 1.15 need provider data migrated. Confirm which of these applies to your version range before following the steps here, and use the sibling pages for those jumps. If none applies, the procedure below is the one to run, and the decision you need to make now is who owns the maintenance window and the rollback plan.
What changes between releases and what each change requires
This table lists the Dify releases and security changes named in the supplied release record and maps each one to the upgrade work it creates for a Compose deployment. Read it as a pre-upgrade checklist: find every target version between your current release and the one you plan to run, then complete the action in each row. Breaking changes are not fully captured here, so confirm them in each target version's release notes before you start.
| Release or change | What changed | Action needed |
|---|---|---|
| Dify 1.16.0 (July 17, 2026) | Minor release in the monthly cadence; the release notes for this version define any schema or configuration changes | Read the 1.16.0 release notes, diff .env.example and reapply Compose customizations if you are upgrading across this version |
| Dify 1.16.1 agent sandbox isolation | Security change routing agent sandbox network traffic through a Squid proxy | Confirm the sandbox and proxy services exist in the new docker-compose.yaml and that your custom network rules still apply |
| Dify 1.16.1 inter-service authentication | Token-based API authentication between Dify services | Check the new environment variables in .env.example and set any required token values before restarting services |
| Dify 1.16.1 sandboxed Jinja2 rendering | Template rendering runs inside a sandbox | Test workflows that use Jinja2 templates after the upgrade, since template behavior may change |
| Dify 1.17.0 (August 25, 2026) | Minor release that may add services or variables that Dify needs to run | Compare the full service list in the new Compose file against your customized copy before running docker compose up |
| Dify 1.17.1 (September 10, 2026) | Patch release following 1.17.0 | Apply it on the same path as 1.17.0 and confirm no new variables or services were added since your last check |
| New services in a release | A release can add services such as the sandbox, proxy or plugin daemon that the stack depends on | Reapply customizations to the new docker-compose.yaml, do not copy an old file over it |
| SECRET_KEY | Signs session cookies and JWTs and encrypts OAuth credentials; changing it logs out all users and can break access to encrypted credentials | Keep the existing value unchanged across every upgrade and back up the env file before editing |
What to back up and inventory before touching the stack
A Compose upgrade is only reversible if you can restore the exact state you started from. These four items define that state: the data, the configuration, the customizations layered on top of the stock files, and a place to rehearse the change before production.
Copy the entire volumes directory
Dify recommends copying the entire dify/docker/volumes directory before an upgrade. That directory holds the persistent data for PostgreSQL, Redis, the file storage and the vector store, so a partial copy can leave the database and the uploaded files out of step with each other. Stop the stack before copying so the database is not written during the copy, then confirm the copy contains every subdirectory you see in the original. Keep the copy somewhere the upgrade cannot touch, and record where it is in your change ticket.
Preserve the current env and Compose files
Save a copy of your current .env and docker-compose.yaml exactly as they run today. The .env file holds the settings that define your deployment, and the Compose file is the one you will edit against the new release. Keep these copies alongside the volume backup so a rollback restores configuration and data together. Store them with the same access controls you apply to other secrets, because .env contains credentials.
Keep SECRET_KEY unchanged
The SECRET_KEY value signs session cookies and JWTs and encrypts OAuth credentials. Dify's environment reference states that changing it after deployment logs out all users. Keep the value from your current .env and carry it into the new file without alteration, and confirm after the upgrade that the value still matches your backup. Treat any unexpected change as a reason to stop and restore.
Inventory local customizations
Write down every change you made to the stock Compose setup: published ports, the reverse proxy in front of Nginx, TLS termination, external PostgreSQL, Redis or object storage, extra containers such as monitoring agents, and any volume mounts or network rules. A release can add services Dify needs, and it can rename or reshape existing ones, so each customization must be reapplied deliberately rather than assumed to survive. Mark which items are required by your environment and which were temporary.
Rehearse in a test environment
Restore the volume copy, the saved .env and the saved Compose file into a separate host or project directory, then run the upgrade there first. This shows whether your customizations still work, whether database migrations complete on your data, and how long your own steps take. The effort depends on your data size and how many customizations you carry, so ask your team or partner to estimate it from this rehearsal rather than from a generic figure.
The upgrade sequence, with checks and rollback points
This sequence turns a Dify Docker Compose upgrade into a repeatable runbook in which each step has a check that proves it finished and a rollback point that restores the prior state if it did not. Operators can stop at any gate and return to a known-good deployment.
Confirm prerequisites and read the target release
Confirm the host runs Docker Compose 2.24.0 or later, then read the release notes and the upgrade guide for the exact target version on the Dify GitHub Releases page. Note the current image tag and the version you are moving from, and record any release that changes services, variables or security behavior. Check that the host still meets the documented minimums of 2 CPU cores and 4 GB of RAM. Done when you have a written target version, a list of changes that affect your deployment, and the current tag recorded as your rollback reference.
Back up volumes and environment files
Copy the entire dify/docker/volumes directory, as Dify recommends before an upgrade, and save copies of your current .env and docker-compose.yaml alongside it. Store the copy outside the deployment directory and confirm it is encrypted and access-controlled, because it contains database contents and secrets. Verify the copy by checking file sizes and listing its contents against the source. Done when the backup is complete, verified and stored where a restore can reach it. This is your primary rollback point.
Stop the stack and keep the prior files
Stop the running services with Docker Compose from the deployment directory so the database and vector store are quiet before any change. Keep the prior docker-compose.yaml, .env and image references in a dated folder rather than overwriting them. Confirm with the compose status command that no Dify containers remain running. Done when the stack is stopped, the prior files are preserved, and nothing writes to the volumes during the remaining steps.
Diff .env.example and reapply configuration
Compare the new .env.example against your existing .env and add any variables the release introduces, carrying over your values for settings such as SECRET_KEY, which must not change after deployment. Then reapply your customizations, such as port mappings, volume paths, TLS or proxy settings and added services, onto the new docker-compose.yaml, because a release can add services Dify needs. Check each change by diffing the new files against the saved prior copies. Done when every customization is either carried forward or deliberately dropped, and the diff review is signed off by the operator.
Pull the target images and pin the tags
Pull the images for the target version and confirm each service resolves to the tag named in the release guide, including the bundled PostgreSQL, Redis, Weaviate, Nginx, sandbox and SSRF proxy images where your file references them. Record the image digests or tags in your change record. If a pull fails or resolves to an unexpected tag, stop and return to the prior files. Done when all images are present locally at the expected tags and the rollback tag list is written down.
Run database migrations
Run the database migration step described in the target version's upgrade guide, using only the command the release documents. Do not run ad hoc schema commands. Capture the full output and keep it with the change record. If the migration fails, do not start the new services. Restore the volumes and prior files from the backup, and return to the previous image tags. Done when the migration reports success and the output is archived, or when the rollback is complete and verified.
Start services and verify health
Start the stack with the new files and watch the api, worker, web and plugin daemon logs until they settle without repeated restarts. Sign in to the console, open an existing workflow and knowledge base, run a test query against a known model provider, and confirm uploaded documents still retrieve. Check that outbound requests still pass through the SSRF proxy. Done when the core checks pass and the operator records the result. If a check fails, roll back by restoring the volumes, prior configuration files and previous image tags, then restart and repeat the checks.
How the Compose stack's parts change during an upgrade
A Dify Compose upgrade touches more than the application image. The bundled stack starts the api, worker, web, plugin daemon, PostgreSQL, Redis, Weaviate, Nginx, a code sandbox and an SSRF proxy, and each of these is defined by two files that the upgrade can change: the docker-compose.yaml that declares the services, images, volumes and ports, and the .env that supplies their settings. Dify's Compose docs say a release can add services Dify needs, so the new docker-compose.yaml is not interchangeable with the one you ran before. Before you pull images, list each service in the target file, note any service that is new to your deployment, and confirm that your customizations (published ports, mounted certificates, resource limits, reverse proxy changes to Nginx) still map onto the services they were written for.
A stale .env is the most common reason an upgraded stack misbehaves while looking like an application bug. Variables added in a newer release are absent from your file, so the containers fall back to defaults that may not match your deployment. Settings such as SECRET_KEY must carry over unchanged, because changing it after deployment logs out all users. Service-to-service settings, including the sandbox, the SSRF proxy and the vector store selection, must agree across api, worker and the plugin daemon. Compare each .env.example with your .env, reconcile differences deliberately, and run docker compose config against the new files to check the rendered result before starting. A healthy web page with failing knowledge base indexing or broken outbound model calls often points to a service or variable that the upgrade did not carry forward.
The bundled PostgreSQL, Redis and Weaviate are data stores with their own volumes under dify/docker/volumes, so the backup you take covers them only if you copy that directory while the stack is stopped or quiesced. Those stores are not upgraded by swapping the Dify image alone, and a failed migration can leave them in a state the previous release cannot read. If you run an external PostgreSQL, object storage (for example S3-compatible storage), Qdrant, Milvus or another vector store instead of the bundled services, the Compose upgrade does not check them. Confirm their versions and compatibility with the target Dify release from the release notes, take their own backups, and test restores on those systems separately.
What makes a Dify Compose upgrade take longer
The table lists the factors that stretch a Compose upgrade and the direction each one moves the work. Read each row against your own deployment to see which items apply, then size the test window and rollback plan around the ones that push effort up.
| Effort driver | Why it changes the work | How to keep it down |
|---|---|---|
| Customized docker-compose.yaml services or proxy rules | Each override must be re-read against the new file, since a release can add services Dify needs. More overrides mean more merge review and more retesting. | Keep overrides in a short, documented patch file and record why each exists. |
| External PostgreSQL or object storage | Migrations and backups run against systems you manage, so the database snapshot and storage sync become separate steps with their own checks. | Confirm which backup tool covers the external database and how storage versions are retained before the window. |
| Volume size and backup transfer time | Copying the full dify/docker/volumes directory before an upgrade scales with data size and the speed of the destination. Large knowledge bases and file stores lengthen the window. | Measure a test copy of the volumes first and confirm free disk space on the host and the backup target. |
| Number of minor releases skipped | Monthly minor releases mean a longer gap usually brings more .env.example changes, more migrations and more release notes to read. | Upgrade in smaller steps where the release guides allow it, and review each release note in order. |
| Plugins and their compatibility | Plugins installed under the plugin architecture must match the target Dify version, so plugin checks can gate the cutover. | Inventory installed plugins and their versions, then confirm compatibility on a test instance. |
| Custom images | Images you built or patched must be rebuilt on the new base and retested, which adds build and registry steps. | Keep the Dockerfile and build pipeline under version control and tag each build with the Dify version it targets. |
| Test environment available | Without a staging copy with production-like data, verification happens on live users, and rollback decisions take longer. | Restore a recent backup into a separate Compose stack and run the upgrade there before production. |
Who runs the upgrade in-house and who brings in a partner
Your own engineers run every step, using a runbook your team maintains. This suits organizations that already operate Docker Compose stacks, have staff who can read release notes critically, and want the upgrade history kept inside their change process. The runbook is the core asset, so it should be versioned, reviewed and tested against a non-production copy before each minor release.
- Access: Shell access to the Compose host, the registry or mirror used for images, and the Git repository holding your customized
docker-compose.yamland.envfiles. - Backups: A tested backup of the entire
dify/docker/volumesdirectory and your env files, stored somewhere the upgrade host cannot overwrite. - Change window: An approved window with a named rollback decision maker, since the team alone decides when to stop.
- Owners: A named technical owner for the runbook, plus a reviewer for security-relevant release notes.
- What you receive: A runbook you control, with a record of each upgrade and the diffs you reviewed.
Check that the team has time to read each release, not only the upgrade steps, because the security changes in a release can require configuration review.
A partner plans and executes one defined upgrade, from a named source version to a named target version, under written scope and deliverables agreed before work starts. This fits a single large jump, an upgrade that needs remediation of customizations, or a team that wants a documented procedure but will run future upgrades itself. Scope should state which customizations are in and which are out, and how the result is verified.
- Access: Read access to the current Compose files,
.envfiles and volumes, plus a staging host that mirrors production. - Backups: Confirmed backups of volumes and env files before the agreed production window, with restore steps tested.
- Change window: A window agreed in writing, with staff available to approve a rollback during it.
- Owners: A decision maker for scope changes and a named contact who can answer questions about your model providers, identity setup and integrations.
- What you receive: A written upgrade record, the reapplied
docker-compose.yamlchanges, an.env.examplecomparison, and a runbook your team can reuse.
Ask the partner to describe in writing how it will reapply your customizations and what happens if a required new service appears in the target release.
A retainer covers ongoing upgrade work across minor releases under an agreed arrangement. Because Dify minor releases have arrived roughly monthly in the supplied release history, a retainer suits teams that want each release assessed on a regular cadence rather than handled as an emergency. The commercial terms, response expectations and included activities are set in your agreement, so confirm them before you sign.
- Access: Standing access to the Compose host, backup storage and the configuration repository, with a documented way to grant and revoke it.
- Backups: A recurring backup schedule and proof that restores have been exercised, not only that backups exist.
- Change window: Pre-agreed windows for each expected release cycle, so the partner can plan the work.
- Owners: An internal approver for each release and an escalation path for failed upgrades.
- What you receive: Per-release assessments, a maintained runbook, and records of every upgrade, with the reasoning for each configuration change.
Confirm what a retainer excludes, such as skipped releases, customization rework or upgrades that combine with database or Weaviate changes.
Questions teams ask before upgrading Dify Compose
How much effort does a Dify Docker Compose upgrade take, and what drives it?
The effort depends mostly on how far the deployment has drifted from the stock files and how many version jumps sit between the current and target release. A stock deployment that changes only the image tags is usually the least work. The main drivers are the number of customized lines in docker-compose.yaml and .env, the number of releases skipped, whether the deployment uses the bundled Weaviate or an external vector store, and whether the target release adds services or changes the plugin model. Major jumps such as the move to the plugin architecture in 1.0 need far more planning than a routine minor release. Ask any partner to base its quote on a written inventory of these items.
Can our own team upgrade Dify Compose without outside help?
Yes, if your team can read release notes, edit Compose files, run database migrations and verify the application afterward. Dify's Docker Compose docs point operators to the upgrade guide for each target version on the GitHub Releases page, so the procedure is documented. Outside help becomes useful when the deployment has heavy customization, when a jump crosses a major change, or when no one on the team has time to test before a production window. Whichever path you choose, the same skills are needed: someone must own the backup, the diff and the rollback decision.
What does the upgrade need from our team in access, backups and test environments?
You need administrative access to the host running Docker Compose, the ability to stop and start services, and read access to the Dify console for post-upgrade checks. Dify recommends copying the entire dify/docker/volumes directory before every upgrade and keeping a copy of your .env and customized docker-compose.yaml. A separate test environment with a copy of production data lets you run migrations and check apps, knowledge bases and model connections before touching production. Name an owner for the change, an owner for application testing, and someone who can approve a rollback window.
How often do Dify minor releases arrive, and does every one need a full upgrade?
Minor releases have arrived roughly monthly. The GitHub releases page lists 1.16.0 on July 17, 2026, 1.17.0 on August 25, 2026 and 1.17.1 on September 10, 2026. Not every release needs the same effort. Read each release's upgrade notes to see whether it adds services, changes environment variables, requires a particular vector store version or includes security fixes that should go out quickly. Many teams plan a regular cadence for routine releases and a separate, tested track for releases that change architecture or dependencies.
Can a breaking Dify upgrade be rolled back, and how?
Rollback is possible only if you kept a complete backup taken before the upgrade. Restore the copied dify/docker/volumes directory, restore the previous .env and docker-compose.yaml, and start the previous image tags. Database migrations may not reverse cleanly, so the volume backup must include PostgreSQL data and the vector store data, and you should test the restore before relying on it. For jumps involving the bundled Weaviate server or the client change, check the release notes for any stated downgrade limits and confirm them with the vendor before the change window.
What should a fixed-scope quote for a Dify Compose upgrade include?
A fixed-scope quote should state the starting and target versions, the deployment inventory, and the list of customizations to be reapplied. It should name the backup method and retention, the .env.example diff review, the image pull and migration steps, the test cases used to verify apps, knowledge bases and model connections, and the rollback procedure. It should also list what is excluded, such as application redesign, new integrations or plugin development, and state who performs each step. Ask for the deliverables in writing, including the updated runbook. DeployOpen agrees scope, deliverables and timelines in writing before work starts, so the quote follows from that written scope.
Which release notes and docs should we read before planning the upgrade?
Start with the upgrade guide for the target version on the Dify releases page on GitHub, then read the Docker Compose deployment docs and the environment variable reference. Compare the release notes against your deployment inventory to find new services, changed variables and security changes. The 1.16.1 release notes, for example, describe agent sandbox network isolation through a Squid proxy, token-based authentication between services and sandboxed Jinja2 rendering, so those changes affect how you test sandbox and API behavior. Record each finding in the change ticket so the reviewer can see what was checked.
How DeployOpen scopes, delivers and supports Dify upgrades
DeployOpen treats a Dify Docker Compose upgrade as a planned change to your environment, not an image pull. We agree the scope in writing, run the upgrade against a copy of your deployment first, and hand over a runbook your team can repeat for later releases.
How we scope
- Inventory your current Dify version, custom docker-compose.yaml changes, .env values and any external PostgreSQL, Redis, vector store or object storage.
- Confirm the target release and read its upgrade guide on the GitHub Releases page before estimating the work.
- Agree in writing the backup scope, the services in the upgrade, the verification steps and the rollback point before work begins.
How we build
- Back up the entire dify/docker/volumes directory and env files, then rehearse the upgrade on a copy of the deployment.
- Diff each .env.example against your .env and reapply customizations onto the new docker-compose.yaml, documenting every change.
- Pull the target images, run database migrations, and test logins, app runs, knowledge base retrieval and model provider connections before sign-off.
How we hand over
- Deliver a written runbook covering pre-checks, backup locations, the exact upgrade sequence and rollback steps for your environment.
- Document every customized file and variable so the next upgrade starts from a known baseline rather than memory.
- Walk your operators through the procedure and record the verification results so your team can repeat it on its own schedule.
How we support
- Engagements are fixed-scope, so the upgrade, its deliverables and its acceptance tests are defined before work starts.
- Ongoing upgrade planning, patch-level support and continuous testing are available as a retainer, scoped to your release cadence.
- Ask your quote to separate one-time upgrade work from any recurring retainer so you can compare it with your in-house effort.

