PhotoPrism 集群运维实战:节点引导、注册、凭据轮换与安全边界
后端前端图像处理人工智能AI 应用【免费下载链接】photoprismAI-Powered Photos App ✨项目地址https://gitcode.com/gh_mirrors/ph/photoprism点击查看免费下载本文是 PhotoPrism 集群Cluster功能的运维与开发指南聚焦 .claude/rules/cluster-operations.md 中沉淀的集群操作规则。文章围绕「Portal 与节点」之间的引导bootstrap、注册registration、凭据轮换rotation、主题分发与数据脱敏展开并结合internal/service/cluster、internal/api、internal/commands等目录下的源码实现帮助读者掌握集群的认证模型、配置边界与日常运维命令能够在多实例部署中安全地完成节点加入、重启、凭据刷新和清理下线。一、架构总览Portal、节点与三条核心原则PhotoPrism 的集群能力由「Portal门户」与两类节点组成instance实例与service服务。从源码看节点角色由 internal/config/config_cluster.go 的NodeRole()定义Portal 则通过 internal/service/cluster/cluster.go 包对外提供多实例部署与编排能力。整个集群运维遵循三条核心原则也是后续所有规则的总纲引导逻辑保持解耦节点引导bootstrap逻辑位于 internal/service/cluster/node/它只通过internal/service/cluster/const.go中的常量与 Portal 通信绝不从internal/config或集群根包反向导入node/*。这让引导阶段可以在数据库连接建立之前运行。凭据即身份Bearer Token 是注册请求携带的唯一凭据。节点对自己的注册信息做变更时用客户端凭据换取访问令牌access token首次加入集群或 CLI 拒绝换发时才使用 join token。请求体中的标识符只用于「选择记录」必须与调用方比对验证绝不信任为所有权证明。失败不致命引导阶段的所有失败注册失败、主题下载失败都是非致命的节点依然能启动只是暂时处于未注册状态。二、节点引导Bootstrap注册与主题同步的执行时机2.1 引导挂载点与执行顺序节点引导通过config.Register(config.StageBoot, cluster-node, InitConfig, nil)注册为引导扩展在数据库连接建立之前执行见 internal/service/cluster/node/bootstrap.go。InitConfig的完整流程为跳过 Portal 节点与未知角色仅对RoleInstance/RoleService生效若自动加入或自动主题开关开启调用bootstrapClusterNode(c)无论开关如何都会调用resolveNodeOIDCClient(c)将节点客户端凭据派生为 OIDC RP 凭据——这保证已注册实例每次重启后都能自动接好 OIDC 登录记录集群 UUID。其中resolveNodeOIDCClient的优先级值得注意显式配置的PHOTOPRISM_OIDC_*凭据优先未配置时OIDC issuer 默认取实例自身 origin即共享域 Portal 的 OPsecret 优先从文件读取保证轮换后的新 secret 在下次启动即生效internal/service/cluster/node/bootstrap.go。2.2 引导的触发条件bootstrapClusterNode并非无条件执行它要求Portal URL 非空PHOTOPRISM_PORTAL_URL同时具备 join token或节点自身 OAuth 凭据NodeClientIDNodeClientSecret。后者的存在意义在于一个已经加入过的节点在重启时即使 join token 已从环境中移除也能用自身的客户端凭据重新发送一次幂等的注册请求把变更后的声明式配置如组准入配置同步到 Portalinternal/service/cluster/node/bootstrap.go。2.3 注册重试策略与终态判定registerWithPortal的实现internal/service/cluster/node/bootstrap.go给出了明确的 HTTP 状态码语义状态码处理方式200 / 201解析RegisterResponse持久化注册信息预热 JWKS成功返回401 / 403 / 404终态不重试。404 通常表示 Portal 未启用集群端点429按重试策略重试限流400 / 409不重试从响应体中提取 Portal 给出的具体拒绝原因registerError并报告其他 5xx重试直至达到最大尝试次数重试参数由 internal/service/cluster/policy.go 中的包级变量控制并可通过环境变量覆盖变量PHOTOPRISM_前缀默认值含义cluster-bootstrap-auto-join-enabledtrue是否自动注册cluster-bootstrap-auto-theme-enabledtrue是否自动同步主题cluster-bootstrap-max-attempts6最大注册尝试次数cluster-bootstrap-retry-delay15s重试间隔cluster-bootstrap-timeout15s单次 HTTP 请求超时对无效输入非布尔、非正数、非法时长applyPolicyEnv会保持原值不变见 internal/service/cluster/policy_test.go 的验证用例。2.4 注册响应持久化与 secret 文件回退注册成功后persistRegistration会把ClusterUUID、ClusterCIDR、NodeClientID、JWKSUrl、PortalLoginUrl、NodeUUID以及数据库设置写回本地配置。写回遵循「先用校验 setter 验证、再持久化」的原则防止来自 Portal 的畸形 URL 进入options.yml。关键的 secret 持久化逻辑在 internal/config/config_cluster.go 的SaveNodeClientSecret只有当本地尚无NodeClientSecret时才持久化 Portal 下发的 secret默认写入config/node/secrets/client_secret可用NODE_CLIENT_SECRET_FILE覆盖当 secret 文件目录或文件不可写时轮换后的值仅缓存在内存中c.options.NodeClientSecret clientSecret当前进程继续运行但重启后需重新获取——这正是文档中「rotated value stays cached in memory so the current process continues」的源码依据。三、认证模型Bearer Token、join token 与 OAuth access token3.1 两种凭据的分工join token首次加入时使用。它在 Portal 侧通过conf.JoinToken()读取并与请求的Authorization: Bearer头做常数时间比较subtle.ConstantTimeCompare见 internal/api/cluster_nodes_register.go。OAuth access token节点变更自身注册信息时使用。registerAuthTokeninternal/service/cluster/node/bootstrap.go优先用节点自身的NodeClientID/NodeClientSecret通过/api/v1/oauth/token以client_credentialsgrant 换取scope 为cluster仅在无节点凭据时回退到 join token。CLI 侧对应clusterRegisterTokeninternal/commands/cluster_helpers.go节点名称与本地配置一致且有客户端凭据时换发 access token否则用 join token。无论哪种路径节点引导本身不会用 join token 重试——引导是无人值守的失败即告警退出。3.2 Portal 侧的身份校验注册端点POST /api/v1/cluster/nodes/register实现在 internal/api/cluster_nodes_register.go的校验矩阵场景凭据要求说明全新节点加入有效的 join token创建新 OAuth client生成rnd.ClientSecret()默认角色instance请求可声明instance/service已存在名称的变更节点自身 OAuth access tokens.IsClient()且s.ClientUID existingNode.ClientIDjoin token不得变更已有注册否则返回 409新名称 节点 token节点自身 OAuth access token 且该客户端已是注册节点允许节点改名请求体中的NodeUUID只作为「选择记录」的标识nodeUUIDClaimedBy会检查该 UUID 是否已归属其他客户端归属冲突时以 409 拒绝。UUID 的生成使用rnd.UUIDv7()即节点以 UUID v7 为键对应 API 路径/api/v1/cluster/nodes/{uuid}。3.3 注册请求体的字段RegisterRequest的关键字段见 internal/service/cluster/node/bootstrap.go 的buildRegisterPayload字段来源说明NodeNameNodeName()必填DNS label 语义小写[a-z0-9-]1–32 字符首尾不能是-NodeUUIDNodeUUID()未配置时由 Portal 生成 UUID v7NodeRoleNodeRole()instance/serviceAdvertiseUrl/SiteUrl配置或自动派生未配置时由节点名 集群域派生为https://name.domainAppName/AppVersionAbout()/Version()报告应用信息ThemeNodeThemeVersion()本地主题版本用于增量同步DisplayNameSiteName()人工可读名称Portal 端遵循 admin 覆盖优先AllowGroups/AllowGroupRoles/GroupsFullView集群声明式配置实例声明Portal 的 admin 覆盖仍然优先3.4 URL 校验的 HTTP/HTTPS 边界注册端点对 URL 有严格的协议校验internal/api/cluster_nodes_register.goAdvertiseUrl仅接受http/https绝对 URL允许 HTTP 以支持集群内流量SiteUrlHTTPS 总是允许HTTP 仅当主机为localhost、127.0.0.1、::1或属于集群内部服务域时才允许。isClusterServiceHost明确放行三种后缀*.svc、*.cluster.local、*.internal含.svc.中间域其余一律要求 HTTPS。四、主题分发GET /api/v1/cluster/theme主题端点在 internal/api/cluster_theme.go 实现行为要点仅 Portal 节点提供服务conf.Portal()为假时返回 FeatureDisabled认证若配置了ClusterCIDR客户端 IP 在 CIDR 内可直接放行refID cidr否则要求acl.ResourceClusteracl.ActionDownload的会话从conf.PortalThemePath()读取主题目录解析符号链接后打包打包前校验app.js存在且非空fs.FileExistsNotEmpty避免分发空主题通过filepath.WalkDir遍历跳过子目录、非常规文件、符号链接和隐藏文件响应头使用pkg/http/header的辅助函数AddDownloadHeader、AddContentTypeHeaderContentTypeZip而不是手写Content-Type打包期间调用theme.DetectVersion并回写节点记录的主题版本updateNodeThemeVersion。节点侧的主题同步在syncNodeThemeinternal/service/cluster/node/bootstrap.go仅在本地缺少app.js或本地版本与 Portal 声明版本不一致时下载版本一致则跳过下载到c.TempPath()/cluster-theme.zip解压到NodeThemePath()解压限额为 32 MB 单文件、512 MB 总量覆盖安装时先os.RemoveAll(themeDir)再解压下载完成且存在有效app.js后activateNodeThemeIfPresent把ThemePath切到节点主题目录——因此「reinstall only whenapp.jsis missing」是一条硬规则主题缺失或版本落后才重装避免无谓的流量与写放大。五、注册流程的旋转语义与 CLI 运维5.1rotatetrue何时发送RegisterRequest.RotateDatabaseCLI 对应--rotate/--db与RotateSecret--rotate-secret是独立的两个开关数据库轮换仅在节点为 MySQL/MariaDB 且本地未配置有效凭据时自动置为true。判断逻辑在ShouldAutoRotateDatabase()internal/config/config_db.goPortal 节点或非 MySQL 驱动直接返回false否则检查本地 DB 名称/用户/密码是否为空。secret 轮换RotateSecret走regy.RotateSecretByClientID生成新 secret 后回写data.RotatedAt时间戳ClientSecret只在创建与轮换的响应中暴露其他任何响应都不包含明文 secret。注册成功后只有新生成的 secret 与数据库设置会被持久化已存在值不会被覆盖。5.2cluster nodes rotate的双路径cluster nodes rotate id|name命令internal/commands/cluster_nodes_rotate.go会根据运行位置走两条路径在 Portal 上直接作用于本地注册表rotateNodeInRegistry通过regy.FindByName解析节点检查角色仅instance/service依次轮换 secret 与数据库凭据90 秒超时provisionerTimeout支持--dry-run预览在实例上通过 Portal 的注册端点完成rotateNodeViaPortal因为该端点只接受节点自身的 access token——clusterRegisterToken用节点自己的客户端凭据换发 token无法用 join token 或他人凭据越权操作。命令还支持--yes免确认与report.CliFlags输出格式选项。注意--database/--secret是可选的一个都不指定时命令只解析并输出节点当前状态。5.3cluster nodes rm的清理语义cluster nodes rminternal/commands/cluster_nodes_remove.go提供三档删除强度标志行为默认删除该 UUID 对应的最新一条客户端记录软删除--all-ids删除共享同一 UUID 的全部记录管理员清理重复 client 行对应注册表DeleteAllByUUID--purge永久删除所有记录并释放 UUID 供后续节点复用PurgeAllByUUID--drop-db同时删除该 UUID 命名的数据库与用户丢弃数据配合--purge时先删库、后释放标识符安全护栏当 UUID 名下仍有数据库存在时释放操作会被拒绝releaseBlockedBy检查NodeDatabases必须显式--drop-db才能继续--dry-run会完整预览将要发生的动作。此外普通 OAuth 客户端删除命令会阻止删除注册了集群节点的客户端并提示改用cluster nodes rm --purge见 internal/commands/clients_remove.go。六、注册表与 DTO以客户端表为后端的 UUID 优先抽象6.1 客户端注册表是唯一正解Registry接口internal/service/cluster/registry/registry.go定义在 Portal 的auth_clients表之上方法与文档完全对应Get/FindByNodeUUID——UUID 优先节点主标识FindByClientID—— 客户端标识查找FindByName—— DNS label 语义查找同名取最新更新RotateSecret/RotateSecretByClientID—— 按 UUID 或 ClientID 轮换DeleteAllByUUID—— 清理共享 UUID 的全部记录。必须使用NewClientRegistryWithConfigclient-backed文件版注册表仅作遗留兼容。注册表实现位于 internal/service/cluster/registry/client.go其Put方法按NodeUUID → ClientID → Name的顺序解析记录若 UUID 与 ClientID 指向不同记录返回ErrIdentifierMismatch保证一次写入只作用于单条注册。GetClusterNodeByUUID(uuid, opts)返回按NodeOpts脱敏后的cluster.NodeDTO由 HTTP 处理器配合NodeOptsForSession控制暴露范围见 internal/service/cluster/registry/response.go。6.2 DTO 脱敏规则NodeOptsForSession的判定是文档「Admin responses may includeAdvertiseUrl/Database; client/user sessions stay redacted」的源码依据会话类型ClientIDAdvertiseUrlDatabase组访问规则Admin 会话✔✔✔✔客户端 / 用户会话✘✘✘✘SiteUrl对所有角色都安全可见客户端配置中还包含storageNamespaceSiteUrl的 SHA-256 派生值用于浏览器端存储的空间隔离。6.3 节点注册文件的落盘注册表文件存放在conf.PortalConfigPath()/nodes/下文件权限为0600fs.ModeSecretFile。PortalConfigPath定义在 internal/config/config_cluster.go即config/portal/目录。join token 默认落在config/portal/secrets/join_token节点客户端 secret 默认落在config/node/secrets/client_secret两者均支持*_FILE环境变量覆盖路径。七、Provisioner 与 DSN数据库凭据的确定性生成7.1 HMAC 命名的确定性internal/service/cluster/provisioner/naming.go 的GenerateCredentials说明数据库与用户名如何生成数据库名prefixdhmac11 默认 prefix cluster_ 用户名 prefixuhmac11 密码 rnd.Base62(32)随机其中hmac11是 HMAC-SHA256 摘要经 Base32无填充编码后截取 11 个字符密钥为db-name:clusterUUID/db-user:clusterUUID数据为 nodeUUID。因此命名对给定的 (clusterUUID, nodeUUID) 是确定性的——集群 UUID 或节点 UUID 变化时名称才会变化。前缀可被PHOTOPRISM_DATABASE_PROVISION_PREFIX覆盖最长 20 字符DatabaseProvisionPrefixMaxLen保证用户名不超过 MySQL 的 32 字符预算、库名不超过 64 字符。7.2 BuildDSN 的驱动回退BuildDSN(driver, host, port, user, pass, name)internal/service/cluster/provisioner/naming.go目前只支持mysql/mariadb其他驱动会打印警告并回退到 MySQL DSN 格式。因此若要支持 Postgres需要同时扩展BuildDSN与provisioner.DatabaseDriver的处理逻辑补充相应校验并在 API 与 CLI 输出中一致地返回driverpostgres当前接入 Postgres 节点的行为是不确定的会走警告回退路径生产使用请以 MySQL/MariaDB 为准。八、会话构造与 API 测试模式对于集群 API 的测试与集成文档给出了三种会话构造方式全部可以在源码中找到对应实现1. Admin 会话全量视图token : AuthenticateAdmin(app, router)AuthenticateAdmin实现在 internal/api/api_test.go内部以admin/photoprism调用AuthenticateUser。2. 用户会话非管理员创建一个非 admin 测试用户role guest设置密码然后token : AuthenticateUser(app, router, guest, password)3. 客户端会话内部字段脱敏SiteUrl可见s, _ : entity.AddClientSession(test-client, conf.SessionMaxAge(), cluster, authn.GrantClientCredentials, nil) token : s.AuthToken() r : AuthenticatedRequest(app, http.MethodGet, /api/v1/cluster/nodes, token)AddClientSession的 grant 类型为authn.GrantClientCredentials与真实节点换发 access token 的路径一致参见 internal/api/api_auth_test.go 对客户端凭据会话的断言此类会话IsApplication()为 false。测试应断言admin 会话能看到AdvertiseUrl与Database客户端/用户会话看不到SiteUrl与storageNamespace对所有角色可见。九、Preflight 检查清单对集群相关改动合并前文档要求跑通以下检查且均为本仓库实际可执行的命令# 1. 全量编译 go build ./... # 2. 格式化与 Swagger 文档重新生成 make fmt-go swag-fmt swag # 3. 注册表包测试 go test ./internal/service/cluster/registry -count1 # 4. 集群相关 API 测试Cluster 前缀 go test ./internal/api -run Cluster -count1 # 5. 集群相关 CLI 测试注册与轮换 go test ./internal/commands -run ClusterRegister|ClusterNodesRotate -count1两个注意事项make swag可能触发模块下载go mod fetch执行前先确认网络可达-count1用于关闭测试缓存确保每次都是真实执行而非复用上次结果。十、常见运维问答速查Q1节点重启后未使用 join token 就完成了注册为什么因为节点已持久化NodeClientID/NodeClientSecret见 internal/config/config_cluster.go引导时registerAuthToken优先用客户端凭据换发 access tokenjoin token 仅作为首次加入或凭据缺失时的回退。Q2secret 文件不可写时轮换会发生什么轮换后的值缓存在内存中当前进程继续工作SaveNodeClientSecret的降级路径但重启后内存值丢失节点需重新通过注册流程获取新 secret。日志会以 info 级别记录刷新事件。Q3为什么SiteUrl允许 HTTP 而普通站点不允许SiteUrl的 HTTP 只放行 loopbacklocalhost、127.0.0.1、::1与集群内部服务域*.svc、*.cluster.local、*.internal这是为集群内流量保留的受控例外其余场景强制 HTTPS。Q4cluster nodes rm默认删除与--all-ids有何区别默认删除该 UUID 对应的最新一条记录软删除标识符仍被保留--all-ids删除共享同一 UUID 的全部重复记录用于管理员清理异常重复的 client 行--purge则永久删除并释放 UUID 供复用。Q5哪些响应可能携带明文ClientSecret只有两条路径新节点创建时的注册响应Secrets.ClientSecret以及显式--rotate-secret轮换后的响应。其余任何列表、详情、会话响应都经过 DTO 脱敏。本文所有结论均可在仓库源码中复核引导与主题同步见 internal/service/cluster/node/bootstrap.go注册端点见 internal/api/cluster_nodes_register.go注册表实现见 internal/service/cluster/registry/client.go凭据命名见 internal/service/cluster/provisioner/naming.goCLI 命令见 internal/commands/cluster_nodes_rotate.go 与 internal/commands/cluster_nodes_remove.go。需要接入或扩展集群功能如新增数据库驱动时请严格遵循本文的轮换语义、脱敏边界与检查清单确保改动与现有认证模型保持一致。赞分享后端前端图像处理人工智能AI 应用【免费下载链接】photoprismAI-Powered Photos App ✨项目地址https://gitcode.com/gh_mirrors/ph/photoprism点击查看免费下载相关推荐kOps 集群密钥与凭据轮换实战指南keypair 优雅轮换与 Secret 更新全流程kOps 集群密钥与凭据轮换实战指南keypair 优雅轮换与 Secret 更新全流程 本指南以 kOpsKubernetes Operations中云原生集群管理运维IaCOneUptime 运行手册凭据Runbook Credentials实战指南让 Runner 安全触达 SSH 主机与 Kubernetes 集群OneUptime 运行手册凭据Runbook Credentials实战指南让 Runner 安全触达 SSH 主机与 Kubernetes 集群 本文可观测性后端运维前端云原生微服务AI Agent视频号视频、音乐、m3u8 保存到本地res-downloader 资源下载完整指南视频号视频、音乐、m3u8 保存到本地res downloader 资源下载完整指南 想把看过的内容和买过的音乐存到本地res downloader 是一款桌面应用网络音视频上一篇免费在线三国杀卡牌制作器 Lyciumaker 全记录一张专属武将卡的诞生之路下一篇Claude SEO 隐私与数据安全实践指南本地优先的 SEO 审计工作流如何界定数据边界创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

OpenCore Legacy Patcher:Intel 老 Mac 安装 macOS Big Sur 到 Sequoia 的全流程

OpenCore Legacy Patcher:Intel 老 Mac 安装 macOS Big Sur 到 Sequoia 的全流程

OpenCore Legacy Patcher:Intel 老 Mac 安装 macOS Big Sur 到 Sequoia 的全流程 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher macOS Big Sur 及…

2026/10/1 2:30:58 阅读更多 →
Fira Code Nerd Font SemiBold 实战指南:NF/NFM/NFP 变体选择、连字保留与 font-patcher 定制打补丁

Fira Code Nerd Font SemiBold 实战指南:NF/NFM/NFP 变体选择、连字保留与 font-patcher 定制打补丁

开发工具CLI 【免费下载链接】nerd-fonts Iconic font aggregator, collection, & patcher. 3,600 icons, 50 patched fonts: Hack, Source Code Pro, more. Glyph collections: Font Awesome, Material Design Icons, Octicons, & more 项目地址: https://…

2026/10/1 2:32:56 阅读更多 →
FreeRTOS任务设计本质:确定性调度而非多线程

FreeRTOS任务设计本质:确定性调度而非多线程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 4:46:41 阅读更多 →

最新新闻

OpenAI Agents SDK生产环境实战:从执行循环到多Agent编排

OpenAI Agents SDK生产环境实战:从执行循环到多Agent编排

先说明一点:这个系列走到第四篇,我不打算再花篇幅重复“什么是 Agent”“怎么装 SDK”这些基础内容了。前三篇已经覆盖了从环境搭建、单个 Agent 的定义、工具调用,到基本的多 Agent 协作,如果你还没读过前面那些,建议…

2026/10/1 4:50:12 阅读更多 →
LLM Agent记忆优化:hindsight事后提炼与MCP集成实践

LLM Agent记忆优化:hindsight事后提炼与MCP集成实践

1. 从“hindsight”这个词说起:为什么它值得单独拿出来做一篇文章“hindsight”这个词本身的意思很简单——事后的聪明、后见之明。但把它放到 LLM Agent 的技术语境里,它指向的东西就具体多了:Agent 在完成一轮任务之后,回过头去…

2026/10/1 4:50:12 阅读更多 →
应急物资管理系统实战:SpringBoot+Vue全栈开发避坑指南

应急物资管理系统实战:SpringBoot+Vue全栈开发避坑指南

刚接手一个应急物资管理系统项目时,我第一反应是这东西看似简单——无非就是物资出入库、库存台账、预警提醒,但真把需求聊细了才发现,背后牵扯到批次管理、有效期校验、多角色审批、多仓库调拨,还有应急场景下"物资必须找得…

2026/10/1 4:50:12 阅读更多 →
综合能源系统优化:需求响应与碳交易耦合建模全解析

综合能源系统优化:需求响应与碳交易耦合建模全解析

近年来做园区级能源规划,一个明显的变化是:业主不再只问“电够不够、气贵不贵”,而是开始追问“能不能少买碳配额”“负荷能不能跟着现货价格走”。这种问题背后,恰恰是综合能源系统从理论走向落地的分水岭——当多能互补、需求响…

2026/10/1 4:50:12 阅读更多 →
大模型模型中立架构实战:接口抽象与baseUrl路由实现多模型无缝切换

大模型模型中立架构实战:接口抽象与baseUrl路由实现多模型无缝切换

1. 为什么“模型中立”不是架构洁癖,而是生存刚需我见过太多团队在项目初期随手选了一个大模型,把调用代码硬编码在业务逻辑的各个角落,半年后想换模型时发现牵一发动全身,改一处崩三处。这不是危言耸听,而是过去两年我…

2026/10/1 4:50:12 阅读更多 →
基于SpringBoot+Vue+MyBatis+MySQL的服装生产管理系统

基于SpringBoot+Vue+MyBatis+MySQL的服装生产管理系统

前阵子整理了一套基于SpringBootVue的服装生产管理系统源码,春节前刚好利用这套骨架给一家做针织衫的中小型服装厂做过信息化改造摸底。整套系统跑下来,我觉得它特别适合两类人:一类是刚入行Java后端、想找一个能完整跑通的实战项目练手的朋友…

2026/10/1 4:49:12 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →