基于windows 使用 Docker 本地化部署Dify
一、环境配置
1.1、安装 Docker Desktop
检查是否安装成功,
打开cmd窗口,输入docker -v 查看docker版本;输入docker info 查看docker信息
1.2、安装WSL
Windows Subsystem for Linux(简称WSL)是一个在Windows 10/11上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。也就是适用于 Linux 的 Windows 子系统 。
安装完毕后,打卡cmd窗口,输入以下命令来检查是否安装成功
wsl-v wsl -l wsl-v -l
二、克隆 Dify 代码仓库
https://github.com/langgenius/dify.git
在D盘新建文件夹dify,解压zip压缩包
进入 Dify 源代码的 Docker 目录,复制环境配置文件,在此路径下打开cmd窗口
三、启动 Docker 容器
docker compose up -d
此时,会报错,错误如下:
Error response from daemon: Get "https://registry-1.docker.io/v2/": dialing registry-1.docker.io:443 container via direct connection because static system has no HTTPS proxy: connecting to registry-1.docker.io:443: dial tcp 162.220.12.226:443: connectex: No connection could be made because the target machine actively refused it.
错误原因是docker无法下载(拉取)一些镜像,https://registry-1.docker.io/v2/不提供镜像下载了,需更换可以提供镜像下载的地址
镜像加速不可用
腾讯云镜像加速器地址:https://mirror.ccs.tencentyun.com
中国科学技术大学:https://docker.mirrors.ustc.edu.cn
Docker官方镜像(中国区)镜像加速:https://registry.docker-cn.com
网易云镜像加速器地址:http://hub-mirror.c.163.com
南京大学镜像加速器地址:https://docker.nju.edu.cn
镜像加速可用镜像源
Daocloud 镜像加速器地址:
"https://docker.m.daocloud.io",
"https://registry.cn-hangzhou.aliyuncs.com",
"https://kqdukn27.mirror.aliyuncs.com"
配置方法,打开docker desktop页面,点击设置图标(右上角此轮图标),在右边输入一下内容
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
“https://docker.m.daocloud.io”,
"https://registry.cn-hangzhou.aliyuncs.com",
"https://kqdukn27.mirror.aliyuncs.com"
]
}
再次执行
docker compose up -d
结果如下图:
出现以上内容,说明dify安装成功
四、访问 Dify
# 本地环境
http://localhost/install
//关闭服务
docker compose down
//启动
docker compose up -d
//查看运行日志
docker compose logs --tail=100 -f api
五、配置
自定义配置
编辑 .env 文件中的环境变量值。然后重新启动 Dify;若添加ollama模型需要再.env文档中最后添加如下两行
# 启用自定义模型
CUSTOM_MODEL_ENABLED=true
# 指定 Olama 的 API地址(根据部署环境调整IP)
OLLAMA_API_BASE_URL=host.docker.internal:11434
六、完成删除dify
若不是重新安装可忽略
需完全删除旧版本的dify,包括容器和卷,删除步骤如下:
6.1、停止容器
在终端中导航到包含 docker-compose.yml 文件的目录,并运行以下命令停止所有正在运行的容器
docker compose down
6.2、删除容器
运行以下命令来删除所有已停止的容器
docker compose rm -f
6.3、删除相关的网络
如果您在 docker-compose.yml 文件中定义了自定义网络,请运行以下命令删除相关的网络:
docker network prune
6.4、删除相关的卷(可选)
如果您在 docker-compose.yml 文件中定义了卷并且不再需要它们,请运行以下命令删除相关的卷:
docker volume prune
6.5、删除 Docker Compose 创建的镜像
默认情况下,docker-compose down 命令不会删除相关的镜像。如果您希望删除由 Docker Compose 创建的镜像,您可以运行以下命令
docker compose down --volumes --rmi all
七、常见问题
7.1、插件安装没有提示成功
以上操作完毕后,就是添加系统模型,在“设置”->“模型供应商”,比如添加ollama、深度求索、硅基流动等模型时;会经常出现安装不成功,这事多点击几下“安装”按钮就会成功安装。
7.2、设置模型的ApiKey时五响应
在为模型供应商设置APIKey时,常时间处于等待状态,
或者出现一异常信息
这中情况,我只能说是玄学,因为多添加几次就会成功,可气的是,我在实操时,一个上午都没添加成功,等下午同样的操作就成功了,个人怀疑是模型提供商服务繁忙。(若有那个大神知道稳妥所在,麻烦留言区告知,不胜感激!!)
错误日志如下:
2025-04-09 09:34:13.405 ERROR [Dummy-57] [app.py:875] - Exception on /console/api/workspaces/current/model-providers/langgenius/openai/openai [POST]
api-1 | Traceback (most recent call last):
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
api-1 | rv = self.dispatch_request()
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
api-1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask_restful/__init__.py", line 489, in wrapper
api-1 | resp = resource(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/views.py", line 110, in view
api-1 | return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return]
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask_restful/__init__.py", line 604, in dispatch_request
api-1 | resp = meth(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/wraps.py", line 187, in decorated
api-1 | return view(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/libs/login.py", line 94, in decorated_view
api-1 | return current_app.ensure_sync(func)(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/wraps.py", line 30, in decorated
api-1 | return view(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/workspace/model_providers.py", line 102, in post
api-1 | model_provider_service.save_provider_credentials(
api-1 | File "/app/api/services/model_provider_service.py", line 145, in save_provider_credentials
api-1 | provider_configuration.add_or_update_custom_credentials(credentials)
api-1 | File "/app/api/core/entities/provider_configuration.py", line 257, in add_or_update_custom_credentials
api-1 | provider_record, credentials = self.custom_credentials_validate(credentials)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/core/entities/provider_configuration.py", line 240, in custom_credentials_validate
api-1 | credentials = model_provider_factory.provider_credentials_validate(
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/core/model_runtime/model_providers/model_provider_factory.py", line 156, in provider_credentials_validate
api-1 | self.plugin_model_manager.validate_provider_credentials(
api-1 | File "/app/api/core/plugin/manager/model.py", line 97, in validate_provider_credentials
api-1 | for resp in response:
api-1 | ^^^^^^^^
api-1 | File "/app/api/core/plugin/manager/base.py", line 189, in _request_with_plugin_daemon_response_stream
api-1 | self._handle_plugin_daemon_error(error.error_type, error.message)
api-1 | File "/app/api/core/plugin/manager/base.py", line 223, in _handle_plugin_daemon_error
api-1 | raise PluginDaemonInternalServerError(description=message)
api-1 | core.plugin.manager.exc.PluginDaemonInternalServerError: PluginDaemonInternalServerError: no available node, plugin not found
api-1 | 2025-04-09 09:34:14.879 ERROR [Dummy-58] [app.py:875] - Exception on /console/api/workspaces/current/model-providers/langgenius/openai/openai [POST]
api-1 | Traceback (most recent call last):
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
api-1 | rv = self.dispatch_request()
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
api-1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask_restful/__init__.py", line 489, in wrapper
api-1 | resp = resource(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask/views.py", line 110, in view
api-1 | return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return]
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/.venv/lib/python3.12/site-packages/flask_restful/__init__.py", line 604, in dispatch_request
api-1 | resp = meth(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/wraps.py", line 187, in decorated
api-1 | return view(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/libs/login.py", line 94, in decorated_view
api-1 | return current_app.ensure_sync(func)(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/wraps.py", line 30, in decorated
api-1 | return view(*args, **kwargs)
api-1 | ^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/controllers/console/workspace/model_providers.py", line 102, in post
api-1 | model_provider_service.save_provider_credentials(
api-1 | File "/app/api/services/model_provider_service.py", line 145, in save_provider_credentials
api-1 | provider_configuration.add_or_update_custom_credentials(credentials)
api-1 | File "/app/api/core/entities/provider_configuration.py", line 257, in add_or_update_custom_credentials
api-1 | provider_record, credentials = self.custom_credentials_validate(credentials)
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/core/entities/provider_configuration.py", line 240, in custom_credentials_validate
api-1 | credentials = model_provider_factory.provider_credentials_validate(
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/app/api/core/model_runtime/model_providers/model_provider_factory.py", line 156, in provider_credentials_validate
api-1 | self.plugin_model_manager.validate_provider_credentials(
api-1 | File "/app/api/core/plugin/manager/model.py", line 97, in validate_provider_credentials
api-1 | for resp in response:
api-1 | ^^^^^^^^
api-1 | File "/app/api/core/plugin/manager/base.py", line 189, in _request_with_plugin_daemon_response_stream
api-1 | self._handle_plugin_daemon_error(error.error_type, error.message)
api-1 | File "/app/api/core/plugin/manager/base.py", line 223, in _handle_plugin_daemon_error
api-1 | raise PluginDaemonInternalServerError(description=message)
api-1 | core.plugin.manager.exc.PluginDaemonInternalServerError: PluginDaemonInternalServerError: no available node, plugin not found
api-1 | 2025-04-10 00:56:47.773 INFO [Dummy-59] [_client.py:1038] - HTTP Request: GET https://marketplace.dify.ai/api/v1/plugins/download?unique_identifier=langgenius/zhipuai:0.0.7@1ee8fe156cc3dffcd085d7fc5581395aecf667cfb548c8d621e505b8a160b619 "HTTP/1.1 200 OK"
api-1 | 2025-04-10 00:57:05.677 INFO [Dummy-60] [_client.py:1038] - HTTP Request: GET https://marketplace.dify.ai/api/v1/plugins/download?unique_identifier=langgenius/replicate:0.0.3@29d878cbb3fe1140bf994eb8efc8070a1210c4cbb3a4ccb76345bfb2f0be08c3 "HTTP/1.1 200 OK"
个人添加成功的结果如下图