Agent 上云部署实战(上):从 GitHub 到 Linux,用 Dify 跑通中间件、域名和 HTTPS

Agent 上云部署实战(上):从 GitHub 到 Linux,用 Dify 跑通中间件、域名和 HTTPS

摘要:Agent 在笔记本能运行,不代表云服务器可以直接访问。本文以 Dify 官方发布仓库为例,在 Ubuntu 上串起 Docker、PostgreSQL、Redis、向量库、模型配置、端口映射、云安全组、Nginx 与 HTTPS,最后给出分层验收、故障定位和备份升级方法。

服务器上的容器显示 Running,浏览器却打不开;管理页面能登录,Agent 一调用模型就超时。这两种问题发生在不同层,不能靠"把所有端口打开"一起解决。

这篇文章的目标很具体:在一台 Linux 或云服务器上部署真实的 Agent 应用平台,让它经过受控入口被访问,并能完成一次真实模型与工具调用。 不从零编造一个平台,也不把 uvicorn --reload 当生产部署。

系列导航与阅读范围

  • 上篇:Dify 平台型部署,覆盖服务器、中间件、端口、域名、HTTPS 与运维。
  • 下篇:《Agent 上云部署实战(下):部署 LangGraph 官方 ReAct 项目,打通镜像、中间件与 API》,解释代码型 Agent 的部署路线。

两篇关联链接在公开发布后补充。本文以 Ubuntu 24.04 LTS、Docker Engine、Compose v2 为命令环境;其他 Linux 发行版需替换安装与防火墙命令。调用远程模型,不部署本地推理引擎,通常不需要 GPU。

**版本边界:**资料核对日期为 2026-10-11,Dify 示例固定为仓库发布标签 1.17.1。不同版本的服务名、环境文件和 Agent API 有差异,不要拿旧版教程变量硬套新版。单机部署适合学习和小规模验证,不承诺高可用或任何并发指标。

文章目录

  • [Agent 上云部署实战(上):从 GitHub 到 Linux,用 Dify 跑通中间件、域名和 HTTPS](#Agent 上云部署实战(上):从 GitHub 到 Linux,用 Dify 跑通中间件、域名和 HTTPS)
    • 系列导航与阅读范围
    • 一、从官方仓库确认:我们究竟部署哪些东西
      • [1.1 中间件各自解决什么问题](#1.1 中间件各自解决什么问题)
      • [1.2 为什么 API 启了,知识库仍然处理不了](#1.2 为什么 API 启了,知识库仍然处理不了)
    • [二、准备 Linux 服务器:先解决资源和出站网络](#二、准备 Linux 服务器:先解决资源和出站网络)
      • [2.1 安装 Docker Engine 和 Compose v2](#2.1 安装 Docker Engine 和 Compose v2)
    • [三、克隆固定发布版本,而不是直接部署 main](#三、克隆固定发布版本,而不是直接部署 main)
      • [3.1 不要把新版 .env.example 当成旧版"大杂烩"](#3.1 不要把新版 .env.example 当成旧版“大杂烩”)
      • [3.2 首次部署生成独立密钥,成对配置不能漏](#3.2 首次部署生成独立密钥,成对配置不能漏)
    • 四、端口设计:先只允许服务器本机访问
      • [4.1 把公网、宿主和容器三个地址空间分开](#4.1 把公网、宿主和容器三个地址空间分开)
      • [4.2 覆盖端口,不能"加一条更安全的映射"就算完成](#4.2 覆盖端口,不能“加一条更安全的映射”就算完成)
      • [4.3 中间件随官方 Compose 部署,先逐个验收](#4.3 中间件随官方 Compose 部署,先逐个验收)
    • [五、云安全组、Linux 防火墙与 SSH 隧道](#五、云安全组、Linux 防火墙与 SSH 隧道)
      • [5.1 安全组规则如何填写](#5.1 安全组规则如何填写)
      • [5.2 没有域名时,先用 SSH 隧道,不裸露安装页面](#5.2 没有域名时,先用 SSH 隧道,不裸露安装页面)
    • [六、域名、宿主 Nginx 与 HTTPS:把正式入口接起来](#六、域名、宿主 Nginx 与 HTTPS:把正式入口接起来)
      • [6.1 配好 DNS 和 Dify 外部 URL](#6.1 配好 DNS 和 Dify 外部 URL)
      • [6.2 先配置 HTTP 证书校验入口](#6.2 先配置 HTTP 证书校验入口)
      • [6.3 拿到证书后替换为完整反向代理配置](#6.3 拿到证书后替换为完整反向代理配置)
    • [七、部署了平台之后,还要配置一个能执行工具的 Agent](#七、部署了平台之后,还要配置一个能执行工具的 Agent)
      • [7.1 模型 Key 不等于 Dify 应用 API Key](#7.1 模型 Key 不等于 Dify 应用 API Key)
      • [7.2 做一个可验收的任务,不只问"你好"](#7.2 做一个可验收的任务,不只问“你好”)
      • [7.3 接本机模型或内部工具时,localhost 最容易误配](#7.3 接本机模型或内部工具时,localhost 最容易误配)
    • 八、访问异常怎样按层定位
      • [8.1 先在服务器本机查,再从你的电脑查](#8.1 先在服务器本机查,再从你的电脑查)
      • [8.2 什么才叫部署验收通过](#8.2 什么才叫部署验收通过)
    • 九、持久化、备份和升级:不要把容器当数据库备份
      • [9.1 必须备份的不只 PostgreSQL](#9.1 必须备份的不只 PostgreSQL)
      • [9.2 升级应先恢复演练,再切换镜像](#9.2 升级应先恢复演练,再切换镜像)
    • 十、选型与下一步
    • 参考来源与说明

一、从官方仓库确认:我们究竟部署哪些东西

项目地址:langgenius/dify。部署入口不是仓库根目录的一条 Python 命令,而是 docker/ 中的官方 Compose、环境模板、Nginx 模板和持久化目录。固定版本部署说明

不要只复制一个 YAML:其中挂载了本地配置文件,缺少 nginx/、ssrf_proxy/ 等目录可能导致挂载失败。完整克隆仓库,再进入 docker/。

1.1 中间件各自解决什么问题

组件 在这次部署中做什么 是否开放公网端口
Web 与 API 管理界面、应用配置和请求入口 只经统一网关访问
Worker、定时调度进程 执行后台处理、定时任务 不需要
PostgreSQL 应用、用户、知识库等结构化数据 不需要
Redis 缓存、消息与后台任务相关通信 不需要
Weaviate 本文选定的知识检索向量存储 不需要
文件存储 用户上传内容及生成产物 通过授权文件接口访问
插件服务与沙箱 模型/工具插件及受限制代码环境 普通使用不开放调试口
Nginx 统一转发界面和 API 请求 公开入口使用 80/443

这里的向量库是 Weaviate,不需要再安装 Milvus、Qdrant、Elasticsearch 全家桶。本文默认文件存储也不依赖 MinIO。如果选择其他后端,再根据对应环境模板补充服务和配置。

1.17.1 还有独立 Agent backend、local sandbox 和相关代理网络。不要依据早期版本的容器数量判断新版是否"多启动了无用服务"。固定版本 Compose

1.2 为什么 API 启了,知识库仍然处理不了

源码启动入口依据运行模式分别启动 API、Celery Worker 或调度进程。它们可以使用同一应用镜像,却承担不同职责。文档上传后的后台处理不应仅凭 API 首页能打开就判定正常。启动脚本

验收要分别看:入口是否通、数据库是否连接、Worker 是否执行、插件是否初始化、模型是否可达。Running 只是进程状态,不是业务成功。

二、准备 Linux 服务器:先解决资源和出站网络

本文建议先用已有测试服务器验证,不要仅凭教程购买配置。可从 4 vCPU、8 GiB 内存、60 GiB 可用 SSD 的测试机器起步,这是本文保守的起始建议,不是官方最低要求或性能保证。文档规模、插件数量、并发和本地模型都会改变资源需求。

先检查环境:

bash 复制代码
cat /etc/os-release
uname -m
free -h
df -h
sudo ss -lntp

最后一条很重要:如果宿主 Nginx、宝塔或其他应用已经占用 80/443,就不能让 Dify 容器再占同一端口。本文采用"宿主 Nginx → 回环端口 → Dify 内部 Nginx",避免冲突。

服务器需能访问 GitHub、镜像仓库、模型供应商以及所选插件源。GitHub 下载成功不代表模型域名也可访问;模型服务器返回 401 至少说明 TLS 和 HTTP 已通,但不说明你的账号具备调用资格。

bash 复制代码
curl -I --connect-timeout 10 https://github.com
# 将下一行替换为你的模型供应商 HTTPS 域名,不带密钥
curl -I --connect-timeout 10 https://api.openai.com

不要通过关闭 TLS 校验处理证书报错。先查系统时间、CA 证书、DNS 和企业代理。也不要随便使用陌生镜像源并把模型密钥交给它。

2.1 安装 Docker Engine 和 Compose v2

在全新 Ubuntu 上,按 Docker 官方 Ubuntu 安装指引 配置官方 apt 仓库。下面用 Ubuntu 24.04 的 noble,其他版本不要照抄发行版代号:

bash 复制代码
sudo apt-get update
sudo apt-get install -y ca-certificates curl git openssl python3
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

创建 /etc/apt/sources.list.d/docker.sources,内容为:

text 复制代码
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc

ARM64 机器把 Architectures 改成 arm64,并确认应用镜像支持该架构。有既有 Docker/Podman 时先阅读官方冲突包说明,不要在生产机上盲目卸载。

bash 复制代码
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo docker version
sudo docker compose version
sudo docker run --rm hello-world

本文一直使用 sudo docker,避免为方便把所有用户加入接近 root 权限的 docker 组。后面的端口覆盖使用 !override,需要 Compose v2.24.4 或更新。单纯版本较新的 Docker CLI 不代表 Compose 插件也符合要求。

三、克隆固定发布版本,而不是直接部署 main

选择一个没有同名目录的路径,例如当前用户下的 agent-services:

bash 复制代码
mkdir -p "$HOME/agent-services"
cd "$HOME/agent-services"
git clone --branch 1.17.1 --depth 1 https://github.com/langgenius/dify.git dify-1.17.1
cd dify-1.17.1/docker
cp .env.example .env
chmod 600 .env
git rev-parse HEAD

记录最后输出的提交标识。固定仓库标签不一定固定所有镜像:某些依赖镜像仍可能使用 latest。正式交付还应记录实际镜像 digest,做安全审查并测试升级,不能只记录 Dify 标签。

3.1 不要把新版 .env.example 当成旧版"大杂烩"

当前发布版本的入口模板与可选 envs/*.env.example 分工:默认启动参数在根模板,高级配置按服务分组。不要从网上复制另一版本的千行 .env,它可能漏掉新增的安全键,还可能包含已弃用配置。

保留同版本模板,通过编辑器修改 .env。下面是需要检查和修改的键,不是可独立替代整份模板的文件 :环境模板

dotenv 复制代码
DB_TYPE=postgresql
VECTOR_STORE=weaviate
WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=false
NGINX_HTTPS_ENABLED=false
SERVER_CONSOLE_API_URL=http://api:5001

最后一个是 Web 在容器内访问 API 的地址,不要改成 http://localhost:5001。此处 NGINX_HTTPS_ENABLED=false 只表示内部这一跳走 HTTP,公网 TLS 在宿主 Nginx 终止,后面会配置。

3.2 首次部署生成独立密钥,成对配置不能漏

创建 configure_first_install.py,在首次启动前运行。脚本只替换模板中的已存在键,遇到版本不匹配就停止;不打印秘密,也不用于已有实例随意轮换密钥:

python 复制代码
from pathlib import Path
import os
import secrets

p = Path('.env')
text = p.read_text()
values = {k: secrets.token_hex(32) for k in (
    'SECRET_KEY', 'DB_PASSWORD', 'REDIS_PASSWORD',
    'PLUGIN_DAEMON_KEY', 'PLUGIN_DIFY_INNER_API_KEY',
    'DIFY_AGENT_API_TOKEN', 'DIFY_AGENT_SERVER_SECRET_KEY',
    'DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN')}
sandbox = secrets.token_hex(32)
vector = secrets.token_hex(32)
values.update({
    'SANDBOX_API_KEY': sandbox,
    'CODE_EXECUTION_API_KEY': sandbox,
    'WEAVIATE_API_KEY': vector,
    'WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS': vector,
    'WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED': 'false',
    'CELERY_BROKER_URL': 'redis://:' + values['REDIS_PASSWORD'] + '@redis:6379/1',
})
found = set()
lines = []
for line in text.splitlines():
    key = line.partition('=')[0]
    if key in values:
        line = key + '=' + values[key]
        found.add(key)
    lines.append(line)
missing = set(values) - found
if missing:
    raise SystemExit('Template keys missing: ' + ', '.join(sorted(missing)))
temporary = p.with_suffix('.new')
temporary.write_text('\n'.join(lines) + '\n')
os.chmod(temporary, 0o600)
temporary.replace(p)
print('First-install secrets configured; values were not printed.')
bash 复制代码
python3 configure_first_install.py

这些只是这条部署路径中明确处理的密钥,不代表以后增加任何存储后端都不需要新凭证。hex 字符串也避免密码中的 @、:、$ 干扰 Redis URI 和 Compose 展开。

**已有数据库不能靠改 DB_PASSWORD 更新密码。**数据库镜像的初始化密码通常只在空数据目录首次创建时生效。已有实例需要协调数据库密码变更和应用配置,不能重新跑上述脚本。SECRET_KEY 改变也可能影响现有会话和签名。

四、端口设计:先只允许服务器本机访问

4.1 把公网、宿主和容器三个地址空间分开

本文固定访问路径为:

text 复制代码
浏览器 https://agent.example.com:443
  → 云安全组允许 443
  → 宿主 Nginx :443
  → 宿主 127.0.0.1:8088
  → Dify Nginx 容器 :80
  → web:3000 / api:5001
  → PostgreSQL、Redis、向量库与插件服务

agent.example.com 是示例域名,必须换成你自己的。公网 IP 在云平台上可能是 NAT 映射,并不一定出现在 ip addr 中,不能因此把服务绑定到一个不存在的地址。

端口 所属位置 外部访问政策
22 Linux SSH 仅管理员公网 IP 或 VPN
80 宿主 Nginx 证书校验与跳转,可按实际方案调整
443 宿主 Nginx 正式 HTTPS 入口
8088 宿主回环 → Dify 网关 不向公网开放
3000、5001 Docker 中的 Web/API 不做公网映射
5432、6379、8080 Docker 中间件 不做公网映射
5003 插件调试 本教程删除映射

4.2 覆盖端口,不能"加一条更安全的映射"就算完成

在 docker/ 下新建 compose.linux.yaml:

yaml 复制代码
services:
  nginx:
    ports: !override
      - "127.0.0.1:8088:80"
  plugin_daemon:
    ports: !reset []

Compose 普通列表覆盖可能按规则合并,导致原来的公网映射还在。这里明确替换 Nginx 所有原端口并移除插件调试映射。Compose 合并规则

**后续每条部署命令都要带这两个 -f。**如果配置时带覆盖文件,启动时忘了,就可能重新暴露默认端口。

bash 复制代码
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml config --quiet
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml config --services
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml pull
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml up -d
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml ps

不带 --quiet 的 config 会展开密钥,不要把它的完整输出复制到公开 Issue 或博客。ps 中应看到 Nginx 的 127.0.0.1:8088->80/tcp,而不是 0.0.0.0:8088。

4.3 中间件随官方 Compose 部署,先逐个验收

bash 复制代码
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml \
  exec -T db_postgres pg_isready -U postgres -d dify
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml \
  exec -T redis redis-cli ping
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml \
  logs --tail 80 api worker plugin_daemon
curl -I http://127.0.0.1:8088

本文默认数据库用户为模板的 postgres;改了用户就一起改检查命令。Redis 容器模板设置了 REDISCLI_AUTH,无需把密码打在终端命令上。预期 Redis 返回 PONG,页面可能是 200 或重定向;这些是验收标准,不是本文伪造的运行截图。

第一次拉取镜像和安装插件可能较慢。日志出现明确失败时再定位原因,不要反复重启把证据冲掉。

五、云安全组、Linux 防火墙与 SSH 隧道

5.1 安全组规则如何填写

云厂商界面不同,但你要配置的是入站 TCP、端口范围、来源地址 :22 只允许管理员出口 IP /32;80/443 按公开网站或内部系统需求允许。若只给团队用,443 也可限制公司出口或 VPN。

不要为了浏览器打不开而开放 1-65535。没有 PostgreSQL 和 Redis 公网映射时,也不需要在安全组里允许 5432/6379。IPv6 是另一条访问路径,如果配置了 AAAA 记录,同样需要检查 IPv6 监听和安全组。

Ubuntu 的 UFW 示例,先确认 SSH 实际端口并保持第二个 SSH 会话:

bash 复制代码
# 替换 203.0.113.10;这是文档保留示例地址,不是你的管理员 IP
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verbose
# 确认现有策略不会锁死 SSH 后,再启用
sudo ufw enable

已有防火墙规则需人工审查,以上新增规则不会自动移除旧的"全网开放 SSH"。Docker 端口发布与防火墙规则有交互,不能只看 UFW 状态就断言容器安全 。限制发布地址、检查 Docker 规则,并从外部测试。Docker 防火墙说明、端口发布说明

5.2 没有域名时,先用 SSH 隧道,不裸露安装页面

在你的电脑执行:

bash 复制代码
ssh -N -L 8088:127.0.0.1:8088 deploy@YOUR_SERVER_IP

然后打开本机 http://127.0.0.1:8088/install。这样浏览器通过 SSH 加密隧道访问服务器回环端口。SSH 自己连不上时,先修正登录用户、密钥、安全组或 SSH 端口,而不是修改 Dify。

首次安装管理员账户完成之前,建议保持入口只通过隧道访问,避免别人先访问未初始化页面。本文不会替你在真实服务器上修改密码或开放端口。

六、域名、宿主 Nginx 与 HTTPS:把正式入口接起来

6.1 配好 DNS 和 Dify 外部 URL

为你拥有的域名配置 A 记录指向云服务器公网 IPv4。不要添加不能工作的 AAAA 记录。解析传播期间可以分别检查本机 DNS 和外部 DNS。

在 .env 中修改下面这些外部 URL,保留内部 API 地址:

dotenv 复制代码
CONSOLE_API_URL=https://agent.example.com
CONSOLE_WEB_URL=https://agent.example.com
SERVICE_API_URL=https://agent.example.com
APP_API_URL=https://agent.example.com
APP_WEB_URL=https://agent.example.com
FILES_URL=https://agent.example.com
TRIGGER_URL=https://agent.example.com
NEXT_PUBLIC_SOCKET_URL=wss://agent.example.com
ENDPOINT_URL_TEMPLATE=https://agent.example.com/e/{hook_id}
SERVER_CONSOLE_API_URL=http://api:5001

这里使用同一域名,不额外制造跨域、Cookie 跨子域和证书配置难题。模板中的 URL 大多是 origin,不要凭感觉都加 /v1;对外应用 API 的具体路径由应用 API 文档决定。

通过隧道测试时,最好先完成初始化,再切换上述正式域名;否则浏览器可能请求尚未配置的正式地址。

6.2 先配置 HTTP 证书校验入口

bash 复制代码
sudo apt-get install -y nginx certbot
sudo install -d -m 0755 /var/www/acme

创建 /etc/nginx/conf.d/agent.conf,先写下列 HTTP 配置。不要覆盖同名的已有业务文件:

nginx 复制代码
server {
    listen 80;
    server_name agent.example.com;
    location /.well-known/acme-challenge/ {
        root /var/www/acme;
    }
    location / { return 404; }
}
bash 复制代码
sudo nginx -t
sudo systemctl reload nginx
sudo certbot certonly --webroot -w /var/www/acme -d agent.example.com

把域名换成你的,按提示提供邮箱并自行确认协议。HTTP-01 校验要求证书机构能从互联网访问该域名的 80 端口;如果公司要求完全不开放 80,应改用可信 DNS 插件的 DNS-01 流程,而不是关闭证书校验。

6.3 拿到证书后替换为完整反向代理配置

map 位于 http 上下文。Ubuntu 默认 conf.d/*.conf 在此上下文载入;自定义 Nginx 安装需自行确认:

nginx 复制代码
map $http_upgrade $agent_connection {
    default upgrade;
    '' close;
}
server {
    listen 80;
    server_name agent.example.com;
    location /.well-known/acme-challenge/ { root /var/www/acme; }
    location / { return 301 https://$host$request_uri; }
}
server {
    listen 443 ssl;
    server_name agent.example.com;
    ssl_certificate /etc/letsencrypt/live/agent.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/agent.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    client_max_body_size 100m;
    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $agent_connection;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
    }
}
bash 复制代码
sudo nginx -t
sudo systemctl reload nginx
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml up -d
curl -I https://agent.example.com

完整保留路径非常重要:Dify 内部 Nginx 会把不同路径转到 Web/API。不要只代理一个自猜的 /api 然后发现文件预览、插件端点或 WebSocket 都失效。官方路由模板

SSE 需要两层代理都不缓冲;WebSocket 需要 Upgrade 头;上传需要两层都允许足够大小。proxy_read_timeout 是相邻读取的空闲超时,不是"任务一定允许运行一小时"。网关之外的 CDN、负载均衡也可能更早断开。Nginx 代理指令

证书更新后还需要 Nginx 重新加载证书。检查发行版安装的自动续期任务,并设置成功续期后的 reload hook;仅运行一次 certbot 不代表永远没有过期风险。

例如用编辑器创建 /etc/letsencrypt/renewal-hooks/deploy/reload-agent-nginx.sh,内容如下,然后设置可执行权限:

bash 复制代码
#!/bin/sh
/usr/sbin/nginx -t && /bin/systemctl reload nginx
bash 复制代码
sudo chmod 750 /etc/letsencrypt/renewal-hooks/deploy/reload-agent-nginx.sh

实际命令路径以 command -v nginx、command -v systemctl 为准。hook 只在续期成功后加载证书,不替代自动续期任务。

bash 复制代码
sudo certbot renew --dry-run
systemctl list-timers --all | grep certbot

七、部署了平台之后,还要配置一个能执行工具的 Agent

7.1 模型 Key 不等于 Dify 应用 API Key

模型 Key 是 Dify 调用模型供应商的凭证;应用 API Key 是你的业务后端调用 Dify 某个应用的凭证;管理员登录密码则用于控制台。这三个不能混用,也都不要写在公开截图里。

通过 HTTPS 控制台完成管理员初始化后,在模型供应商配置中添加你有权限使用的服务,选择支持所需工具调用能力的模型并完成连接测试。必要时填写供应商明确提供的 API Base,不要把普通网页地址当 API 地址。

7.2 做一个可验收的任务,不只问"你好"

建议创建一个检索型 Agent:提示词要求它"回答前先检索,给出来源,信息不足时说明";连接一个已配置凭证的只读搜索工具;明确最大迭代与费用预算。先在调试界面确认出现工具调用,再保存应用版本。

如果使用知识库,先上传一个不含敏感信息的小文档,配置 embedding 模型,确认索引完成。聊天模型能连接不代表 embedding 模型也已配置;一直等待索引时,应同时看 Worker、embedding API 和向量库,不是只重启 Web。

当前 Dify 包含不同 Agent 类型。传统 Agent-chat/Chatbot 使用聊天消息接口,新版 Agent 有自己的 API 表面,不能把 /v1/chat-messages 宣称为所有 Agent 的通用入口 。以应用页面显示的 API 示例和类型为准。API 入门与应用类型

下面命令用于传统聊天兼容应用,先在终端交互读取应用 Key,避免把真实 Key 写进 Shell 历史:

bash 复制代码
read -r -s -p 'Dify app API key: ' DIFY_APP_KEY
printf '\n'
curl -N --fail-with-body https://agent.example.com/v1/chat-messages \
  -H "Authorization: Bearer $DIFY_APP_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"inputs":{},"query":"请检索并说明 Docker Compose 的用途,附上来源", "response_mode":"streaming", "conversation_id":"", "user":"deployment-check-001"}'
unset DIFY_APP_KEY

inputs 要包含你实际应用要求的变量,不能保证任意应用都接受空对象。通过流式事件中的结束/错误信息判定成功,不只看最初 HTTP 200。聊天消息接口

**服务器出站调用模型与用户入站访问网站是两个方向。**安全组开放 443 入站,不会自动修好服务器出站 DNS、代理或模型额度。

7.3 接本机模型或内部工具时,localhost 最容易误配

在 API 容器内,127.0.0.1 指该 API 容器,不是 Linux 宿主。若模型是同一 Compose 内的服务,用服务名与容器端口;若在另一网络,建立受控网络连接;若在宿主,用可达的宿主私网地址并限制来源。不要为方便把模型服务和 SSH 一起公开。

Linux 上 host.docker.internal 不一定默认存在。添加 host-gateway 映射只能解决名称,还需要宿主服务实际监听可达地址和防火墙允许。SSRF 代理也可能拒绝私网目的地,应针对必要地址添加最小允许规则,不要取消所有限制。

八、访问异常怎样按层定位

8.1 先在服务器本机查,再从你的电脑查

bash 复制代码
# Linux 服务器上
curl -I http://127.0.0.1:8088
sudo ss -lntp
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml ps
sudo nginx -t
sudo journalctl -u nginx --since '10 minutes ago' --no-pager
# 你自己的电脑上
curl -I https://agent.example.com
现象 优先检查 不应做的动作
本机 8088 也不通 容器退出、映射、80/8088 冲突、初始化日志 先开放所有公网端口
本机通,外网超时 DNS、公网 IP、安全组、宿主监听、防火墙 给数据库开公网权限
Connection refused 目标端口无监听、访问了错误地址 只调整模型提示词
HTTPS 证书错误 域名是否匹配、有效期、证书链、时间 用 -k 长期跳过验证
502 上游连接、服务健康、Docker DNS、配置路径 固定一个会变化的容器 IP
页面能开,接口 CORS 错 外部 URL、协议、跨域和 Cookie 永久设置任意来源且忽略凭证
413 两层代理与应用上传限制 无限扩大限制且不设配额
回答最后一次性出现 两层缓冲、CDN、模型是否真流式 宣称 SSE 已实现却不看事件
文档永远在排队 Worker、Redis、embedding、向量库 只重启浏览器
插件安装失败 插件源/PyPI 出站、证书、签名、存储权限 关闭签名验证解决所有问题

502 时优先用服务名检查连接、重新加载网关并排查 DNS,不把动态容器 IP 硬编码进长期配置。错误日志可能包含路径或输入,应脱敏后再分享。

8.2 什么才叫部署验收通过

至少保留四类真实证据:容器健康与映射、HTTPS 页面、工具调用轨迹、外部 API 请求完成。重启后的数据仍在,也要单独检查。以下留给你在自己的服务器实际执行后补图:

【截图占位:Compose 服务及回环端口映射,隐藏敏感变量】

【截图占位:HTTPS 控制台和模型连接测试,隐藏 Key】

【截图占位:一次真实 Agent 工具调用及 API 完成事件】

九、持久化、备份和升级:不要把容器当数据库备份

9.1 必须备份的不只 PostgreSQL

结构化数据库、向量库、上传文件、插件存储、环境配置和新增命名卷都需要纳入清单。先检查实际挂载:

bash 复制代码
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml config --volumes
sudo docker volume ls

volumes/ 是宿主绑定目录,但某些服务使用 Docker 命名卷。只打包这个目录不一定覆盖全部数据。不要使用 docker compose down -v 做普通升级,它会删除相关命名卷。

PostgreSQL 逻辑备份示例,先创建受保护的备份目录:

bash 复制代码
umask 077
mkdir -p ./backups
sudo docker compose -f docker-compose.yaml -f compose.linux.yaml \
  exec -T db_postgres pg_dump -U postgres -d dify -Fc \
  > ./backups/dify-$(date +%Y%m%d-%H%M%S).dump

这是单库备份,插件数据库及其他数据库需另行覆盖;运行中分别备份数据库和文件并不自动提供跨存储一致性。小规模完整备份可以安排停写窗口、停止应用与相关写入、使用正确的数据库备份或存储快照机制,再逐一覆盖绑定目录和命名卷。不要复制正在写入的 PostgreSQL 数据目录并称为可靠备份。

备份要加密、异地保存、设置保留期限,并用隔离环境演练恢复。将 .env 放进未加密的公开对象存储,就是把全套密钥公开。

9.2 升级应先恢复演练,再切换镜像

阅读目标版本 Release 与迁移说明,备份数据和配置,建立新版本目录,按新模板迁移必要键,再测试数据库迁移、插件和知识库。数据迁移后能否退回旧程序,要看 schema 兼容性,不能只 git checkout 旧标签就保证回滚。

单机的 restart: always 只改善进程退出和宿主重启后的恢复,不会给你第二台服务器,更不会自动修好损坏数据。正式多用户服务还需容量、日志轮转、错误告警、配额及灾难恢复计划。

十、选型与下一步

想让团队通过 UI 管理知识库、工具和 Agent,Dify 是更直接的起点。它的运维成本来自完整平台的多个状态服务,而不是一份 Python 文件。

如果你希望图节点、工具执行和 API 协议都由代码控制,下篇基于官方 ReAct 仓库完成镜像构建和服务部署。两种路线都要面对公网入口、中间件和密钥,只是业务编排的入口不同。

先完成这条最小闭环:本机回环访问 → SSH 隧道初始化 → 模型与工具成功 → 域名 HTTPS → 外部 API 验收 → 备份恢复。前一阶段失败时,留在该层定位,不用扩大端口权限掩盖问题。

参考来源与说明

资料采集与核对日期:2026-10-11。配置以固定发布版本为基准;本文给出部署流程与验收标准,不虚构你的云服务器启动结果。

配图为生成式中文示意图,完整提示词随本地 Markdown 保存,实际端口以配置和 docker compose ps 为准。

相关推荐
jaronho2 小时前
【脚本】 【Linux】启动所有网卡
linux·运维·服务器
草莓熊Lotso2 小时前
【C++ 基于微服务的即时通讯系统】基建三件套:gflags + gtest + spdlog 源码编译安装与实战入门
linux·网络·数据库·c++·微服务·log4j
H.莓飛2 小时前
【C++】类与对象(末):static、友元与拷贝优化
linux·开发语言·c++·visual studio
程序员-Benothing10 小时前
Vim编辑器从入门到精通:模式、快捷键、配置、插件
linux·运维·服务器
‎ദ്ദിᵔ.˛.ᵔ₎11 小时前
linux 进程信号 (上)
linux·服务器
小白学大数据11 小时前
拼多多反爬对抗实战:Scrapy 中间件化采集架构解析
开发语言·scrapy·中间件·架构
15Moonlight11 小时前
Linux网络(02):Socket 编程 UDP
linux·网络·udp
wuminyu11 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
liulilittle12 小时前
Linux 下 select 测试函数
linux·服务器·网络·数据库·c++·select·c