🟡第一部分:Dokcer
在开始部署之前,我们先了解一些基础概念,这样你会更清楚自己在做什么,而不是单纯地"照着步骤操作"。
🔘Docker
Docker是用来运行和管理 容器 的一个工具。作为一个独立的环境,里面包含了应用程序本体(dift)及其所有依赖(如操作系统、库、配置文件等)。无论你的电脑是啥环境,容器内的环境始终是一致的。这样就不担心兼容。
- Docker Engine 是核心组件,负责管理容器、镜像、网络和卷。
- Docker Compose 用于描述和管理多容器应用。
- Docker Hub 是镜像的托管平台,用于分享和下载镜像。
- Docker Swarm 和 Kubernetes 是容器编排工具,用于大规模部署和管理容器。
🔘Docker Compose
Docker Compose 是用于定义、运行多容器的 Docker 应用的工具,允许你通过一个命令(比如 docker compose up
)启动、停止和管理多个容器。它的核心功能是基于一个配置文件(通常是 docker-compose.yml
)来描述服务、网络和卷等。换句话说,Docker Compose 是执行操作的工具 ,它负责解析 docker-compose.yml
文件并根据其中的描述来创建和管理容器。以下是 Docker Compose 的典型工作流程:
- 编写 docker-compose.yml 文件:定义应用的所有服务、网络和卷。
- 运行 Docker Compose 命令 :使用
docker compose up
启动所有服务。 - Docker Compose 解析文件 :Docker Compose 根据
docker-compose.yml
文件创建容器、网络和卷。 - 启动容器: Docker Compose 按照依赖关系启动所有服务。
🔘docker-compose.yml (Dify)
Dify 是一个开源的 AI 应用开发平台,允许创建和管理 AI 应用。它需要多个服务协同才能工作,其中涉及到处理网页请求的Web服务器Nginx ;核心后端服务API 服务 ,存储数据的数据库 ;缓存数据加速访问的Redis 。这些服务会分别运行在不同的 Docker 容器中。
下图是 Dify 的 docker-compose.yml
文件对应的服务架构图,展示了 Dify 部署时各个服务(容器)间的关系、依赖、数据存储的挂载方式。
服务(Services)
图中的方框(比如 nginx
、worker
、api
、web
、db
、redis
)表示"服务"。每个"服务"就是一个独立的 Docker 容器。你可以把容器想象成一个小房间,里面运行着一个程序。nginx
里运行着 Nginx。api
里运行着 Dify 的后端程序(处理你的数据请求)。 db
里运行着数据库。docker-compose.yml
文件中,services
部分定义了所有服务:
yaml
services:
nginx:
image: nginx:latest
api:
image: langgenius/dify-api:1.1.3
db:
image: postgres:15
每个服务名对应一个容器,image
指定了容器运行的程序。服务名称就像是房间的名称,您可以随意更改它,比如把nginx改成 "xxx" 。只是要注意所有引用该服务名称的地方都需要进行相应的更新,以确保容器之间的通信和其他配置仍然有效。image才是决定这个房间真正的用途,使用不同的标签可以确保部署特定版本的软件。
端口映射(Ports)
Docker 容器的作为一个隔离的 运行环境 ,就像一个独立的小电脑,每个容器都有自己的网络栈,这意味着容器内部的应用程序绑定的是容器内部的端口 ,因此外部无法直接访问容器内部的服务。例如你在容器内启动了一个 Web 服务,监听了 80 端口。如果没有端口映射,你无法从(主机或外部网络)访问这个服务,因为它只存在于容器内部。端口映射的作用就是将容器内部的端口暴露给外部 。
当然,不是所有服务都需要端口映射。对于Docker内部的服务间通信,也就是两个服务都在同一个 Docker 网络中(比如 Dify 的 API 服务和 PostgreSQL 数据库),它们可以直接通过服务名和容器内部端口进行通信,而不需要端口映射。比如API 服务可以通过 db:5432 访问 PostgreSQL 数据库,而不需要将 5432 映射到主机。或者说如果某个服务只需要在容器内部运行,并且不需要外部访问(比如 Redis 缓存),那么可以不进行端口映射。
图中 80
端口指向 nginx
,表示 nginx
服务监听 80 端口。你用浏览器访问 http://localhost
(默认是 80 端口),请求会到达 nginx
。在 docker-compose.yml
中,端口映射用 ports
定义:
yaml
services:
nginx:
ports:
- "80:80" # 宿主机端口 : 容器内部端口
# 这表示:你电脑的 80 端口被映射到 `nginx` 容器的 80 端口。
卷(Volumes)
卷是你自己电脑上的一个本地路径,用来存容器的数据。因为容器是临时的,如果你删除了容器(比如关机后清理),容器内部的数据会丢失。卷可以让数据持久化,保存在你电脑上,即使容器没了,数据还在。图中有 /volumes/
开头的部分(比如 /volumes/app/storage
、/volumes/db/data
),这些都是 Docker 卷。
图中有几个卷:/volumes/app/storage
:存储 Dify 应用数据(比如用户上传的文件)/volumes/db/data
:存储数据库的数据。 /volumes/redis/data
:存储 Redis 的缓存数据。
在 docker-compose.yml
中,卷分为两部分定义:顶层 volumes
定义:声明所有用到的卷。
yaml
volumes:
app_storage:
db_data:
redis_data:
这里只是定义了卷的名称(app_storage
、db_data
等)。实际存储路径(比如 /volumes/db/data
)由 Docker 自动管理,通常在你电脑的 Docker 数据目录下(比如 Windows 的 C:\ProgramData\Docker\volumes
)。服务中的 volumes
映射会和和挂载路径一起解释。
挂载路径(Mount Paths)
把宿主机上的某个文件或目录(比如卷 /volumes/app/storage
)"挂载"到容器内部的某个路径(比如 /app/api/storage
)。简单来说,挂载就是"连接":让容器能访问宿主机上的文件或目录。挂载后,容器(api
)可以在 /app/api/storage
路径下读写数据,而这些数据实际保存在宿主机的 /volumes/app/storage
中。
- 图中有很多挂载路径:
/volumes/app/storage
挂载到worker
和api
服务的/app/api/storage
路径。- 这表示
worker
和api
共享同一个存储目录,数据保存在宿主机的/volumes/app/storage
中。
- 这表示
/volumes/db/data
挂载到db
服务的/var/lib/postgresql/data
路径。- 数据库的数据会保存在宿主机的
/volumes/db/data
中。
- 数据库的数据会保存在宿主机的
/etc/nginx/nginx.conf
是nginx
容器的路径,挂载自宿主机的./nginx/nginx.conf
文件。- 这表示
nginx
容器会使用宿主机上的./nginx/nginx.conf
文件作为配置文件。
- 这表示
在 docker-compose.yml
中,挂载路径用 volumes
字段定义:格式是 宿主机路径:容器内部路径
:
yaml
services:
api:
volumes:
- app_storage:/app/api/storage
worker:
volumes:
- app_storage:/app/api/storage
db:
volumes:
- db_data:/var/lib/postgresql/data
nginx:
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
app_storage:/app/api/storage
表示把卷app_storage
挂载到容器内部的/app/api/storage
路径。./nginx/nginx.conf:/etc/nginx/nginx.conf
表示把宿主机上的./nginx/nginx.conf
文件挂载到容器内部的/etc/nginx/nginx.conf
路径。挂载路径(app_storage:/app/api/storage
)就像一条传送带,把宿主机上的文件或卷(/volumes/app/storage
)连接到容器内部的路径(/app/api/storage
)。 这样容器就可以读写数据,而数据实际保存在宿主机上。
网络关系(Network Relationships)
图中的虚线箭头(比如 nginx
到 api
和 web
的箭头)表示服务之间的通信。 在 Docker Compose 中,所有服务默认运行在同一个网络(network)中,服务之间可以通过服务名(比如 api
、web
)直接通信。
Docker Compose 自动为所有服务创建一个默认网络,服务之间可以通过服务名直接访问。比如,nginx
可以通过 api
这个名字访问 api
服务(实际是访问 api
容器的 IP 地址)。如果需要显式定义网络,可以在 docker-compose.yml
中添加:
yaml
networks:
dify-network:
driver: bridge
然后在每个服务中指定网络:
yaml
services:
nginx:
networks:
- dify-network
api:
networks:
- dify-network
在 Docker Compose 中,所有服务默认运行在同一个网络(network)中,因此它们可以通过服务名(如 api
、web
)直接通信。在 docker-compose.yml
中,这通常由 nginx
的配置文件(nginx.conf
)定义,告诉 nginx
如何转发请求。
🟡第二部分:准备工作
🔘步骤 1:安装 Docker Desktop
-
下载安装 Docker Desktop:
- 打开浏览器,访问 Docker 官网:www.docker.com/products/do...。
- 根据你的操作系统(Windows、macOS 或 Linux)下载对应的安装包
Docker Desktop Installer.exe
。 - 按照提示完成安装,启动 Docker Desktop。你会在任务栏右下角看到一个小鲸鱼图标。
-
验证 Docker 是否正常运行:
bashdocker --version # `Docker version 24.0.7, build afdd53b` 的输出,说明 Docker 安装成功。 docker compose version # `Docker Compose version v2.23.0` 的输出,说明 Docker Compose 也正常。
🔘 步骤 2:安装 Git(可选)
-
如果你想通过 Git 克隆 Dify 的代码,需要安装 Git。
-
下载 Git :访问 Git 官网:git-scm.com/downloads。下载适合你操作系统的版本。
-
安装 Git:双击安装程序,按照提示完成安装(可以一直点"下一步",默认设置即可)。
-
验证 Git 安装 :
bashgit --version # `git version 2.43.0` 的输出,说明 Git 安装成功。
-
如果你不想用 Git,也可以通过直接下载 ZIP 文件的方式获取 Dify 代码(后面会讲)。
🟡第三部分:下载 Dify 代码
🔘方法 1:使用 Git 克隆(推荐)
-
打开终端,进入一个你想存放 Dify 代码的目录,比如:
bashcd C:\Users\YourName\Projects # Windows 示例 cd ~/Projects # macOS/Linux 示例
-
克隆 Dify 仓库:
bashgit clone https://github.com/langgenius/dify.git
-
进入 Dify 的
docker
文件夹:bashcd dify/docker
🔘方法 1:直接下载 ZIP 文件
- 打开浏览器,访问 Dify 的 GitHub 仓库:github.com/langgenius/...。
- 点击页面右上角的绿色按钮
Code
,然后选择Download ZIP
。 - 下载完成后,解压 ZIP 文件到一个目录,比如
C:\Users\YourName\Projects\dify
。 - 打开解压后的文件夹,进入到
dify/docker
子文件夹。一定要进到这个文件啊。
🟡第四部分:配置环境变量
Dify 使用一个 .env
文件来配置环境变量(比如数据库密码、端口号等)。
🔘步骤 1:创建自己的 .env
文件
- 进入
dify/docker
文件夹。 - 找到一个名为
.env.example
的文件。 - 复制这个文件并重命名为
.env
(当然win系统直接命名.env可能报错,命令行复制就行)
🔘步骤 2:修改 .env
文件
- 数据库密码:DB_PASSWORD=difyai123456
- Redis 密码: REDIS_PASSWORD=difyai123456
- 初始化管理员密码:INIT_PASSWORD=your_admin_password(可选,设置后安装时会自动填充)
注意 :如果你的电脑上 80 端口(默认 HTTP 端口)被占用,可以修改 .env
文件中的端口:
bash
EXPOSE_NGINX_PORT=8080 # 这样 Dify 会运行在 8080 端口,你需要通过 `http://localhost:8080` 访问。
🟡第五部分:启动 Dify
现在我们用 Docker Compose 启动 Dify 的所有容器。
🔘步骤 1:启动 Docker Desktop
- 确保 Docker Desktop 正在运行(任务栏右下角有小鲸鱼图标,状态是绿色)。
🔘步骤 2:运行 Docker Compose
- 打开终端,进入
dify/docker
文件夹,cd过去 - 运行以下命令:
docker compose up -d
,-d
表示以后台模式运行(容器不会占用终端)。第一次运行时,Docker 会下载所有需要的镜像(Nginx、PostgreSQL、Redis)可能需要几分钟,具体时间取决于你的网速。
🔘步骤 3:检查容器状态
- 打开 Docker Desktop,点击左侧的 "Containers" 菜单。
- 你应该看到几个以
docker-
开头的容器,如下: - 如果它们的 "Status" 都是 "Running"(运行中),说明启动成功。
- 如果有容器状态是 "Exited"(已退出),可以点击容器名称,查看日志(Logs)排查问题。
也可以不通过GUI,直接靠命令行检查,在终端运行:docker ps -a
,你会看到所有容器的状态如下
bash
CONTAINER ID IMAGE STATUS NAMES
abc12345 nginx:latest Up 2 minutes docker-nginx-1
def67890 langgenius/dify-api:1.1.3 Up 2 minutes docker-api-1
🟡第六部分:完成 Dify 安装
Dify 提供了一个安装向导页面,我们需要通过浏览器完成最后设置。打开浏览器,访问:http://localhost/install
,如果你修改了端口(比如 8080),就访问 http://localhost:8080/install
。你会看到 Dify 的安装向导页面。页面会自动检查数据库、Redis 等服务是否正常连接。如果一切正常,点击"下一步"。输入管理员邮箱和密码(如果 .env
文件中设置了 INIT_PASSWORD
,这里会自动填充)。
🟡第七部分:关机后如何重新启动 Dify**
步骤 1:启动 Docker Desktop
- 开机后,Docker Desktop 不会自动启动。双击桌面上的 Docker Desktop 图标,等待Docker 启动完成
步骤 2:启动 Dify 容器
-
通过 Docker Desktop 启动:
- 打开 Docker Desktop,点击左侧的 "Containers" 菜单。
- 找到以
docker-
开头的容器(比如docker-nginx-1
)。 - 如果状态是 "Exited"(已退出),选中所有 Dify 相关的容器,点击顶部蓝色的 "Start" 按钮。
- 等待状态变成 "Running"。
-
通过命令行启动(如果你更喜欢命令行):
bashcd 你的Dify路径/docker
运行:
bashdocker compose up -d (之前第一次已经拉取了镜像,不会再重新下载,放心)
🟡第八部分:常见问题和注意事项
🔘端口冲突
如果 80 端口被占用(比如你本地有其他 Web 服务器),可以在 .env
文件中修改端口:
bash
EXPOSE_NGINX_PORT=8080
然后通过 http://localhost:8080
访问。
🔘停止 Dify
如果你想停止 Dify,进入 dify/docker
文件夹,运行:
bash
docker compose down
或者在 Docker Desktop 中,选中所有 Dify 容器,点击 "Stop" 按钮。
🔘清理数据
如果你想从头开始(比如重新安装),可以删除 volumes
文件夹中的数据:
bash
rm -rf ./volumes/*
然后重新运行 docker compose up -d
。
🔘更新 Dify
如果 Dify 有新版本,进入 dify
文件夹,更新代码:
bash
git pull origin main
然后重新启动容器:
bash
docker compose down
docker compose up -d