Wing 模拟器中的 sim.Container:从 entrypoint 测试快照看自定义容器启动与底层实现
编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载导读sim.Container是 Wing 标准库中用于在本地模拟器Wing Simulator中运行 Docker 容器的资源它允许开发者在真实的云端部署之前用本地容器完成服务联调与测试。本文以仓库中的 Hangar 测试快照 entrypoint.test.w_test_sim.md 为线索完整拆解sim.Container自定义entrypoint与args的实战写法、全部构造参数、底层docker run命令的生成逻辑、hostPort端口映射原理以及容器的停止与强制清理机制读完即可在自己的 Wing 项目中熟练编排带自定义启动命令的本地容器并理解其运行日志的每一行含义。一、快照文档是什么Hangar 端到端测试的产物tools/hangar/__snapshots__/test_corpus/sdk_tests/container/目录下的快照文件是 Wing 仓库中 Hangar 工具链见 tools/hangar/README.md运行端到端测试后生成的确定性输出。快照目录的定位逻辑定义在 tools/hangar/src/paths.tssnapshotDir path.join(hangarDir, __snapshots__)而测试用例的收集路径定义在 tools/hangar/src/generate_tests.ts。本文的主角entrypoint.test.w_test_sim.md就是测试源文件 tests/sdk_tests/container/entrypoint.test.w 在sim 目标Wing Simulator下执行一次测试后的标准输出快照其内容如下[INFO] container with entrypoint | hello [WARNING] container with entrypoint | Timeout waiting for container root/Default/with-entrypoint to shutdown, removing forcefully pass ─ entrypoint.test.wsim » root/Default/test:container with entrypoint Tests 1 passed (1) Snapshots 1 skipped Test Files 1 passed (1) Duration DURATION这份快照虽然只有十几行却完整记录了一次带自定义 entrypoint 的容器测试从启动、请求到关闭的全过程是理解sim.Container行为最直接的事实依据。二、测试源码剖析自定义 entrypoint 的最小完整示例快照对应的测试源码 entrypoint.test.w 全文如下/*\ skipPlatforms: - win32 - darwin \*/ bring sim; bring http; bring expect; // only relevant in simulator if target sim { let entrypoint new sim.Container( name: my-entrypoint-app, image: ./my-docker-image, containerPort: 3000, args: [-c, RESPONSEhello /usr/local/bin/node /app/index.js], entrypoint: /bin/sh, ) as with-entrypoint; test container with entrypoint { let response http.get(http://localhost:{entrypoint.hostPort!}); log(response.body); expect.equal(hello, response.body); } }这段代码有几个值得注意的关键点skipPlatforms声明该测试明确跳过 win32 与 darwin 平台因为容器资源依赖 Docker 守护进程Linux 是 Wing 模拟器容器测试的标准环境。if target sim条件编译sim.Container仅存在于模拟器目标因此整个资源创建与测试都包裹在目标判断中避免在tf-aws等编译目标下生效。这一点从同名编译快照 entrypoint.test.w_compile_tf-aws.md 可以得到印证——tf-aws 目标下生成的主 Terraform 文件几乎是空的没有任何容器相关资源。自定义entrypoint与argsentrypoint: /bin/sh覆盖了镜像默认的入口程序args: [-c, RESPONSEhello /usr/local/bin/node /app/index.js]则把启动参数传给/bin/sh组合效果等价于在容器内执行RESPONSEhello /usr/local/bin/node /app/index.js——即以环境变量方式注入响应内容并启动 Node 服务。hostPort!非空断言hostPort是 Wing 的 token 属性只有在容器真正启动、端口完成映射后才会解析出宿主机端口测试中通过!断言其已就绪。镜像本身来自本地目录 tests/sdk_tests/container/my-docker-image其中的 Dockerfile 与 index.js 定义了测试服务的真实行为FROM node:20.8.0-alpine EXPOSE 3000 ADD index.js /app/index.js ENTRYPOINT [ /app/index.js ]const response process.env.RESPONSE; const server http.createServer((req, res) { res.end(response ?? Hello, Wingnuts!); }); console.log(listening on port 3000); server.listen(3000);注意index.js中process.env.RESPONSE的读取逻辑默认镜像入口直接运行/app/index.js时响应的是默认值Hello, Wingnuts!而entrypoint.test.w通过把entrypoint换成/bin/sh、用args注入RESPONSEhello环境变量让同一镜像在测试中返回hello。快照第一行[INFO] container with entrypoint | hello正是log(response.body)输出的结果expect.equal(hello, response.body)随之通过测试在末尾打印pass。三、sim.Container 完整 API全部构造参数与默认值sim.Container的构造参数ContainerProps定义于 packages/winglang/sdk/src/target-sim/container.ts官方 API 文档见 docs/api/04-standard-library/sim/container.md。完整参数清单如下参数类型必填默认值说明namestr是无容器名称也参与镜像标签的生成imagestr是无公共 Docker 镜像名拉取运行或本地含Dockerfile的目录路径构建运行containerPortnum否不暴露端口容器内部需要暴露的 TCP 端口设置后才会生成hostPortenvMutMapstr否{}注入容器的环境变量argsMutArraystr否[]传给容器 entrypoint 的参数entrypointstr否镜像默认 entrypoint覆盖容器入口程序volumesMutArraystr否[]卷挂载点如[/host:/container]以/开头且不含:的路径按匿名卷处理networkstr否Docker 默认网络Docker 网络模式如host、bridgesourcePatternstr否构建上下文全部文件计算源码哈希时参与的 glob 模式用于判断是否需要重建镜像sourceHashstr否基于源文件自动计算显式指定代表容器源码的哈希值其中entrypoint与args的语义需要区分entrypoint覆盖的是 Docker 的--entrypoint入口程序本身而args是传给该入口的启动参数。在 Dockerfile 中镜像默认入口是ENTRYPOINT [ /app/index.js ]测试将其替换为/bin/sh后args中的-c RESPONSEhello ...就变成了 shell 执行的命令行。正是二者的组合实现了同一镜像、不同启动方式的灵活性。四、底层原理一条 docker run 命令是如何拼出来的sim.Container在模拟器中运行时的实际载体是 packages/winglang/sdk/src/target-sim/container.inflight.ts 中的Container类。该类的start()方法container.inflight.ts逐段拼接出最终的docker run命令固定参数-i --rm --name wing-ulid其中--rm保证容器退出即被清理容器名以wing-前缀加 ULID 生成以避免冲突网络参数配置了network时追加--networknetworkcontainer.inflight.ts端口映射设置了containerPort时追加-p containerPort由 Docker 自动分配宿主机端口container.inflight.ts环境变量env非空时先写入临时文件再以--env-file方式传入container.inflight.ts 与 createEnvFile卷挂载对volumes逐项追加-vcontainer.inflight.tsentrypoint 覆盖配置了entrypoint时追加--entrypoint 值这正是本次测试的核心参数container.inflight.ts最后是镜像标签与args中的每一个参数container.inflight.ts。于是entrypoint.test.w中的配置最终展开为类似这样的命令docker run -i --rm --name wing-ulid -p 3000 --entrypoint /bin/sh my-entrypoint-app:hash -c RESPONSEhello /usr/local/bin/node /app/index.js镜像标签与构建/拉取分流在预检阶段 packages/winglang/sdk/src/target-sim/container.ts 会根据image是否为本地路径决定镜像标签若image是本地目录如./my-docker-image镜像标签为${name}:${hash}其中hash取自显式传入的sourceHash或由sourcePattern限定范围后对源文件计算 MD5fs.md5(props.image, props.sourcePattern)若image是公共镜像名如hashicorp/http-echo镜像标签直接使用该名称。运行时prepareImage 先尝试docker inspect检查镜像是否已存在已存在则直接复用不存在时本地目录走docker build -t tag dir镜像名走docker pull tag。这意味着本地 Dockerfile 变更会因源码哈希变化而自动触发重建这是sourcePattern/sourceHash参数存在的原因。hostPort 的生成与就绪等待hostPort是资源在预检阶段创建的 token 属性container.ts仅当配置了containerPort时才存在。容器启动后模拟器通过 start() 中的waitUntil循环每 100ms 检查一次容器状态总超时 30 秒见 waitUntil普通网络模式下通过docker inspect读取NetworkSettings.Ports中containerPort/tcp对应的HostPort拿到映射后的宿主机端口使用network: host时宿主机端口与容器端口相同container.inflight.ts这一行为在 network.test.w 中有专门的断言expect.equal(networkHost.hostPort, 5678)。拿到端口后测试中的http.get(http://localhost:{entrypoint.hostPort!})才能命中容器内的 3000 端口服务。容器中途意外退出会抛出 Container stopped unexpectedly 错误。五、容器生命周期与快照中的 WARNING 日志解读快照第二行是[WARNING] container with entrypoint | Timeout waiting for container root/Default/with-entrypoint to shutdown, removing forcefully它来自容器关闭逻辑而不是测试失败——测试本身最终标记为pass。关闭流程在 kill() 中实现模拟器先向 docker 子进程发送SIGTERM优雅退出信号并等待 2 秒若容器在 2 秒内未退出则触发超时分支打印上述 WARNING 日志并执行docker rm -f containerName强制删除container.inflight.ts。这里的root/Default/with-entrypoint是资源在 Wing 应用树中的完整路径with-entrypoint正是源码中as with-entrypoint指定的显示 ID。本测试中的容器以/bin/sh作为入口shell 进程对 SIGTERM 的响应路径导致容器未在 2 秒内完成优雅退出因此出现了强制移除的警告——这是模拟器保证资源及时释放的兜底机制并非错误。相比之下Dockerfile 中的index.js显式注册了 SIGINT 处理process.on(SIGINT, ...)说明对信号响应良好的服务可以更平滑地关闭。六、状态保留与更多实战配置sim.Container还支持跨模拟器重启保留数据。官方文档 container.md 指出关闭 Wing Console 时所有容器都会被停止并移除要让容器状态在重启后保留可以挂载匿名卷new sim.Container( name: my-service, image: ./my-service, containerPort: 8080, volumes: [/var/data], );其实现机制在 container.inflight.ts以/开头且不含:的卷路径被识别为匿名卷Wing 会为它生成wing-volume-ulid的命名卷并通过状态文件state.jsoncontainer.inflight.ts记录路径与卷名的映射下次启动时复用同一命名卷。这一模式在 mount.test.w 中以postgres:15镜像 /var/lib/postgresql/data数据目录的形式给出了实际用例同时展示了env传POSTGRES_PASSWORD的写法。其他相关测试用例还包括container.test.w同时验证公共镜像拉取hashicorp/http-echo与本地目录构建两种模式并分别断言bang\n与Hello, Wingnuts!响应network.test.w验证network: host模式下hostPort直接等于containerPortpull-failure.test.w 与 build-failure.test.w分别用非法镜像协议foo://do-not-pull-me和不存在的构建目录验证失败路径。七、运行与验证方式在仓库环境中这些容器测试属于 Hangar 端到端测试体系按 tools/hangar/README.md 的说明在 Wing 开发流程中执行。直接验证本文示例的方式是确保本机 Linux 环境已安装并运行 Docker 守护进程然后对 entrypoint.test.w 执行wing test并指定sim目标。若输出与 entrypoint.test.w_test_sim.md 快照一致即pass ─ entrypoint.test.wsim » root/Default/test:container with entrypoint、Tests 1 passed (1)则说明自定义entrypointargs的容器编排正确生效。需要说明的是sim.Container是模拟器专属资源对应winglang/sdk.sim.Container不参与tf-aws等云端目标的资源生成因此这类容器编排通常用于本地开发联调与回归测试云端部署仍需借助平台提供的容器工作负载能力。赞分享编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载相关推荐Wing 容器 Entrypoint 快照测试解析从 sim.Container 参数到 tf-aws 编译产物Wing 容器 Entrypoint 快照测试解析从 sim.Container 参数到 tf aws 编译产物 导读 本文围绕 Wing 仓库中 hanga编程语言编译器云原生语言运行时Wing 模拟器容器测试全解从 sim.Container 到 hangar 快照的端到端验证Wing 模拟器容器测试全解从 sim.Container 到 hangar 快照的端到端验证 本文围绕 Wing 仓库中 sim.Container 资源在编程语言编译器云原生语言运行时Wing 容器资源深度解析从 hangar 编译快照看 sim.Container 在 tf-aws 与模拟器目标下的行为Wing 容器资源深度解析从 hangar 编译快照看 sim.Container 在 tf aws 与模拟器目标下的行为 本文以仓库 tools/hanga编程语言编译器云原生语言运行时上一篇fre:ac免费音频转换器跨平台终极指南与实用教程下一篇Taro Runner 公用工具函数解析tarojs/runner-utils 的 Sass 注入、多端文件解析与 Vite 编译上下文创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

JDK 11.0.15 Linux部署指南:TLS 1.3与GC调优实战

JDK 11.0.15 Linux部署指南:TLS 1.3与GC调优实战

简介:本资源为Linux平台下Java 11.0.15正式版JDK标准发行包(jdk-11.0.15_linux-x64_bin.tar.gz),面向Java初学者、Linux服务器开发者及需要稳定LTS版本JDK的生产环境部署人员,解决跨平台开发、服务端编译运行及JVM调优…

2026/10/14 20:53:22 阅读更多 →
Dubbo服务注册与暴露全流程解析:从Spring容器启动到注册中心

Dubbo服务注册与暴露全流程解析:从Spring容器启动到注册中心

1. 从一次线上故障说起&#xff1a;为什么要搞清楚服务注册与暴露很多同学用 Dubbo 做微服务&#xff0c;配置文件里写个<dubbo:service>或者加个DubboService注解&#xff0c;服务就能被调用了&#xff0c;至于背后发生了什么&#xff0c;基本靠“框架自动搞定”这句话糊…

2026/10/14 20:52:20 阅读更多 →
从零搭建私有文档问答:向量检索与RAG实战指南

从零搭建私有文档问答:向量检索与RAG实战指南

1. 从零搭建私有文档问答&#xff1a;为什么向量检索是绕不开的那道坎很多人第一次接触大模型应用&#xff0c;脑子里想的都是"我把文档丢给模型&#xff0c;它就能回答我的问题"。真动手才发现&#xff0c;模型根本读不到你的私有文档——它只认训练时见过的东西。于…

2026/10/14 20:52:20 阅读更多 →

最新新闻

AI Agent实战指南:从架构设计到工程落地的核心要点

AI Agent实战指南:从架构设计到工程落地的核心要点

1. 从"会聊天的模型"到"能办事的Agent"&#xff1a;认知先对齐很多人第一次接触 AI Agent&#xff0c;脑子里浮现的还是那个对话框——你问一句&#xff0c;它答一句&#xff0c;答完就结束。但如果你真拿这种心态去搭 Agent&#xff0c;大概率会在第三天就…

2026/10/14 21:43:45 阅读更多 →
iOS社交应用如何通过App Store 4.3审核:从被拒原因到差异化避坑指南

iOS社交应用如何通过App Store 4.3审核:从被拒原因到差异化避坑指南

"4.3被拒了&#xff0c;App Store审核组说我的应用与其他应用存在大量雷同&#xff0c;属于垃圾应用。"这句话我今年已经听不止一个人说过了。社交应用是4.3的重灾区&#xff0c;不管你做的是兴趣社区、同城交友、泛娱乐聊天室还是垂直圈层App&#xff0c;只要你提交…

2026/10/14 21:43:45 阅读更多 →
HDFS架构原理与运维实战:从副本机制到Shell命令避坑指南

HDFS架构原理与运维实战:从副本机制到Shell命令避坑指南

HDFS这玩意儿在圈子里算得上"老贵族"了——平时不显山露水&#xff0c;但整个大数据生态的数据底座都压在它身上。不管是离线数仓的日分区清洗&#xff0c;还是实时链路落地的中间结果&#xff0c;最终都要老老实实落到HDFS的块上。这篇不聊教科书里那些干巴巴的定义…

2026/10/14 21:43:45 阅读更多 →
蓝桥杯省赛冲刺:一天掌握模拟、set与map的实战技巧

蓝桥杯省赛冲刺:一天掌握模拟、set与map的实战技巧

1. 写在最前面&#xff1a;这24小时到底该怎么用作为一个参加过好几届蓝桥杯、也带过不少学弟学妹临时抱佛脚的人&#xff0c;我先说句实话&#xff1a;如果你只剩一天&#xff0c;别指望学会所有的算法&#xff0c;但一定要把"模拟、set、map"这三个词焊死在脑子里。…

2026/10/14 21:43:45 阅读更多 →
TypeScript运行时校验实战:用impeccable给数据加一道保险

TypeScript运行时校验实战:用impeccable给数据加一道保险

上个月我负责的一个小工具上线没几天&#xff0c;就有用户反馈说页面打开是空白的。控制台报错指向Cannot read properties of undefined (reading name)&#xff0c;追到根因后我发现&#xff1a;后端悄悄改了接口字段&#xff0c;而 TypeScript 的编译期检查在这里完全失效。…

2026/10/14 21:43:45 阅读更多 →
Android项目结构详解:从Gradle构建到App启动的完整认知

Android项目结构详解:从Gradle构建到App启动的完整认知

第一次用IDE创建Android项目时&#xff0c;我对着自动生成的一堆文件夹发了好一会儿呆。明明只想写一个“你好&#xff0c;世界”&#xff0c;可工程里却躺着settings.gradle、build.gradle、gradlew、local.properties&#xff0c;还有一个看起来很重要又不敢随便动的MainActi…

2026/10/14 21:42:43 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起&#xff1a;它到底想解决什么问题第一次看到"AnyPS5"这个标题&#xff0c;我脑子里冒出来的第一个念头是&#xff1a;这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述&#xff1a;Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师&#xff0c;我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性&#xff0c;实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景&#xff0c;也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间&#xff0c;确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中&#xff0c;这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →