当 docker-compose.yaml 文件部署时,Dify 线上版本升级过程

如果线上 Dify 是通过 docker-compose.yaml 文件部署的,那么当 Dify 版本升级时该如何操作呢?官方已经给出了 Docker composeSource Code 两种方式。相对而言,前者更简单些,至少不需要安装依赖包和迁移数据库文件。为了更加具体化理解,假设把 Dify v0.9.1 升级为 Dify v0.9.1-fix1 版本[1]。

本文主要介绍当 docker-compose.yaml 文件部署时,Dify 线上版本升级过程。主要用到的内容就是 docker 目录中的这些文件。对这些文件的详细介绍,参考文献[2]。当docker-compose.yaml文件部署时,Dify线上版本升级过程:https://z0yrmerhgi8.feishu.cn/wiki/O0q9wPKL9istdgkldDzcArV9nMe

一.重点文件介绍

1.yaml 和.env 文件关系

(1).env 文件作用

yaml 文件和 .env 文件什么关系呢?比如 .envdocker-compose.yamlmiddleware.envdocker-compose.middleware.yaml。简单理解,docker-compose.yaml 文件可引用 .env 文件中的环境变量。docker-compose 支持从 .env 文件中加载环境变量,并在 docker-compose.yaml 文件中使用它们。这通常用于配置敏感信息或根据不同环境(开发、生产等)动态设置参数。

(2)默认加载.env 文件

需要注意的是默认情况下,无论是 docker-compose.yaml 还是 docker-compose.middleware.yaml,它们都只会读取当前目录下的 .env 文件,不会自动读取其他命名的 .env 文件(如 middleware.env)。

因此,docker-compose.middleware.yaml 不会默认读取 middleware.env 文件中的环境变量,除非显式指定它。

(3)指定加载 middleware.env 文件

如何让 docker-compose.middleware.yaml 读取 middleware.env需要通过 --env-file 选项来显式指定 middleware.env 文件,这样它才能被正确加载。比如,docker-compose --env-file middleware.env -f docker-compose.middleware.yaml up。具体到 docker-compose.middleware.yaml 文件中指定 middleware.env 如下所示:

(4)docker-compose.yaml 文件部署

因为线上使用 docker-compose.yaml 文件部署,所以用到了 .envdocker-compose.yaml,没有用到 middleware.envdocker-compose.middleware.yaml

二.线上版本更新 [1]

1.需要备份的文件

包括 docker-compose.yaml 文件,.env 文件,volumes 目录。如下所示:

cd docker
cp docker-compose.yaml docker-compose.yaml.$(date +%s).bak
cp .env .env.$(date +%s).bak
tar -cvf volumes-$(date +%s).tgz volumes

2.需要更新的文件

包括 docker-compose.yaml 文件,.env 文件。操作方式是使用目标版本(比如 Dify v0.9.1-fix1 版本)的对应文件,同时更新相关参数,比如 URL、数据库密码、开放端口等。

3.线上升级操作过程

备份和更新文件后,首先停止服务,然后更新服务,如下所示:

sudo docker compose -f docker-compose.yaml -p "dify0901" up -d
sudo docker compose -f docker-compose.yaml -p "dify0901-fix1" down

三.线上更新原理

1.镜像是何时更新的

如果使用官方镜像,系统会自动从 Docker Hub 拉取。如果自行打包镜像,那么需要上传服务器后进行加载。

2.数据库是合适迁移的

langgenius/dify-api:0.9.1-fix1 镜像就是通过如下 Dockerfile 打包的,容器启动时会执行命令 ENTRYPOINT ["/bin/bash", "/entrypoint.sh"],如下所示:

ENTRYPOINT ["/bin/bash", "/entrypoint.sh"] 命令中就有数据库迁移的脚本,如下所示:

根据什么迁移呢?就是 alembic_version 表中的 version_num。迁移什么内容呢?就是 dify\api\migrations\versions 目录下自动生成的文件。如下所示:

具体到 Dify v0.9.1 升级为 Dify v0.9.1-fix1 版本,对应的文件为 2024_10_09_1329-d8e744d88ed6_fix_wrong_service_api_history.py。如下所示:

3.解释迁移文件

2024_10_09_1329-d8e744d88ed6_fix_wrong_service_api_history.py 为例,如下所示:

"""fix wrong service-api historyRevision ID: d8e744d88ed6
Revises: 33f5fac87f29
Create Date: 2024-10-09 13:29:23.548498"""
from alembic import op
from constants import UUID_NIL
import models as models
import sqlalchemy as sa# revision identifiers, used by Alembic.
revision = 'd8e744d88ed6'
down_revision = '33f5fac87f29'
branch_labels = None
depends_on = None# (UTC) release date of v0.9.0
v0_9_0_release_date= '2024-09-29 12:00:00'def upgrade():# ### commands auto generated by Alembic - please adjust! ###sql = f"""UPDATEpublic.messages
SETparent_message_id = '{UUID_NIL}'
WHEREinvoke_from = 'service-api'AND parent_message_id IS NULLAND created_at >= '{v0_9_0_release_date}';"""op.execute(sql)# ### end Alembic commands ###def downgrade():# ### commands auto generated by Alembic - please adjust! ###sql = f"""UPDATEpublic.messages
SETparent_message_id = NULL
WHEREinvoke_from = 'service-api'AND parent_message_id = '{UUID_NIL}'AND created_at >= '{v0_9_0_release_date}';"""op.execute(sql)# ### end Alembic commands ###

这段 Alembic [3]迁移脚本用于修正 service-api 相关的数据问题,具体是更新 messages 表中的 parent_message_id 字段。

(1)头部注释

"""fix wrong service-api historyRevision ID: d8e744d88ed6
Revises: 33f5fac87f29
Create Date: 2024-10-09 13:29:23.548498
"""
  • 功能描述:这段注释说明了本次迁移的主要功能是修复 service-api 的历史记录数据。
  • Revision ID: d8e744d88ed6 是此次迁移的唯一标识符。
  • Revises: 依赖于之前的迁移版本 33f5fac87f29
  • Create Date: 创建日期为 2024-10-09。

(2)导入相关模块

from alembic import op
from constants import UUID_NIL
import models as models
import sqlalchemy as sa
  • alembic.op:用于执行数据库操作,如 op.execute(),这是 Alembic 提供的操作接口。
  • UUID_NIL:假设 UUID_NIL 是一个常量,表示空的 UUID。UUID_NIL 通常代表一个零值 UUID (00000000-0000-0000-0000-000000000000)。
  • modelssqlalchemy:虽然导入了 modelssqlalchemy,但在此迁移脚本中并未直接使用这些模块。可能这些导入是模板代码的产物,或者为将来使用做准备。

(3)版本信息

revision = 'd8e744d88ed6'
down_revision = '33f5fac87f29'
branch_labels = None
depends_on = None
  • revision:本次迁移的唯一标识符。
  • down_revision:指向上一个迁移的 ID,即 33f5fac87f29,用于定义迁移顺序。
  • branch_labelsdepends_on:没有定义分支标签或依赖。

(4)定义版本发布日期

v0_9_0_release_date = '2024-09-29 12:00:00'

v0_9_0_release_date:这是版本 v0.9.0 的发布日期。用作 SQL 查询中的条件,用来确保只影响在此日期及之后创建的数据。

(5)upgrade 函数

def upgrade():# ### commands auto generated by Alembic - please adjust! ###sql = f"""UPDATEpublic.messages
SETparent_message_id = '{UUID_NIL}'
WHEREinvoke_from = 'service-api'AND parent_message_id IS NULLAND created_at >= '{v0_9_0_release_date}';"""op.execute(sql)# ### end Alembic commands ###
  • 功能:当运行 upgrade 时,执行一段 SQL 来修复 parent_message_idNULL 的记录。

  • SQL 逻辑

    • UPDATE public.messages:更新 messages 表。
    • SET parent_message_id = ‘{UUID_NIL}’:将 parent_message_id 字段设置为 UUID_NIL
    • WHERE 子句
      • invoke_from = ‘service-api’:只影响由 service-api 触发的记录。
      • parent_message_id IS NULL:筛选出 parent_message_idNULL 的记录。
      • AND created_at >= ‘{v0_9_0_release_date}’:确保只影响在 v0_9_0 版本发布后的数据(即 2024-09-29 12:00:00 之后创建的记录)。

(6)downgrade 函数

def downgrade():# ### commands auto generated by Alembic - please adjust! ###sql = f"""UPDATEpublic.messages
SETparent_message_id = NULL
WHEREinvoke_from = 'service-api'AND parent_message_id = '{UUID_NIL}'AND created_at >= '{v0_9_0_release_date}';"""op.execute(sql)# ### end Alembic commands ###
  • 功能:当需要回滚迁移时,执行 downgrade 函数,恢复之前的状态。

  • SQL 逻辑

    • UPDATE public.messages:更新 messages 表。
    • SET parent_message_id = NULL:将 parent_message_id 字段恢复为 NULL
    • WHERE 子句
      • invoke_from = ‘service-api’:只影响由 service-api 触发的记录。
      • parent_message_id = ‘{UUID_NIL}’:筛选出 parent_message_idUUID_NIL 的记录。
      • AND created_at >= ‘{v0_9_0_release_date}’:确保只影响在 v0_9_0 版本发布后的数据。

小结:这个迁移脚本的作用是修正 service-api 触发的消息记录,其中 parent_message_idNULL 的记录被更新为 UUID_NILupgrade 函数负责修改数据,downgrade 函数则负责回滚修改。

参考文献

[1] https://github.com/langgenius/dify/releases/tag/0.9.1-fix1

[2] Dify 的 Docker 部署指南 (中文翻译):https://z0yrmerhgi8.feishu.cn/wiki/GDscwWIeiir986kTkyNcIZZAnpe

[3] SQLAlchemy(alembic)和 Flask-SQLAlchemy(Flask-Migrate)入门教程:https://z0yrmerhgi8.feishu.cn/wiki/IbMsw5xbLintiGkCc2bcFDStnMc

[4] 当docker-compose.yaml文件部署时,Dify线上版本升级过程:https://z0yrmerhgi8.feishu.cn/wiki/O0q9wPKL9istdgkldDzcArV9nMe

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何让手机ip变成动态

在数字化浪潮中,手机已成为我们日常生活中不可或缺的一部分。无论是浏览网页、使用社交媒体还是进行在线购物,手机都扮演着举足轻重的角色。然而,在享受网络带来的便利时,我们也需要关注网络安全和隐私保护。静态IP地址可能让手机…

vue3 如何调用第三方npm包内部的 pinia 状态管理库方法

抛砖引玉: 如果在开发vue3项目是, 引用了npm第三方包 ,而且这个包内使用了Pinia 状态管理库,那我们如何去调用 npm内部的 Pinia 状态管理库呢? 实际遇到的问题: 今天在制作npm包时遇到的问题,之前Vue2版本的时候状态管理库用的Vuex ,当时调用npm包内的状态管理库很简单,直接引…

Linux笔记---调试工具GDB(gdb)

1. gdb的概念 GDB,全称GNU Debugger,是一个功能强大的开源调试工具,广泛用于Unix和类Unix系统,以及Microsoft Windows和macOS平台。GDB允许开发者在程序执行过程中查看内部运行情况,帮助定位和修复程序中的错误。 gd…

编译器gcc/g++

gcc 只用来编译C g 编译C/C 1.预处理(进行宏替换/去注释/条件编译/头文件展开等) 先创建 code.c 文件 -E --> 从现在开始,进行程序的翻译,一旦预处理做完,就停下来 -o --> 表明 -o 后面的文件名称 code…

一.安装版本为19c的Oracle数据库管理系统(Oracle系列)

1.数据库版本信息: 版本信息: 或者直接由命令查出来: 2.操作系统的版本信息 3.安装包下载与上传 可以去oracle官网下载也可以从其他人的百度网盘链接中下载: 使用xftp工具或者其他的工具(mobaxterm)上传到l…

DimensionX 部署笔记

目录 生成视频用CogVideoX-5b-I2V 推理代码: DimensionX 生成视频用CogVideoX-5b-I2V 推理代码: 可以生成,从左向右旋转的,也可以生成从上往下旋转的: import torch from diffusers import CogVideoXImageToVideo…

uni-app移动端与PC端兼容预览PDF文件

过程遇到的问题 1、如果用的是最新的版本的pdfjs的话,就会报Promise.withResolvers 不是一个方法的错误,原因是Promise.withResolvers是ES15新特性,想了解可参考链接,这里的解决方案是将插件里的涉及到Promise.withResolvers的地…

Node.js | Yarn下载安装与环境配置

一、安装Node.js Yarn 是 Node.js 下的包管理工具,因此想要使用 Yarn 就必须先下载 Node.js。 推荐参考:Node.js | npm下载安装及环境配置教程 二、Yarn安装 打开cmd,输入以下命令: npm install -g yarn检查是否安装成功&…

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS,并结合cpolar内网穿透工…

[Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress

目录 1. 什么是 Docker Compose 生活案例 2. 为什么要使用 Docker Compose Docker Compose 的安装 Docker Compose 的功能 使用步骤 核心功能 Docker Compose 使用场景 Docker Compose 文件(docker-compose.yml) 模仿示例 文件基本结构及常见…

鸿蒙NEXT应用示例:切换图片动画

【引言】 在鸿蒙NEXT应用开发中,实现图片切换动画是一项常见的需求。本文将介绍如何使用鸿蒙应用框架中的组件和动画功能,实现不同类型的图片切换动画效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT B…

【spring 】Spring Cloud Gateway 的Filter学习

介绍和使用场景 Spring Cloud Gateway 是一个基于 Spring Framework 5 和 Project Reactor 的 API 网关,它旨在为微服务架构提供一种简单而有效的方式来处理请求路由、过滤、限流等功能。在 Spring Cloud Gateway 中,Filter 扮演着非常重要的角色&#…

opencv(c++)图像的灰度转换

opencv(c)图像的灰度转换 quickopencv.h #pragma once #include <opencv2/opencv.hpp> using namespace cv; class QuickDemo { public:void colorSpace_Demo(Mat& image); };quickopencv.cpp #include "quickopencv.h"// QuickDemo类中的颜色空间演示函…

problem forward和solution backward有什么区别

Note: 在具体研究中&#xff0c;problem forward是先提出问题&#xff0c;然后围绕着科学问题设计出完美的解决方案&#xff1b;而solution backward是先盘算自己有哪些技术&#xff0c;有哪些解决方案&#xff0c;反过来去寻找和定义问题。

C++构造函数详解

构造函数详解&#xff1a;C 中对象初始化与构造函数的使用 在 C 中&#xff0c;构造函数是一种特殊的成员函数&#xff0c;它在创建对象时自动调用&#xff0c;用来初始化对象的状态。构造函数帮助我们确保每个对象在被创建时就处于一个有效的状态&#xff0c;并且在不传递任何…

使用WebSocket技术实现Web应用中的实时数据更新

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中…

[N1CTF 2018]eating_cms

打开题目 只有个登录框&#xff0c;其他什么都没有&#xff0c;尝试了一下弱口令&#xff0c;没能成功 尝试访问一下register.php&#xff0c;看看能不能注册个账号 注册页面&#xff0c;随便注册个账号登陆一下 url中感觉是个注入点&#xff0c;尝试使用file伪协议读取一下us…

算法之二分查找优化:leetcode34:在排序数组中查找元素的第一个和最后一个位置

题干 分析 问题背景 给定一个已排序的数组&#xff0c;目标是找到一个给定的目标值 target 在数组中的 第一个位置 和 最后一个位置。如果目标值不存在&#xff0c;返回 [-1, -1]。 由于题干要求的时间复杂度是 O(log n)&#xff0c;并且数组是有序的&#xff0c;考虑使用二分…

【3D Slicer】的小白入门使用指南九

定量医学影像临床研究与实践 任务 定量成像教程 定量成像是从医学影像中提取定量测量的过程。 本教程基于两个定量成像的例子构建: - 形态学:缓慢生长肿瘤中的小体积变化 - 功能:鳞状细胞癌中的代谢活动 第1部分:使用变化跟踪模块测量脑膜瘤的小体积变化第2部分:使用PET标…

为什么要使用Ansible实现Linux管理自动化?

自动化和Linux系统管理 多年来&#xff0c;大多数系统管理和基础架构管理都依赖于通过图形或命令行用户界面执行的手动任务。系统管理员通常使用清单、其他文档或记忆的例程来执行标准任务。 这种方法容易出错。系统管理员很容易跳过某个步骤或在某个步骤上犯错误。验证这些步…