Who this is for and what you will be able to do
This guide is for developers and small teams who want to run Dify on their own machine or server without setting up a database and a vector database first. After reading it, you should be able to start Dify with Docker Compose on one machine, change its configuration, replace the default credentials before going live, and upgrade safely later.
What the default deployment includes
The default Docker Compose deployment comes with PostgreSQL, Weaviate, and the other services Dify needs. You do not have to prepare a database or a vector database in advance[1]. The setup runs Dify on a single machine, and the guide then covers security hardening, customization, and upgrades[1].
Prerequisites: hardware, software, and platform
You need at least 2 CPU cores and 4 GiB of memory[1].
You need Docker and Docker Compose 2.35.0 or later, with the Docker daemon running. You also need Git to download Dify, and OpenSSL to generate a token for the Agent local sandbox[1].
Installation differs by operating system[1]:
- macOS: install Docker Desktop and give its virtual machine at least 2 virtual CPUs and 8 GiB of memory.
- Linux: install Docker Engine and Docker Compose following your distribution's instructions.
- Windows: enable WSL 2, install Docker Desktop, and keep the code and container data in the Linux file system.
Once Docker is installed, check the Compose version first[1]:
docker compose versionGetting, configuring, and starting Dify
Choose a release on the Dify releases page. Replace <version> in the command with that release's tag, then clone the repository and move into the docker directory[1]:
git clone --branch <version> --depth 1 https://github.com/langgenius/dify.git
cd dify/dockerNext, create the .env file from the template. Generate a token for the Agent local sandbox and store it in DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN. The Agent backend and its local sandbox both need this shared token to start[1].
Before the first start, set the production credentials listed in the security section if this deployment is for production. You can also set an external vector database or MySQL in .env in place of the default Weaviate and PostgreSQL. Switching after the first start does not migrate existing data[1].
In the dify/docker directory, start the services and check their status[1]:
docker compose up -d
docker compose ps --allServices that keep running should show Up or healthy. The init_permissions task runs only once to prepare storage permissions, and it shows Exited (0) when it finishes[1].
Accessing Dify and deploying remotely
After startup, open http://localhost/install in a browser, create the admin account, and then log in at http://localhost[1].
For a remote server, replace localhost with the server's IP address or domain name. The default HTTP port is 80. If port 80 is already in use, set EXPOSE_NGINX_PORT in docker/.env to another port and include it in the address. For real-time collaboration on a remote server, add NEXT_PUBLIC_SOCKET_URL to docker/.env with the server's WebSocket address, then run docker compose up -d again[1].
Customization: raising the Nginx upload limit
Settings for the whole deployment are stored in docker/.env. They include the Compose profile, published ports, mount paths, health check scheduling, and shared credentials. Other settings are kept per service. Most services load the bundled .defaults files under docker/envs/. Do not edit those files. Put your changes in the local .env file named in the comments. Settings shared by the API, Worker, and scheduled tasks go in envs/core-services/api-worker.env[1].
As an example, here is how to raise Nginx's maximum request body size to 200M. If envs/infrastructure/nginx.env does not exist, copy it from the defaults file first[1]:
cp envs/infrastructure/nginx.defaults envs/infrastructure/nginx.envThen add this line to that file[1]:
NGINX_CLIENT_MAX_BODY_SIZE=200MAfter the change, validate the configuration and then recreate the affected containers. Use up -d rather than restart, because restart keeps the container's existing environment variables[1]:
docker compose config --quiet
docker compose up -dFinally, check the Nginx setting that is actually in effect. The output should include client_max_body_size 200M;. If another value appears, look for an override in docker/.env, because the value can also come from other places[1]:
docker compose exec -T nginx nginx -T 2>&1 | grep client_max_body_sizeSecurity hardening before going live
Before you open the deployment to other people, configure HTTPS and replace the development credentials in docker/.env. Replace DB_PASSWORD and REDIS_PASSWORD for the database and Redis. Set SANDBOX_API_KEY and CODE_EXECUTION_API_KEY to the same strong key for the code execution sandbox[1].
Weaviate needs attention too. Set WEAVIATE_API_KEY to a strong key, add it to WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS, and set WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED to false so that authentication is required. For the plugin daemon, use two different strong keys for PLUGIN_DAEMON_KEY and PLUGIN_DIFY_INNER_API_KEY[1].
The default stack does not publish the database, Redis, the code execution sandbox, or Weaviate ports to the host. Even on a private network, restrict access to those services[1].
Also be aware of SECRET_KEY. If you leave it unset, Dify generates a random key on the first start and saves it with your data. If you set or change it later, tokens and file links signed with the old key stop working[1].
Upgrading
Before you upgrade, choose the target version on the Dify releases page and read its upgrade notes[1]. Every Compose command you run from then on must use the same project name and Compose files as the existing deployment, including any -p or -f options or COMPOSE_PROJECT_NAME. This keeps the existing named volumes mounted[1].
To back up, stop the deployment in dify/docker with docker compose stop, so the database is not writing while you copy its files. Then back up docker/.env, the local .env files, any custom Compose files, and persistent data such as docker/volumes/[1].
Git does not track the local .env files or docker/volumes/, so they stay in place after you check out a new version. If you have edited Git-tracked files such as docker-compose.yaml, stash those changes first. Then run the following from the repository root[1]:
git stash
git fetch --tags origin
git checkout <version>Next, compare docker/.env.example with your current docker/.env, and compare each local service file with its template. Update the settings you need inside your existing files. Do not overwrite them with the templates, because that drops your overrides. Keep your existing database and any vector database still in use, along with their connection settings and Compose profiles. Changing DB_TYPE or VECTOR_STORE does not migrate data[1].
Finally, pull the new images and bring the stack up again[1]:
docker compose pull
docker compose up -d
docker compose ps --allAfter the upgrade, running services should show Up or healthy, and init_permissions should show Exited (0). Then open Dify and try the features that depend on your custom settings[1].
Limits and common questions
- This is a single-machine deployment. The page does not cover multi-machine high availability, so that would need separate planning[1].
- The page does not list costs or specific cloud server sizes. Its hardware requirement is a floor of 2 CPU cores and 4 GiB of memory[1].
- Switching the database or vector store does not migrate data automatically. Keep that in mind at first start and during upgrades[1].
Next steps
For the full list of environment variables and the priority rules that apply to them, follow the configuration reference linked from the page[1].
Adapted from the Dify documentation page on deploying Dify with Docker Compose[1], released under the CC BY 4.0 license.
Sources
- 1使用 Docker Compose 部署 DifyDify docs (CC BY 4.0)
Cite this page: Self-hosting Dify with Docker Compose. TellWorld, https://www.tellworld.net/practice/practice-dify-docker-deploy. Updated 2026-11-14