Openship:自托管部署平台完整指南——从快速启动到生产级 CI/CD 与 Docker Compose 落地
【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openship
Openship 是一款开源、可自托管的部署平台,内置完整 CI/CD 流水线。本文将基于仓库官方葡萄牙语 README(docs/i18n/README.pt.md)为核心骨架,结合 CLI 源码、Docker Compose 编排 与 openship.json 配置 Schema 等仓库实证,系统讲解安装方式、工作原理、功能矩阵、三端界面、CLI 命令、声明式配置以及自托管生产落地的细节,帮助你从零开始把 Openship 跑起来并理解其底层机制。
图:Openship 控制面板界面(仓库 docs/screenshots/screen.png)。
快速启动:三种部署形态的选择
Openship 自身(控制平面)有三种运行形态,选择取决于使用人数以及是否需要常驻可达,具体可参见 docs/installation.md 中的决策表:
| 场景 | 运行方式 |
|---|---|
| 单人、私有 | 桌面应用:控制平面运行在本地机器上,通过 SSH 驱动远端服务器,不对外暴露任何端口 |
| 团队、常驻、CI/推送部署 | 服务器自托管:控制平面运行在 Linux 机器上并绑定公网 URL,需要登录,仅限邀请 |
| 零运维 | Openship Cloud:托管服务,开箱即用 |
方式一:npm 全局安装 CLI
npm i -g openship openship init需要 Node.js 22+(安装脚本在系统 Node 版本过低时会自带运行环境)。在任意项目目录下执行openship init,即可将当前目录与 Openship 项目建立关联——从源码看,该命令会在目录下生成.openship/project.json链接文件(见 apps/cli/src/commands/init.ts),后续的openship deploy会读取这个文件来定位目标项目。
方式二:Docker Compose 自托管
git clone https://gitcode.com/GitHub_Trending/ope/openship && cd openship cp .env.example .env docker compose --env-file .env -f docker/docker-compose.yml up -d该编排位于仓库 docker/docker-compose.yml,采用拉取镜像的方式(默认来自ghcr.io/oblien/*),无需本地编译。注意:仓库根目录的docker-compose.yml是另一份文件(SaaS/源码控制平面),并不用于自托管你的应用,别用错。
方式三:桌面应用
在 openship.io 下载对应平台安装包,或运行openship install拉取桌面版。桌面版控制平面只在本机运行(应用关闭即停止),没有任何公网暴露面,适合单机开发者。
它到底做什么:一次部署的完整流水线
把 Openship 指向一个GitHub 仓库、本地文件夹或预构建产物,它会端到端执行一条流水线:
- 识别(Detect)——读取项目的
package.json、框架配置、锁文件以及docker-compose.yml/openship.json,自动推断技术栈、包管理器、构建/启动命令和端口。零配置文件即可工作;openship.json可覆盖推断结果。 - 构建(Build)——在目标服务器或编排器本地构建 Docker 镜像(或裸发布包),解析后的配置被冻结为快照,因此重新部署和回滚会严格复现当初发布的内容。
- 运行(Run)——以容器(仅发布到 loopback,绝不暴露公网端口)或受监督的主机进程方式运行。
- 路由与安全(Route + secure)——OpenResty 边缘网关写入反向代理 vhost 并签发 Let's Encrypt 证书(HTTP-01)。因为路由和 TLS 发生在应用启动之后,DNS 或证书问题只会显示为"需要处理",绝不会导致部署失败或应用下线。
- 推送即部署(Push-to-deploy)——GitHub webhook 在每次推送时重新运行流水线,且 monorepo 场景下只重建实际被改动的服务。
推送即部署和公网域名需要常驻服务器或 Cloud——桌面/loopback 实例没有公网端点来接收 webhook。
功能矩阵
| 内置 CI/CD | 推送即部署、预览环境、staging/prod 流程、回滚 |
| 任意技术栈 | Node、Python、Go、Rust、PHP、Ruby、Java、.NET、Docker、monorepo |
| 完整后端 | Postgres、MySQL、MongoDB、Redis、worker、WebSocket、对象存储 |
| 域名与 SSL | 自动 Let's Encrypt、泛域名、无限域名、自动续期 |
| CDN | 边缘缓存、HTTP/3、Brotli 压缩、即时 purge |
| 邮件服务器 | 内置 SMTP 与 DKIM/SPF/DMARC——无需 Mailgun 或 SES |
| 备份 | 定时备份、数据库 + 卷、一键恢复、随时导出 |
| 实时监控 | 实时构建日志、容器指标与资源用量流式上屏(详见 docs/monitoring.md) |
| 可扩展性 | 云端自动伸缩,自托管侧已为多节点就绪 |
| 可移植性 | 标准 Docker 容器,可自由在云厂商间迁移 |
| Docker Compose | 原样部署你现有的 compose 文件 |
在任何地方部署
- Openship Cloud——托管、自动伸缩、零配置
- 任意 VPS——Hetzner、DigitalOcean、Linode、OVH 等
- 独立服务器——裸金属、托管机房、homelab
- 多服务器——跨机器分发负载
无论部署到哪里,界面完全一致。
三端界面与自动化
- 桌面应用——完整 GUI、实时日志、一切一键完成,适合单人。
- Web 控制面板——浏览器中的同一套界面,面向团队。
- CLI——可脚本化、对 CI 友好;同时也是安装与管理自托管实例的方式。
此外,REST API与MCP(面向 AI Agent 的协议端点)补齐了自动化与工具集成能力。从 README.md 可知:只有主动选择开放的路径才会被暴露为 MCP 工具,每次调用都会重新校验权限,凭证/令牌类路由永远不会成为工具。
CLI 参考:安装、运行与管理实例
完整的 CLI 参考见 docs/installation.md,这里给出核心命令(源码实现位于 apps/cli/src/commands 目录):
运行与管理实例
| 命令 | 作用 |
|---|---|
openship up [--foreground] | 以常驻服务方式启动(开机自启 + 崩溃自动重启);--foreground前台附加运行 |
openship up --public-url <url> [--managed-edge] | 在公网域名下提供控制面板(--managed-edge会在机器上安装 OpenResty + 免费 Let's Encrypt 证书并完成路由,无需单独反向代理) |
openship stop | 停止服务 |
openship status [--json] | 查询运行状态、解析后的端口与 API 健康状态 |
openship open | 在浏览器中打开控制面板 |
openship update | 升级 CLI 与内置服务器到最新版本 |
openship reset-admin-password | 在本机重置管理员登录密码(无需登录) |
openship install | 下载当前系统的桌面应用 |
openship doctor | 诊断 CLI 环境(配置、上下文、运行时) |
openship up会自动选择运行方式(源码见 apps/cli/src/commands/up.ts):
- Linux 且有 Docker → Compose 模式(默认,可加
--compose强制):拉起完整栈——Postgres、Redis、API、dashboard,以及容器化的OpenResty 边缘网关(:80/:443)。这种模式可以在同一台机器上托管你的应用,带自动域名 + Let's Encrypt TLS。 - 其他环境 → bare 模式(macOS、Windows 或没有 Docker 的 Linux,可加
--bare强制):单个轻量进程 + 内嵌数据库(PGlite),相当于"永远在线 + 需要登录"的桌面应用,把应用部署到远端服务器(SSH)或 Cloud。
其他值得注意的up参数(源码注释中有详细说明):--compose模式支持--edge migrate|takeover|cancel(处理 :80/:443 上已存在的第三方代理)、--no-host-control(加固:不给控制平面通往宿主 OS 的通道)、--host-ssh-host/port/user(rootless Docker 或非常规 sshd 时的宿主通道配置)、--reset-secrets(数据卷仍在但原.env丢失时的密钥重置)、--non-interactive(配合--admin-email等的无头安装)。另外openship up --dry-run可以只预览将要执行的安装计划而不改动机器。
部署与检查
| 命令 | 作用 |
|---|---|
openship init | 将当前目录关联到项目(生成.openship/project.json) |
openship deploy | 触发当前项目的部署 |
openship logs <deploymentId> [-f] [--tail N] | 查看或实时跟随部署日志 |
openship deployment | 列出 / 管理部署 |
openship project | 列出 / 管理项目 |
openship service | 管理栈内的服务 |
openship domain | 管理项目域名 |
openship deploy的源码(apps/cli/src/commands/deploy.ts)展示了它的两条路径:在 git 仓库内走POST /api/deployments(支持--branch、--commit、--env production|preview、--force-all、--smart-route、--refresh、--service-ids等参数);不在 git 仓库内则走文件夹上传流水线。加--watch可实时跟随部署日志。
基础设施与管理员
| 命令 | 作用 |
|---|---|
openship server | 管理自托管 SSH 服务器 |
openship system | 读取 / 更新实例设置 |
openship mail | 邮件服务器配置 |
openship backup | 项目的备份策略(定时计划) |
认证、配置与自动化
| 命令 | 作用 |
|---|---|
openship login/logout | 使用个人访问令牌(PAT)认证,令牌在 dashboard 的 Settings 中创建 |
openship context | 管理上下文——CLI 连接哪个实例 |
openship token | 管理个人访问令牌 |
openship api <method> <path> | 对任意 API 路由发起已认证请求(类似gh api) |
多数只读命令支持追加--json以便脚本化处理。
声明式配置:openship.json
如果你想要比自动检测更强的控制,可以在仓库根目录放置openship.json。它是一个权威覆盖层:自动检测先运行,然后文件中出现的每个字段都会覆盖对应检测值(未出现的字段保留检测结果)。其完整类型定义见 packages/core/src/openship-config/schema.ts,校验与强制类型转换实现在 packages/core/src/openship-config/parse.ts,同时会生成 JSON Schema 供编辑器自动补全。
核心字段一览:
| 分组 | 字段 | 说明 |
|---|---|---|
| 构建 | framework | 技术栈 ID,覆盖自动检测 |
| 构建 | packageManager | 包管理器(npm/pnpm/yarn/bun 等) |
| 构建 | rootDirectory | 项目根目录(monorepo 子应用场景) |
| 构建 | composePath | compose 文件路径;声明后项目变为 compose/services 部署 |
| 构建 | installCommand/buildCommand/startCommand | 安装、构建、启动命令覆盖 |
| 构建 | outputDirectory | 静态产物输出目录 |
| 构建 | volumes | 跨部署保留的路径(如 Laravel 默认保留storage/) |
| 运行时 | runtime | bare|docker |
| 运行时 | workload | web(端口 + 路由)|worker(无端口常驻容器)|static(静态文件) |
| 运行时 | port | 应用监听端口 |
| 环境变量 | env | 普通字符串,或{ "value": "...", "secret": true }加密存储 |
| 域名路由 | domains | 域名数组,支持port、targetPath、type(free|custom) |
| 资源 | resources | 规格档位unlimited/micro/low/medium/high/xlarge,或显式cpuCores/memoryMb/diskMb |
| 就绪门禁 | readiness | 部署期一次性"是否启动成功"检查(与 Docker HEALTHCHECK 不同,只有它能判定部署失败) |
| 服务 | services | Compose 服务定义(image、build、ports、volumes、command、restart、healthcheck、resources等) |
| Monorepo | monorepo | workspace 配置 + 各子应用(rootDirectory、framework、buildCommand等)的构建覆盖 |
示例(web 应用 + 加密环境变量 + 域名 + 资源上限):
{ "framework": "nextjs", "port": 3000, "env": { "DATABASE_URL": { "value": "postgres://user:pass@host/db", "secret": true } }, "domains": [{ "domain": "app.example.com", "type": "custom" }], "resources": { "tier": "medium" } }解析器对未知顶层键只给出警告而非报错(软性忽略),但类型错误、非法枚举值、越界数值会记入
errors;openship config validate在errors非空时直接失败。
生产级自托管:Docker Compose 栈细节
官方编排文件 docker/docker-compose.yml 定义了五个服务:
| 服务 | 说明 |
|---|---|
postgres | postgres:16-alpine,私有端口 5432,数据卷子目录PGDATA=/var/lib/postgresql/data/pgdata |
redis | redis:7-alpine,私有端口 6379,开启 AOF 持久化 |
api | 控制平面,默认 loopback127.0.0.1:4000(可用API_PORT覆盖) |
dashboard | 界面,默认 loopback127.0.0.1:3001(可用DASHBOARD_PORT覆盖) |
edge | OpenResty 边缘网关,network_mode: host直绑宿主 :80/:443,固定容器名openship-edge |
几个值得注意的实现细节:
- Docker-out-of-Docker:
api容器挂载宿主 Docker socket(/var/run/docker.sock),从而能在宿主守护进程上构建并运行你的应用容器。因此 api 容器通过 socket 拥有宿主特权,只能在受信任的主机上运行,不要暴露到不可信网络。 - 路由状态共享:api 与 edge 通过宿主 bind 挂载共享四块目录——
/var/lib/openship/edge/sites-enabled(vhost)、/etc/letsencrypt(证书)、/var/lib/openship/edge/acme(ACME 挑战)、/opt/openship/static(静态根目录)。API 写入 vhost、证书和静态目录,edge 读取并提供服务。 - 版本固定:在
.env中设置OPENSHIP_VERSION可实现可复现的拉取与升级;OPENSHIP_IMAGE_REGISTRY可覆盖镜像源(镜像场景)。升级命令为docker compose --env-file .env -f docker/docker-compose.yml pull && … up -d。 - 远程访问:从其他机器访问(局域网 IP 或反向代理)必须在
.env设置OPENSHIP_PUBLIC_URL,否则登录会被拒绝(403 ORIGIN_REJECTED);反向代理场景还需设置TRUST_PROXY=true。 - 绑定接口:默认 api/dashboard 只发布在 loopback,由 edge 前置公网域名;只有确实想绕开域名直接对外时,才设置
OPENSHIP_BIND_ADDR(如0.0.0.0)。
Postgres 启动失败的排查(EPERM)
如果postgres容器首次启动报could not write to file "pg_wal/xlogtemp.NN": Operation not permitted,说明数据库卷所在文件系统不支持 Postgres 需要的底层操作(这是EPERM,不是权限/uid 问题)。先清掉半初始化的卷重试:
docker compose -f docker/docker-compose.yml down -v docker compose --env-file .env -f docker/docker-compose.yml up -d仍失败则检查宿主/内核层不兼容:systemd-detect-virt若显示openvz/lxc说明宿主有问题;df -T "$(docker info -f '{{.DockerRootDir}}')"若显示nfs/cifs/fuse/zfs说明 contenteditable="false">【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openship
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考