首页 文章 精选 留言 我的

精选列表

搜索[全栈],共10004篇文章
优秀的个人博客,低调大师

基于阿里的Node全栈之路(六)专有网络VPC的应用

本来打算继续讲讲前后端分离的,但是因为我准备的自开发的博客还没做好,所以还是放到后面几篇文章上好了。 这一篇文章,主要想介绍一下一种网络安全的应用。我也希望有高人能一起交流下这种方式的弱点。 如果用过阿里云容器服务的同学应该都知道,容器的载体还是用镜像生成的的服务器,而这些镜像是阿里自己搞的,所以会有所滞后,所以很多时候,会遇到像图中这种情况,而这些漏洞的升级,又逼得你不得不天天维护,因为这种漏洞出现的概率好高。 我们除了天天去检查漏洞外,还有没有其它的办法能够去处理这些问题呢?做个检查漏洞的,一有漏洞自动补全?那不是和阿里要做的这个东西一样吗?购买阿里的服务吧,我作为一个个人开发者,那是能省就省的,而且,我认为最好的防御就是不被发现。 经历过负载均衡和OSS这些阿里云实用的功能后。我觉得在阿里云,应该是要能够找到解决的办法的,在经过一段时间的研究,我的新的方案出来了,其实很简单,就是隔离一切! 这里对专有网络隔离的原理进行一些简单解释,简单的说,阿里云docker专有在创建服务器和维护的时候,打开docker访问外网的接口,同时也只是通过代理的方式进行访问,在不需要外网的环境下,关闭外网,这样极大的提高了安全性。 还是和以前一样的,在开始介绍这种方案之前,我们做个前期的准备工作,这里用到的技术: 专有网络: 顾名思义,就是局域网,外部完全不能访问这个网络。 弹性公网IP: 也就是购买一个公网IP,可以挂载在想要访问网络的ECS上。 提醒: 阿里云容器服务没有完全支持专有网络,这点阿里云上也有说明(见下图),当你的容器完全创建在专有网络的时候,如果不能访问外网,一些阿里云和外部工具在docker初始化的时候会不被安装。所以这里要提醒大家,创建专有网络下的容器前,先部署好专有网络的环境。 步骤: 购买不带公网IP的ECS。购买可配置公网EIP,并绑定到该ECS上。(端口专有网络连接公网的时候,只需要解绑公网EIP就可以了) 创建专有网络 创建交换机 按照阿里云的VPC通过有公网IP的ECS访问外网的配置文档,进行配置,得到如下结果。 基于此专有网络,购买容器所需要的ECS,并不配置公网IP,或者直接在容器服务内创建ECS,并选择不保留公网EIP。 创建集群,此时因为专有网络可以通过上述绑定好公网EIP访问外网,所以创建的集群成功,如果创建集群后,集群管理节点失败,或者阿里云的监控安装失败,都是因为专有网络无法访问外网导致,这时,需要查看专有网络是否不能访问外网。

优秀的个人博客,低调大师

Docker Compose本地开发全栈:前端+后端+向量库一键启动

**📰 科技要**闻 • 腾讯云在WAIC 2026发布ADP 4.0海外版,企业级智能体开发平台正式出海,同步升级Claw模式和Skill广场。 • WAIC 2026全面探展:从烤披萨到拿快递,具身智能机器人开始走进真实生活场景,落地速度明显加快。 • 英特尔与Google Cloud深化战略合作,阿里1688同期公布AI时代B2B交易互联互通开放标准。 上周组里来了个新人,第一天入职给他配环境,从拉代码到能跑起来问答,花了他整整一天。他中间发我截图,Milvus起不来,ES连不上,前端报了个CORS错误,追根溯源发现是他本地Redis版本装的是7.0,我们线上用的是7.2的一个新特性。我看着这些错误突然意识到——**这半年我们一路给系统加组件、加服务,却从来没认真想过"怎么让人在十分钟内跑起来完整系统"这件事**。之前都是老人带新人口传心授,一份"环境搭建手册"改了又改,永远追不上服务的变化速度。这篇就是把这个坑填上:用Docker Compose把Next.js前端、FastAPI后端、Milvus、ES、Redis全部串起来,一条命令拉起整个知识库系统。 **一、先别急着写compose文件:想清楚依赖顺序图** 我第一版compose文件是照着服务列表一个个抄的,抄完直接`docker compose up`,结果后端疯狂重启——它在Milvus还没初始化完成的时候就去连接,连接失败直接崩,Compose的重启策略又把它拉起来重试,形成了一个"看起来在跑但啥也做不成"的死循环。这玩意儿坑了我整整一天,最后才想明白:**写compose文件前,必须先把依赖顺序图画出来**,谁要等谁,等到什么程度算"就绪",这是决定整个方案能不能用的地基。 **基础设施层:Redis / ES / Milvus** ↓ healthcheck通过 **是否健康检查通过?** ↓ **✅ 是 →** FastAPI后端启动,连接基础设施成功 **❌ 否 →** Compose继续等待,不启动依赖方,不进入崩溃重启循环 ↓ **后端 /health 是否200?** ↓ **✅ 是 →** Next.js前端启动,代理转发生效 **❌ 否 →** 前端保持等待态,避免用户看到一堆502错误 这张图看起来简单,但它帮我理清了一个关键问题:**容器"启动了"和"能被依赖"是两件完全不同的事**。Compose默认的`depends_on`只保证启动顺序,不保证服务真正可用——Milvus容器进程起来了,但它内部的元数据存储可能还没初始化完,这中间的时间差正是绝大多数"本地跑不起来"问题的根源。 **二、healthcheck + depends_on condition:把"顺序"变成"真就绪"** 解决上面那个死循环的关键是`depends_on`的`condition: service_healthy`,配合每个服务自己的`healthcheck`定义。这不是什么冷门特性,但很多团队的compose文件里压根没写healthcheck,全靠`sleep 10`硬等,谁的机器慢一点就直接炸: ``` services: redis: image: redis:7.2-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 10elasticsearch: image: >- elasticsearch:8.13.0 environment: - discovery.type=single-node - xpack.security.enabled=false healthcheck: test: >- curl -f http://localhost:9200/_cluster/health || exit 1 interval: 10s timeout: 5s retries: 15milvus: image: >- milvusdb/milvus:v2.4-standalone depends_on: etcd: condition: service_healthy minio: condition: service_healthy healthcheck: test: >- curl -f http://localhost:9091/healthz interval: 10s timeout: 5s retries: 20backend: build: ./backend depends_on: redis: condition: service_healthy elasticsearch: condition: service_healthy milvus: condition: service_healthy healthcheck: test: >- curl -f http://localhost:8000/health interval: 5s timeout: 3s retries: 10frontend: build: ./frontend depends_on: backend: condition: service_healthy ``` 重点说说两个容易踩坑的细节。第一,`retries`要给够——Milvus这种带存储引擎的服务冷启动经常要十几秒到几十秒,如果照搬网上教程写的`retries: 3`,在配置差一点的机器上必然超时失败,你会看到一个"服务明明在正常运行却被判定为unhealthy"的诡异现象。第二,**Milvus本身依赖etcd和minio**,这是个容易被忽略的传递依赖——很多人只给backend配了对Milvus的healthy依赖,却没意识到Milvus启动过程中如果etcd没就绪,它自己也会反复重启,表现出来的症状跟"Milvus慢"一模一样,排查方向直接错了。 这几年Docker Compose自身也在进化,v2版本已经内置在Docker CLI里(`docker compose`而不是`docker-compose`),不再需要单独装Python版本的compose,团队里还有人用老命令的记得提醒一下,行为细节上有些差异,最典型的就是环境变量插值的规则变严格了。 **三、多环境配置:一份基础文件,三份覆盖文件** 我们最开始只有一份`docker-compose.yml`,本地开发和CI测试环境的差异全靠改环境变量硬凑,结果就是本地能跑,CI跑不起来,排查半天发现是CI机器内存小,Milvus给的默认配置直接把容器OOM杀了。后来改成基础文件+覆盖文件的模式,这是Compose官方推荐但很多人没用起来的能力: ``` # docker-compose.yml # 只写共性配置:image、network、 # 基础环境变量# docker-compose.dev.yml # 覆盖:挂载源码volume、 # 打开debug端口、加watchfiles# docker-compose.ci.yml # 覆盖:限制资源上限、 # 关闭healthcheck重试等待、 # 用最小内存参数跑Milvus# 本地开发启动: docker compose \ -f docker-compose.yml \ -f docker-compose.dev.yml \ up# CI流水线启动: docker compose \ -f docker-compose.yml \ -f docker-compose.ci.yml \ up -d ``` 这个设计的好处是**共性配置只维护一份,环境差异清晰可见**。之前那次CI内存OOM的问题,加一份ci覆盖文件,给Milvus的`deploy.resources.limits`降到512M,配合它自带的`MILVUS_QUOTA_AND_LIMITS`相关环境变量收紧内存用量,CI就稳定跑起来了,完全不用碰基础文件。团队里谁想加一个新环境(比如"演示环境用固定端口方便截图"),也只需要加一份覆盖文件,不会污染主配置。 **四、热重载:volume挂载+watchfiles,代码改完立刻生效** 环境能起来只是第一步,本地开发的效率还取决于"改代码要不要重启容器"。我们最早的做法很粗暴——每次改后端代码都要重新build镜像,一次build三四十秒,一天下来光等待就浪费不少时间。后来分两块解决:前端用Next.js自带的dev server配合volume挂载天然支持热重载,后端用`watchfiles`驱动uvicorn的reload。 ``` # docker-compose.dev.yml 片段 services: backend: volumes: - ./backend/app:/app/app - ./backend/tests:/app/tests command: >- uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /app/app environment: - WATCHFILES_FORCE_POLLING=truefrontend: volumes: - ./frontend/src:/app/src - ./frontend/public:/app/public # 排除node_modules,避免容器 # 内外依赖互相覆盖冲突 - /app/node_modules command: npm run dev ``` 这里有两个我踩过的坑值得单独说。第一是`WATCHFILES_FORCE_POLLING`,如果不开这个,在macOS上用Docker Desktop挂载volume,inotify的文件变更事件经常传不进容器(跟Docker Desktop的osxfs/gRPC-FUSE文件系统实现有关),代码改了容器里没反应,这个问题排查起来极其反直觉——你看着文件明明改了,reload就是不触发。第二是前端那行`/app/node_modules`匿名volume,作用是"排除"这个目录不被本地挂载覆盖,让容器内自己安装的依赖生效,不然本地如果没装依赖或者系统不一致(比如本地是macOS装的依赖,容器是Linux),会直接报一堆原生模块不兼容的错误。这行代码看起来莫名其妙,但少了它新人环境十有八九会炸。 **五、数据持久化与seed数据:新人环境要"自带数据"** 环境跑起来了,但一个空的知识库对新人调试毫无意义——他没法验证检索效果,也没法复现线上的bug。我们加了一个init容器,专门负责首次启动时导入seed数据: ``` services: seed-loader: build: ./scripts/seed depends_on: milvus: condition: service_healthy elasticsearch: condition: service_healthy volumes: - ./scripts/seed/data:/data:ro # 用一个标记文件避免重复导入 - seed_marker:/marker command: >- sh -c " test -f /marker/done || (python load_seed.py && touch /marker/done) " restart: "no"volumes: milvus_data: es_data: seed_marker: ``` 这里的关键设计是`seed_marker`这个标记volume——第一次`up`会执行导入,之后每次重启不会重复灌数据,也不会覆盖开发过程中新增的测试数据。`restart: "no"`也是有意为之,这个容器执行完就该退出,不应该被Compose的默认重启策略反复拉起。团队约定是每次seed数据结构有大改动(比如新增了字段),就删掉标记volume强制重跑:`docker compose down -v && docker compose up`,这一条命令写进了README的显眼位置,省了不少"我数据是不是脏了"的排查时间。 **六、日志聚合:docker compose logs不够用,加一层过滤** 本地跑五六个服务,出问题的时候`docker compose logs`会把所有服务的日志混在一起刷屏,肉眼很难定位。我们没有引入什么复杂的日志系统(本地开发犯不上上ELK),而是靠两个简单的约定解决了大部分问题。 第一是所有服务统一输出结构化JSON日志,哪怕是本地开发也不例外,这样可以用`jq`直接过滤: ``` # 只看backend服务里的ERROR级别日志 docker compose logs -f backend \ | jq -R 'fromjson? | select(.level=="ERROR")'# 按traceId串起某一次请求 # 跨越的所有服务日志 docker compose logs \ | grep "trace_id=8f2a91" ``` 第二是给每个服务在compose文件里配上`logging.driver: json-file`并限制大小,避免本地磁盘被日志撑爆——这个坑我们真的踩过,有次组里同事的电脑跑了两周没重启环境,Milvus日志把磁盘写到报警,查了半天才发现根源是日志没做滚动: ``` x-logging: &default-logging driver: json-file options: max-size: "10m" max-file: "3"services: backend: logging: *default-logging milvus: logging: *default-logging ``` 这里用了YAML的锚点语法`&default-logging`和`*default-logging`,避免每个服务都重复写一遍相同的配置。说实话,我最开始也不觉得这种小地方有必要抠,但compose文件写到十几个服务之后,重复配置的维护成本会突然显现——改一个参数要在八个地方同步改,漏改一个就是下次排障的隐患。 **七、从Compose到生产:别指望无缝,但可以少走弯路** 这半年经常有人问"Docker Compose能不能直接用来做生产部署",我的判断很明确:**不能,也不该硬凑**。Compose是单机编排工具,没有跨节点调度、没有自动扩缩容、没有滚动发布这些生产级能力,这些活儿还是要交给Kubernetes(我们系列的第18篇会详细讲)。但这不代表Compose和K8s之间是两套毫无关联的世界,我们摸索出几条能实际降低迁移成本的经验。 第一,本地compose文件里的服务边界,最好跟未来K8s里的Deployment/Service边界保持一致——如果本地把两个逻辑上独立的服务塞进一个容器"图省事",迁移到K8s拆分成两个Pod的时候,代码里那些写死的"同容器内直连"的逻辑全部要推翻重写。第二,环境变量的命名和读取方式尽量遵循12-factor原则,本地用`.env`文件,生产用K8s的ConfigMap/Secret,只要变量名和读取逻辑一致,切换配置源基本零成本。第三,healthcheck的检查逻辑最好直接复用——我们本地compose里写的`/health`接口,原封不动搬进K8s的livenessProbe/readinessProbe,不需要为两套环境维护两套健康检查逻辑。 这一篇解决的是团队协作里最容易被忽视的一块——不是模型效果好不好,是"新人能不能十分钟内跑起来项目"这个看起来不起眼但天天在消耗团队时间的问题。上线这套compose配置之后,我们统计过,新人从拿到代码到能跑通一次完整问答的时间,从平均一天压缩到十几分钟。下一篇打算往多Agent协作的方向走——现在这套系统里已经不止一个Agent在跑,Supervisor怎么分发任务、Router怎么判断走哪条路、Handoff怎么在多个Agent之间平滑交接,这些模式设计得不好,比单Agent的问题还难排查。到时候见。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册