尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
给仓库写个 cloudinabottle.toml:Cloud in a Bottle 应用开发完整教程
【免费下载链接】cloud-in-a-bottleDeploy, use, and share web apps on a server you control. Your apps, data, and infrastructure stay yours.项目地址https://gitcode.com/gh_mirrors/cl/cloud-in-a-bottle点击查看免费下载Cloud in a Bottle 是一个自托管的 Web 应用托管平台你在自己的服务器或本地虚拟机上部署它随后像给手机装 App 一样把任何带 Dockerfile 的 Git 仓库变成拥有独立子域名、HTTPS 证书和权限管理的在线应用。这篇文章只讲一件事如何给你的仓库写一个cloudinabottle.toml应用清单让平台一键完成构建、部署和路由。一、先花 2 分钟看懂 Cloud in a Bottle 的运作方式在动手写清单之前先建立一个整体印象。一个 Cloud in a Bottle 实例就是一台机器上一个路由器服务router它是整个实例的控制平面详见 docs/src/how_it_works/overview.md从 Git 仓库安装应用你在仪表盘点 Deploy New App填入仓库地址平台读取cloudinabottle.toml用 rootless Podman 构建你的 Dockerfile自动启动容器每个应用一个子域名名为notes的应用就运行在https://notes.yourdomain.com/通配符 DNS 和通配符证书由平台统一管理你不需要为每个应用配 DNS 或证书路由与认证由平台代劳Caddy 处理 TLS路由器按子域名把请求代理进容器。默认所有路由都需要平台属主owner登录应用本身不用写登录逻辑容器以 rootless 方式运行容器内 root 对应主机上的非特权用户天然更安全。 一句话总结你只负责应用代码 一个 Dockerfile 一份 cloudinabottle.toml剩下全是平台的事。二、最小示例给仓库加上 cloudinabottle.tomlcloudinabottle.toml必须放在仓库根目录完整字段参考见 docs/src/creating_an_app/manifest_spec.md。一个最小可用的目录结构如下my-app/ ├── cloudinabottle.toml # 应用清单本文主角 ├── Dockerfile # 容器定义 ├── pyproject.toml # 依赖声明或 package.json / go.mod └── app.py # 你的应用代码对应的一份最小清单[app] name my-app version 0.1.0 description What it does [runtime.container] image Dockerfile # 相对仓库根目录的 Dockerfile 路径 port 8080 # 应用容器内监听的 HTTP 端口 [resources] memory_mb 128 cpu_cores 0.1 [data] sqlite [main] # 自动创建数据库文件 app_data true # 持久化数据目录默认开启配套的 Dockerfile与 apps/test_app/Dockerfile 思路一致FROM python:3.12-alpine COPY --fromghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv WORKDIR /app COPY pyproject.toml . RUN uv sync COPY . . EXPOSE 8080 CMD [uv, run, python, -u, app.py]应用代码只需遵循一条铁律监听0.0.0.0:port且端口与清单里的port一致。比如一个十几行的 Flask 应用from flask import Flask app Flask(__name__) app.route(/) def index(): return h1Hello from Cloud in a Bottle/h1 if __name__ __main__: app.run(host0.0.0.0, port8080)TLS 由路由器终结代理进容器的是 HTTP所以你不需要在应用里处理证书。三、cloudinabottle.toml 字段速查表区块必填关键字段说明[app]✅name、version、description应用唯一标识小写字母连字符、版本号、描述[runtime.container]✅image、port、commandDockerfile 路径、应用端口、容器启动命令覆盖[[ports]]可选label、container_port、host_port暴露非 HTTP 端口如 SMTPhost_port 0表示自动分配[routing]可选health_check、public_paths健康检查路径判断应用是否启动完成、免登录公开路径[[links]]可选name、path在应用详情页展示额外入口如管理后台[resources]可选memory_mb默认 128、build_memory_mb、cpu_cores默认 0.1运行时与构建阶段的资源上限[data]可选app_data、app_temp_data、app_archive、sqlite声明需要的数据层见下一节[[services.v2.*]]可选provides/consumes对外提供服务 / 调用其他应用的服务仓库里就有几份现成的真实清单可以对照阅读最简测试应用apps/test_app/cloudinabottle.toml包装现成软件一行 Dockerfile 数据权限apps/file_browser/cloudinabottle.toml完整示例服务提供 消费 密钥申请apps/oauth_provider/cloudinabottle.toml清单解析与安全校验capabilities、devices 的白名单等实现在 compute_space/src/compute_space/core/manifest.py写清单遇到解析被拒绝的报错时可以回来看。四、数据存储让应用的数据活得比容器久 应用容器随时可能被重建但数据不该跟着消失。平台提供三级存储通过[data]声明全部挂载在容器内的/data/下层级清单开关容器内环境变量特点永久数据app_data true默认开启BOTTLE_APP_DATA_DIR本地磁盘小而快适合配置文件、主数据库临时数据app_temp_data trueBOTTLE_APP_TEMP_DIR本地磁盘适合可重建的缓存、构建产物归档数据app_archive trueBOTTLE_APP_ARCHIVE_DIR大块内容视频、照片、附件可由属主配置 S3 后端弹性扩容以 SQLite 为例在清单里写sqlite [main]平台就会自动创建数据库文件并通过BOTTLE_SQLITE_MAIN环境变量把路径告诉应用。代码里应该读环境变量而不是硬编码路径import os DB_PATH os.environ[BOTTLE_SQLITE_MAIN] # 指向 /data/app_data/my-app/sqlite/main.db平台还会注入一批运行时环境变量完整列表见 docs/src/creating_an_app/overview.mdBOTTLE_APP_NAME应用名也就是它的子域名前缀BOTTLE_APP_ID不随改名变化的稳定应用 ID适合给持久状态做主键BOTTLE_APP_TOKEN跨应用服务调用的认证令牌BOTTLE_ROUTER_URL路由器内部地址用于发起服务调用BOTTLE_ZONE_DOMAIN实例域名BOTTLE_OWNER_USERNAME属主显示名可用来初始化 SSO 账户。五、路由细节健康检查与公开路径 [routing]区块控制平台如何看见你的应用[routing] health_check /health # 平台用它的 200 响应判断应用启动完成 public_paths [/webhook, /callback] # 这些路径前缀无需登录即可访问health_check应用启动后平台轮询该路径返回 200 才算就绪。参考实现见 apps/test_app/server.pypublic_paths默认所有路由都要 owner 登录。如果你的应用自己实现了认证或需要接收 Webhook / OAuth 回调把对应路径列进public_paths。此时路由器会在携带有效 owner 会话的请求上附加X-OpenHost-Is-Owner: true头方便你的应用公开页面 属主可见编辑按钮。另外如果你的应用需要 HTTP 之外的协议如 SMTP 25 端口用可重复的[[ports]]声明主机端口映射注意80/443被路由器保留且多个应用抢同一主机端口会安装冲突推荐host_port 0自动分配。六、进阶让应用之间互相调用Services v2这是 Cloud in a Bottle 最有意思的能力应用之间不直接通信全部经由路由器中转路由器负责解析提供方、转发权限详见 docs/src/creating_an_app/cross_app_services.md。消费端你的应用想调用别人的服务[[services.v2.consumes]] service github.com/imbue-openhost/openhost/services/secrets shortname secrets # 你自己起的短名用于调用 version 0.1.0 grants [{key MY_API_KEY}] # 安装时向属主申请的权限然后在代码里通过路由器发起调用curl -X POST $BOTTLE_ROUTER_URL/api/services/v2/call/secrets/get \ -H Authorization: Bearer $BOTTLE_APP_TOKEN \ -H Content-Type: application/json \ -d {keys: [MY_API_KEY]}提供端你的应用想对外暴露服务[[services.v2.provides]] service github.com/imbue-openhost/openhost/services/my-service version 0.1.0 endpoint /api/ # 服务请求会落在应用内的这个前缀下平台内置了secrets密钥托管与oauth第三方 OAuth 令牌管理两个服务规格文件在 services/secrets/ 和 services/oauth/。grants中的权限条目会在用户安装应用时弹出审批页——属主批准一次之后调用自动带上授权。七、部署上线从 Git 仓库到 https 域名 清单写好、推到 Git 仓库后部署只需要一步仪表盘打开你的实例仪表盘点击 NEW / Deploy New App粘贴仓库地址即可。平台会自动读取cloudinabottle.toml、构建镜像、启动容器最终你的应用出现在https://my-app.yourdomain.com/或者用 bottle CLI偏好终端的话安装方式见 docs/src/operation/cli.mdbottle app deploy 你的git仓库URL --wait bottle app status my-app bottle app logs my-app --follow更新代码同样简单push 之后在应用详情页点Update and reload拉新代码并重新构建或执行bottle app reload my-app --update --wait八、常见坑与调试工作流 ⚠️构建阶段被 OOM 杀死build_memory_mb默认等于memory_mb。如果你的构建过程比如pip install大依赖比运行时更吃内存请显式调高apps/test_app/cloudinabottle.toml 里就是这个场景的注释端口不匹配应用实际监听的端口必须与runtime.container.port一致且必须绑定0.0.0.0而不是127.0.0.1否则路由器代理不进去应用卡在启动中多半是health_check路径没有返回 200先用bottle app logs app --follow看构建日志和容器日志X-OpenHost-*头不可信于外部客户端伪造的这些头会在进入容器前被路由器剥除只有路由器能设置它们调试循环本地改代码 → commit push → 应用详情页 Update and reload → 重新测试通常几分钟一个迭代。 项目还提供了带 Litestar uv Playwright 集成测试的官方应用模板从零写新应用时可以直接基于它起步见 docs/src/creating_an_app/overview.md 中的 App template 一节。写在最后回到标题那句话给仓库写个cloudinabottle.toml你的代码就有了自己的云。一份几十行的 TOML换来了容器构建、子域名、HTTPS、认证、数据持久化和跨应用服务这一整套基础设施——而且数据全部留在你自己的硬件上。现在就去打开你的仓库把那份清单加上吧。赞分享【免费下载链接】cloud-in-a-bottleDeploy, use, and share web apps on a server you control. Your apps, data, and infrastructure stay yours.项目地址https://gitcode.com/gh_mirrors/cl/cloud-in-a-bottle点击查看免费下载相关推荐应用与平台之间的契约Cloud in a Bottle 注入的环境变量与数据目录完整速查应用与平台之间的契约Cloud in a Bottle 注入的环境变量与数据目录完整速查 Cloud in a Bottle 是一个自托管的 Web 应用部署Learn X in Y Minutes 仓库中的 JSON 完整教程从数据类型到实战写法Learn X in Y Minutes 仓库中的 JSON 完整教程从数据类型到实战写法 导读 本文以 learnxinyminutes docs 仓库中的文档教程从安装到查询XLite插件的完整使用教程从安装到查询XLite插件的完整使用教程 XLiteGitHub 加速计划是一款强大的工具能够让你使用SQLite查询Excel电子表格.xlsx、.创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Python实现FPU模拟:非线性振子链能量递归的数值复现

Python实现FPU模拟:非线性振子链能量递归的数值复现

简介:费米-帕斯塔-乌拉姆(FPU)问题模拟器是一份基于Python的完整仿真实现,面向物理非线性系统爱好者、计算物理初学者及教学场景。程序在真实弹性基础上引入二次方与三次方非线性项,通过调节alpha与beta参数即可直观观…

📅 2026/10/14 17:04:47
从理论到落地:构建企业级信息安全防线

从理论到落地:构建企业级信息安全防线

🔒免责声明:本文仅供网络安全学习、企业安全规划、课程论文案例参考,所有安全策略落地需要结合企业自身业务实际情况,遵守网络安全相关法律法规。 在信息系统安全规划与设计中,我们常将 “保密性、完整性、可用性、不可…

📅 2026/10/14 17:04:47
【Web 渗透】10 款 Burp Suite 神器插件合集,直接拉满渗透测试效率

【Web 渗透】10 款 Burp Suite 神器插件合集,直接拉满渗透测试效率

🔒法律免责声明:本文所有技术内容仅用于企业授权渗透测试、安全学习研究。未经资产所有者书面授权,禁止对互联网任何业务系统实施渗透、扫描、漏洞探测等行为,违规操作将触犯网络安全相关法律法规,全部风险由使用者自行…

📅 2026/10/14 17:04:47
MORE NEWS

更多资讯

📰

openHiTLS 社区贡献指南:CLA 签署、Issue 讨论与本地构建验证实战

密码学网络安全 【免费下载链接】openHiTLS 旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践&#xff…

📰

视频播放异常排查:非APP层导致的黑屏卡顿根因定位

干播放器开发的,多少都经历过这种夜晚:线上反馈视频黑屏、卡顿、一直转圈,第一反应把APP代码翻了个底朝天,日志加了十几处,甚至回滚了两个版本,问题还在。后来才发现,出问题的环节根本不在APP层…

📰

玲珑轮胎登上山东台:一条轮胎凭什么跑出“山东好品”的底气

近日,玲珑轮胎登上山东电视台新闻频道《市场监管在线》栏目“好品山东‘链’成记—企业说好品”,以“质量是企业的生命线”为主题,玲珑轮胎常务副总裁孙松涛介绍了玲珑通过提高制造标准、加大研发能力、提升产品性能、严格把控质量、紧抓细节…

📰

PRAXIST 直接 CLI 运维指南:从校验、启动到观察、停止与恢复的完整生命周期

人工智能AI Agent多智能体Agent 工作流深度研究AI 评测 【免费下载链接】PRAXIST Autonomous research system for measurable, computer-executable research. 项目地址: https://gitcode.com/gh_mirrors/pr/PRAXIST 点击查看 免费下载 本文是面向运维人员&#x…

📰

ATF转换PNG/JPG工具实战:从识别文件头到DXT1解压的完整指南

简介:这是一款专门将Adobe纹理格式(ATF)转换为PNG或JPG格式的实用工具,面向Stage3D开发者、Flash/Air游戏美工及需要跨平台处理ATF纹理的图形工作者。资源包合计30个文件,压缩后约13.58MB,内含exe主程序、d…

📰

GuardianShell主动式AI野生动物哨兵:边缘计算架构与部署实战

1. 从零拆解 GuardianShell:一个主动式 AI 野生动物哨兵到底在解决什么问题第一次看到 GuardianShell 这个标题,我脑子里蹦出来的不是“又一个 AI 摄像头”,而是一个很具体的画面:凌晨两点,某片山区农场的边缘&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬