Docker容器化实战:用NodeJS构建镜像并部署运行

Docker刚出来那两年,很多人觉得它是“运维才需要玩的东西”,搞业务开发的碰都不碰。但只要你试过在一台新电脑上把NodeJS项目跑起来,装完Node、再配环境变量、再发现版本不对、再发现某个原生依赖编译失败……折腾一个下午之后,你会无比渴望有一个东西能把这些破事全部打包隔离。Docker就是干这个的。

这篇内容不搞那种很玄的理论轰炸,而是从一个实际需求出发:给你一个NodeJS程序,我们从零开始装Docker、写镜像配置、构建镜像、把程序跑起来。整个过程我尽量按照实际操作的时间顺序来讲,什么地方容易踩坑、什么地方可以偷懒,我都会指出来。这套流程你要是走通了,后面玩转数据库、Redis、Nginx这些容器化部署,基本都是一通百通。

1. 动手之前:先别急着敲命令,把三个核心概念搞清楚

很多人学Docker失败,不是命令敲得少,而是对着教程复制粘贴了半天,完全不知道自己在干什么。所以哪怕你是急着上手的性子,我也建议你先用五分钟把下面几件事捋明白,这比多敲十遍命令都管用。

1.1 镜像和容器:一个像“安装包”,一个像“运行中的程序”

这个概念我每次都会用生活里的例子来讲。你把镜像理解成手机里的“安装包”,容器就是“已经安装好并且正在运行的App”。安装包是静态的,躺在那里不能干活;容器是动态的,它跑起来了,占资源,会出日志,可以被停止、删除。

所以整个Docker的工作流就是:先准备好一个镜像,然后基于这个镜像去创建并运行容器。我们要做的NodeJS程序,最终跑起来的时候,就是以“容器”的形式存在的。这个理解一旦建立,后面看到docker run就不会懵了——它的意思其实就是“基于某个安装包,把App启动起来”。

1.2 镜像的分层结构:为什么Docker能这么省空间

镜像还有一个关键特性,它是一层一层堆叠起来的。每个Dockerfile指令都会生成一个新层,Docker会缓存这些层。这也是为什么你在自己电脑上构建过的镜像,再次构建时会非常快;连同一个基础镜像的多个不同项目,也可以共享底层文件,而不是各存一份。

这对NodeJS项目直接的影响就是:基础镜像的层是共享的,你只需要把项目代码那一层打进去。所以不要动不动就去下载一个几百MB的所谓“全家桶镜像”,尽量选体积小、适合跑生产的基础镜像,比如node:20-alpine。这也是后面实操里我会优先选的类型。

1.3 镜像仓库:Docker世界的“应用商店”

镜像不会凭空产生,你第一步需要一个基础镜像,比如NodeJS官方提供的镜像。这些镜像放在一个叫“镜像仓库”的地方,最知名的是Docker Hub,上面放着海量官方和社区维护的镜像。用docker pull命令可以把远程的镜像拉到本地。

但对于国内环境来说,直接访问Docker Hub有时候会比较慢,这就涉及镜像加速的配置。这是个非常实际的体验问题,我后面会专门讲一下配置方法,免得你卡在第一步。

1.4 用Docker跑NodeJS的完整链路

把概念串起来,我们要做的事就非常清晰了:

  1. 在电脑上安装好Docker环境。
  2. 准备一个最简单的NodeJS程序(含代码和依赖描述文件)。
  3. 编写一个Dockerfile,告诉Docker怎么把我们的程序变成镜像。
  4. 执行docker build构建出项目镜像。
  5. 执行docker run基于镜像启动容器,让NodeJS服务在容器里跑起来。
  6. 通过浏览器或命令访问这个服务,验证整个链路通了。

后面所有内容都是顺着这六步展开的,你心里有一条线,就不容易在细节里迷路。

2. 安装Docker:不同系统上的操作差异

安装Docker本身不复杂,但不同操作系统上的安装方式和后续权限管理不太一样,这里分开说。

2.1 Linux系统上安装(以Ubuntu为例)

Linux下的安装,主流方式是用官方提供的脚本,一条命令搞定:

curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh

这个脚本会自动检测你的发行版,然后把Docker引擎装好。装完之后,Docker是以root权限运行的,所以每次敲docker命令都需要加sudo。为了方便日常操作,你可以把当前用户加入docker组,之后就不用在每条命令前面敲sudo了:

sudo usermod -aG docker $USER newgrp docker

注意这一操作有个安全风险:加入docker组后,你的用户权限几乎等同于root,因为Docker本身可以挂载宿主机目录。自家开发机这么用没问题,公司服务器上要慎重。

提示:装完之后立刻检查一下,执行docker version,看到Client和Server两段都正常输出,说明引擎在运行。如果只有Client有信息、Server报错,多半是Docker守护进程没起来,Linux下用sudo systemctl enable --now docker启动一下。

2.2 macOS和Windows上的安装

macOS和Windows推荐直接安装官方桌面版。这个软件包自带Docker引擎、命令行工具以及一个图形化管理界面,对新手非常友好。

安装过程基本就是一路下一步,但有一个关键前置条件:Windows上必须开启硬件虚拟化(一般BIOS里默认打开),并且需要确保Windows的“虚拟机平台”功能处于启用状态。很多人装完死活启动不了,回头一看就是这一步漏了。macOS相对省心,只要是近几年的机器,直接装就行。

这两个平台的桌面版安装完成后,菜单栏或任务栏会出现一个小鲸鱼图标,点击后看到Engine running就说明环境已经就绪。

2.3 安装后的三个验证动作

不管哪个平台,装完我都建议做一个“最小化验证”,确认环——境是通的:

docker version # 查看客户端和服务端版本 docker info # 查看运行环境详细信息 docker run hello-world # 镜像运行最小化测试

第三条命令会拉取一个官方测试镜像,然后打印一段说明文字。如果这段文字能正常打印出来,说明你拉取镜像、创建容器、运行容器整个链路都没有问题。很多人直接跳过这个测试开始搞业务,最后遇到问题了才想起来排查环境,反而浪费时间。

我自己的习惯是:装完立刻跑一遍这三条,确认环境的“地基”是稳的,再往上盖楼。

3. 准备一个NodeJS服务并编写Dockerfile

现在进入正题:假设我们要把一个NodeJS HTTP服务打进Docker里。

3.1 先准备一个最简单的NodeJS程序

为了演示,我们写一个极简的HTTP服务。新建一个项目文件夹,比如就叫docker-node-demo,在里面创建app.js:

const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello from Dockerized NodeJS!'); }); app.listen(port, () => { console.log(`App listening at http://localhost:${port}`); });

再创建package.json:

{ "name": "docker-node-demo", "version": "1.0.0", "main": "app.js", "scripts": { "start": "node app.js" }, "dependencies": { "express": "^4.18.2" } }

本地如果没有装NodeJS也没关系,我们最终的目的是让这个程序在Docker容器里运行。但写Dockerfile之前,我建议你至少知道这段代码是干什么用的——它会监听3000端口并返回一行文本。

3.2 Dockerfile逐行拆解

在项目文件夹里新建一个名为Dockerfile的文件(注意没有后缀),内容如下:

FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install --registry=https://registry.npm.taobao.org COPY . . EXPOSE 3000 CMD ["npm", "start"]

一行一行来看。

FROM node:20-alpine:指定基础镜像。20是Node主版本,alpine表示这是一个基于 Alpine Linux 的极简版本,体积要比默认的node:20小很多,下载更快,跑起来也更省内存。如果项目里有用到比较冷门的原生模块,可能需要换回标准版,但绝大多数项目用alpine都没问题。

WORKDIR /app:设置镜像里的工作目录。后面所有相对路径都会基于这个目录。这相当于在容器里创建了一个/app文件夹,并把它作为我们的“项目根目录”。

COPY package*.json ./:先把依赖描述文件复制进去。注意这里复制的是package.json和package-lock.json(如果有)。单独把这两个文件先复制进去是有讲究的——Docker的每一层都有缓存,只要这一层的输入没变,构建时就直接用缓存,不会再执行一次。如果我们在代码改动之后仍然能命中依赖层的缓存,构建速度会快非常多。

RUN npm install --registry=https://registry.npm.taobao.org:在镜像里安装依赖。我特意加了一个 registry 参数,替换成国内可用的npm镜像源,这样下载依赖的速度会有质的飞跃。你自己操作的时候,也可以把这个镜像源地址换成自己用着顺手的。

COPY . .:把整个项目目录里的文件复制进镜像,覆盖到刚才的/app目录下。前面已经单独复制过依赖文件并安装了依赖,这里再把代码复制进去,相当于“代码变、依赖不变”的缓存效果。

EXPOSE 3000:声明容器内服务使用的端口。注意它只是“声明”,并不会真的把端口映射到宿主机。真正让外部访问到服务,需要在docker run时用-p参数做端口映射。

CMD ["npm", "start"]:设置容器启动时默认执行的命令。这里用了数组格式,它直接执行npm这个可执行程序,参数是start。一个镜像只能有一个CMD,谁最后写谁生效。

3.3 .dockerignore:一个很容易被忽略但能救命的文件

如果你的项目里恰好装了node_modules,并且没有.dockerignore文件,那么执行COPY . .时会把本地那一堆依赖包一起塞进镜像里。这不仅让镜像体积膨胀,而且在Linux和Windows的环境差异下,本地node_modules里可能包含不适合容器运行的二进制文件,最终结果就是镜像构建成功,但容器运行时报各种奇怪的错。

解决方案非常简单。在项目里新建一个.dockerignore文件,内容类似这样:

node_modules .git *.log .DS_Store

这样COPY . .时就会自动忽略这些目录。无论是镜像体积还是构建速度,都会明显改善。这一步属于“做一次受益终身”的习惯。

4. 构建镜像、加载并运行容器

到这里,所有准备工作做完了。下面进入真正让Docker“干活”的阶段。

4.1 用docker build构建项目镜像

在项目文件夹里执行:

docker build -t docker-node-demo:v1 .

解释一下参数:

  • -t docker-node-demo:v1:给镜像命名并打标签。docker-node-demo是仓库名,v1是标签,通常用来标识版本。命名和标签可以随便起,最好是语义化,比如myproject:20250101。
  • 最后的.:指定构建上下文路径。这个.代表当前目录,Docker会把当前目录里没有被.dockerignore忽略的文件打包发送给Docker守护进程,作为构建上下文。

第一次构建会拉取NodeJS基础镜像,这时候能明显感觉到网络的影响。如果拉取卡住,大概率是Docker Hub访问慢,建议先配置镜像加速器,然后再试。

构建过程中,你会看到一步步执行FROM、WORKDIR、COPY、RUN、CMD的输出。每一步完成,右上角会出现类似[OK]的提示,表示这一层构建成功。构建完成后,用docker images查看本地镜像列表,能看到刚才构建出来的镜像,通常体积在200MB上下。

4.2 用docker run加载并运行容器

镜像构建好之后,运行容器只需要一条命令:

docker run -d -p 8080:3000 --name my-node-app docker-node-demo:v1

参数拆开看:

  • -d:后台运行容器,不占用当前终端。
  • -p 8080:3000:端口映射。格式是“宿主机端口:容器内端口”。这里的意思是把容器内的3000端口映射到宿主机的8080端口。
  • --name my-node-app:给容器起一个名字,方便后续管理。
  • 最后是镜像名,也就是我们刚构建好的docker-node-demo:v1。

执行完后,用docker ps查看运行中的容器。只要看到my-node-app在列表里,说明容器已经正常起来了。然后在浏览器访问http://localhost:8080,就能看到 “Hello from Dockerized NodeJS!” 这行字。

注意:容器内部的服务监听的是3000端口,也就是我们代码里app.listen(port)的port,这个值没有变。所以-p 8080:3000的右侧要跟代码里监听的端口保持一致。如果把右侧写成了8080,服务在容器里监听3000,映射就失效了。

4.3 查看日志和进入容器排查问题

程序如果在容器里崩了,或者根本没起来,第一件要做的事就是看日志:

docker logs my-node-app

日志里会显示NodeJS进程打出的所有输出,包括我们的App listening at...,以及任何报错信息。如果发现容器没有任何输出,多半是启动命令出了问题,或者npm install阶段就失败了。

有时候,日志看不出明显问题,但你怀疑容器内部环境不对。这时候可以进入容器查看现场:

docker exec -it my-node-app sh

exec是在运行中的容器里再执行一个命令,-it表示用交互式终端操作,sh是启动一个交互式shell。进入容器后,你可以像登录一台服务器一样到处看看,检查文件有没有复制进去、依赖有没有装上、环境变量对不对。

这个实操习惯在排查问题时会帮你节省大量时间。很多新手只会反复改代码重新构建,却不愿意进入容器里看一眼实际状态,结果绕大圈。

5. 常见问题与排查技巧实录

下面这些问题,是我实际带人做的时候遇到的高频问题,整理成速查表会直观一些。

现象常见原因解决思路
构建时拉取基础镜像卡住Docker Hub网络延迟高配置镜像加速器,重试docker build
容器启动后立即退出启动命令报错或进程主动退出执行docker logs查看运行日志
端口访问不通端口映射写错或服务监听地址错误检查-p格式,代码中监听0.0.0.0而非127.0.0.1
npm install 非常慢默认下载源网络慢Dockerfile中指定国内npm镜像源
镜像体积异常大项目依赖被误复制进镜像确认.dockerignore是否生效
docker: permission denied当前用户不在docker组usermod -aG docker $USER后重新登录
构建时能安装依赖,运行时报模块找不到package.json和lock文件不一致删除本地lock后重新build,或确保lock文件被正确复制

5.1 端口冲突怎么办

如果本地的8080端口已经被其他程序占用,运行docker run时会报地址占用错误。两个解决方向:换一个宿主机端口,比如-p 8081:3000;或者先检查并停掉占用端口的进程。我自己更推荐前者,因为更简单,也避免了误杀其他服务的风险。

5.2 镜像构建慢的问题怎么破

构建慢主要分两块:基础镜像下载慢和npm依赖安装慢。前者通过配置镜像加速器解决,后者通过在Dockerfile里指定国内的npm镜像源解决。这两个慢的问题如果不处理,新手很容易以为是自己操作错了,反复重装Docker,实际上跟Docker本身无关。

5.3 容器起来了但访问不到服务

这个问题最隐蔽。很多人按教程把容器跑起来了,docker ps也显示正常,但浏览器访问就是打不开。如果端口映射没有问题,那十有八九是NodeJS服务监听的地址不对。在容器里,代码用app.listen(port)监听,默认是监听所有网络接口的,这没问题;但如果你在代码里显式写了app.listen(port, '127.0.0.1'),那服务只会监听容器内部地址,宿主机代理过来的流量进不来。写NodeJS服务的时候,监听地址不要硬编码成127.0.0.1。

5.4 如何自己排查“莫名挂掉”的容器

容器如果不断重启,你可以先看一眼重启次数:

docker ps -a

看到STATUS列有Restarting字样,说明容器确实在崩溃循环里。这时候不要再反复docker run,先跑docker logs把错误信息拿出来。绝大多数崩溃问题,日志里都会直接写清楚原因,剩下的交给排查思路就行。

6. 把单个容器进阶成“服务编排”:一点经验之谈

如果你把上面的NodeJS服务跑通了,你会发现一个事实:Docker本身并不难,难的是用Docker的时候怎么管理这些容器、网络、存储和依赖关系。一个真实的业务项目,往往不只一个服务:前端、后端、数据库、缓存中间件……它们之间需要相互通信,端口要合理分配,环境变量要集中管理。这时候再用一条条docker run去启动容器,效率太低了,而且特别容易记混参数。

我的建议是,把这篇入门内容做完之后,下一站直接学习docker-compose。你在项目里写一个docker-compose.yml,把所有服务的镜像、端口、环境变量、数据卷都声明好,然后一条docker-compose up -d就把整套环境拉起来。你会在配置里用到一个叫“网络”的东西,服务之间用“服务名”互相访问,不需要再记一堆IP地址。

我个人在实际操作中的体会是:Docker入门阶段的关键不在于命令背得熟,而在于建立“镜像—容器—仓库”“构建—运行—排查”这条完整链路的心智模型。一旦你脑子里有了这条链路,所有新概念都可以挂到熟悉的位置上——数据卷解决持久化、容器编排解决多服务协同、镜像构建优化解决交付效率。慢慢你会发现,Docker不是给运维专用的工具,而是每一个写代码的人都应该具备的基本功。

相关新闻

FPGA上的DPCC动态坏点校正:从Bayer滑窗到商用ISP落地

FPGA上的DPCC动态坏点校正:从Bayer滑窗到商用ISP落地

做ISP的硬件工程师,基本都经历过这样的夜晚:传感器增益一拉高,预览画面里突然浮出密密麻麻的白点,截图放大一看,每个点死死钉在固定坐标上,不闪烁、不漂移。客户第一反应是Sensor坏了,但你把原厂…

2026/10/20 7:25:01 阅读更多 →
MSVC2017编译OSG3.63+osgEarth2.10+Qt5.14环境搭建与避坑指南

MSVC2017编译OSG3.63+osgEarth2.10+Qt5.14环境搭建与避坑指南

简介:本资源面向使用 MSVC2017 进行三维地理可视化开发的 C 工程师与 Qt 桌面应用开发者,提供一套可直接编译运行的 OSG 3.6.3 与 osgEarth 2.10 集成环境,并附带一个简单 Qt 工程示例,帮助读者省去自行编译第三方库的繁琐过程&am…

2026/10/20 7:25:01 阅读更多 →
AI芯片软硬件协同设计:从算力焦虑到性能落地的关键技术与实践

AI芯片软硬件协同设计:从算力焦虑到性能落地的关键技术与实践

1. 从"算力焦虑"说起:为什么AI芯片的软硬件协同设计成了必答题这两年跟做芯片和做算法的朋友聊天,绕不开的一个词就是"算力焦虑"。模型参数从亿级飙到万亿级,训练集群的规模从几百张卡扩到几万张卡,可大家发现…

2026/10/20 7:24:00 阅读更多 →

最新新闻

RAG面试高频考点全解析:从检索到生成的优化链路

RAG面试高频考点全解析:从检索到生成的优化链路

1. 为什么面试官揪着RAG不放:先把这个动机吃透我最近在系统梳理大模型方向的面试题,RAG(Retrieval-Augmented Generation,检索增强生成)几乎是每家必问的模块。尤其是做应用层项目的岗位,RAG的提问密度比微…

2026/10/20 8:14:30 阅读更多 →
机票电商平台重构实战:领域拆分与异步订单链路设计

机票电商平台重构实战:领域拆分与异步订单链路设计

简介:eyoo旅游机票电商平台(重构版)是一份基于Ruby与Rails技术构建的在线机票销售系统项目资源,面向Ruby后端开发者、电商平台学习者以及关注系统重构优化的人群。项目覆盖业务逻辑处理、ActiveRecord数据库操作、RESTful API接口…

2026/10/20 8:14:30 阅读更多 →
Docker容器化实战指南:从DockerFile到Compose编排全解析

Docker容器化实战指南:从DockerFile到Compose编排全解析

1. 先从一张架构图说起:为什么我们绕不开Docker我的个人项目X,从零开始做全栈实践。最初只开了一个云服务器,上面跑着数据库、缓存、定时任务,后来要加前后端服务,每个环境都折腾一遍依赖。结果不到三个月,…

2026/10/20 8:14:30 阅读更多 →
PHP借贷源码拆解与本地部署:从业务闭环到避坑实践

PHP借贷源码拆解与本地部署:从业务闭环到避坑实践

简介:一套基于 PHP 实现的借贷公司/网贷平台整站源码,面向需要快速搭建在线借贷系统的技术团队、中小型网贷项目开发者和 PHP 学习者。源码在得得系统基础上完成改编,并经过实际测试可用,覆盖用户注册、信用评估、借款申请、还款计…

2026/10/20 8:14:30 阅读更多 →
实战推演:用 esp32-iphone-agent 的思路,给自己 iPhone 做个“自动化开关“,可行吗

实战推演:用 esp32-iphone-agent 的思路,给自己 iPhone 做个“自动化开关“,可行吗

实战推演:用 esp32-iphone-agent 的思路,给自己 iPhone 做个"自动化开关",可行吗 【免费下载链接】esp32-iphone-agent Let an AI model use a real iPhone with a $7 ESP32: AirPlay eyes, USB HID hands, any OpenAI-compatible …

2026/10/20 8:14:30 阅读更多 →
Agent上线就崩?从状态管理到可观测性,拆解工程化落地的五大核心难题

Agent上线就崩?从状态管理到可观测性,拆解工程化落地的五大核心难题

1. 演示与上线之间的鸿沟到底在哪做 Agent 项目的人大概都经历过这种场面:内部演示的时候,Agent 流畅地理解需求、调用工具、多步推理、最后给出一个漂亮的答案,会议室里一片掌声。然后老板说“下周上线吧”,结果一上线&#xff0…

2026/10/20 8:13:30 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →