pipewright

package module
v1.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 2 Imported by: 0

README

Pipewright

A lightweight, self-hosted CI/CD + deployment + ops platform. A single static Go binary (frontend embedded, zero runtime dependencies) — one tool replacing the "CI + Ansible/Kamal + Portainer" trio.

Release CI

English | 简体中文


Why Pipewright

Mainstream options are either heavy (Jenkins with a pile of plugins + JVM) or a three-tool assembly (Woodpecker/Drone + Ansible/Kamal + Portainer). Pipewright packs "continuous integration, multi-server deployment, and server/container ops" into one static binary: download, start, open the browser — that's the entire install.

Pipewright Jenkins Drone + Ansible + Portainer
Single-binary deploy ✅ ❌ JVM + plugins ❌ three-tool assembly
Visual pipeline orchestration (DAG) ✅ built-in canvas plugin hand-written YAML
Isolated builds ✅ ✅ ✅
Multi-server deploy (SSH, agentless) ✅ built-in plugin Ansible
Server / container ops ✅ built-in ❌ Portainer
Zero-downtime + failure rollback ✅ plugin DIY
One-click self-update ✅ ❌ ❌

Screenshots

Global overview — projects, run success rate, environment deployment status, server health, and DORA metrics, all on one screen:

Dashboard

Visual pipeline orchestration — a two-level (stage/job) DAG canvas: horizontal links for serial, vertical side-by-side for true parallel. Supports matrix builds, manual approval gates, sidecar services, and post-stage steps; the canvas and YAML round-trip both ways:

Pipeline canvas

Run detail — stage transitions, live logs (SSE push + history replay), build artifacts and image references, and per-step status:

Run detail

Container management — one-stop management of containers/images/Stacks/volumes/networks across hosts, with lifecycle operations, live stats, logs, and an interactive terminal:

Container management

Feature Overview

  • 🔐 Security foundation — single-admin auth (argon2id + CSRF) · encrypted credential vault (NaCl secretbox, masked display, never plaintext) · append-only audit · end-to-end secret redaction.
  • 🧩 Projects & pipelines — visual orchestration canvas (stage DAG + intra-stage job-level DAG) · matrix builds · manual approval gates · sidecar services (attach DB/Redis for tests) · trigger rules + branch→environment mapping · server-authoritative validation.
  • 🏗 Isolated builds & artifacts — version-pinned isolated builds inside containers · build dependency caching · multiple artifact types (image/JAR/dist) + push to private registries · live terminal logs (SSE) + history replay · read-only code browsing (Monaco).
  • 🚀 Multi-server deployment — agentless deploy over SSH · health gating · zero-downtime cutover + failure rollback · parallel fan-out across hosts + visible partial failures · environment deployment history and rollback.
  • 📣 Notifications — WeCom / DingTalk / Lark (Feishu) / email / custom webhook · fine-grained event→channel routing · templates + custom variables · in-pipeline notification nodes.
  • 🖥 Server & container ops — multi-host status overview (CPU/memory/disk) · container/image/Stacks/volume/network management · live + historical service logs · interactive container terminal · web ops terminal (host shell, full copy-paste/signal support) · anomaly detection alerts.
  • 📈 Metrics — the four DORA metrics (deployment frequency / lead time for changes / change failure rate / mean time to restore) out of the box.
  • 🔄 Update check + one-click self-update — Settings → System checks GitHub for the latest release with semantic comparison; binary deployments can auto-update with one click from the UI (download + checksum verification + atomic replace + self-restart), while Docker deployments get the exact upgrade command.

Security is non-negotiable: credentials stored as ciphertext only, commands arrayified against injection, outbound SSRF locked down, logs redacted.

Install / Deploy

Pick any of three form factors. The platform itself is a single static binary with zero runtime dependencies (no Go/Node required).

Docker prerequisite: the platform itself doesn't depend on Docker, but "isolated builds / container deployment" do require Docker (without it, it degrades to a stub runner and performs no real builds). The console / SSH deployment / notifications don't need Docker. The one-click script detects Docker and prompts if it's missing; on Linux you can set INSTALL_DOCKER=1 to auto-install it (via the official get.docker.com); on macOS, install Docker Desktop.

① One-click script (Linux / macOS)

Downloads the static binary for your platform from GitHub Releases and installs it to /usr/local/bin (with checksum verification + Docker detection):

curl -fsSL https://raw.githubusercontent.com/huangchengsir/pipewright/master/install.sh | sh

# Pin a version / custom dir / auto-install Docker on Linux too:
VERSION=v1.0.0 INSTALL_DIR=$HOME/.local/bin INSTALL_DOCKER=1 \
  sh -c "$(curl -fsSL https://raw.githubusercontent.com/huangchengsir/pipewright/master/install.sh)"

# Run (first launch bootstraps the admin; master key is for the credential vault)
PIPEWRIGHT_MASTER_KEY=$(openssl rand -base64 32) \
PIPEWRIGHT_ADMIN_PASSWORD=change-me \
  pipewright          # open http://localhost:8080, log in with admin / change-me

Recommended: install as a systemd service (auto-start on boot + restart on crash + one-click self-update available; Linux, requires root). The script persists the master key to /etc/pipewright/master.key, stores data in /var/lib/pipewright, and writes config to /etc/pipewright/pipewright.env:

SETUP_SERVICE=1 sh -c "$(curl -fsSL https://raw.githubusercontent.com/huangchengsir/pipewright/master/install.sh)"
# Status / logs: systemctl status pipewright  ·  journalctl -u pipewright -f
# Change port etc.: edit /etc/pipewright/pipewright.env then systemctl restart pipewright

# Use MySQL instead of the default SQLite (DSN is go-sql-driver format; parseTime=true is required):
SETUP_SERVICE=1 PIPEWRIGHT_DB_DRIVER=mysql \
  PIPEWRIGHT_DB_DSN='user:pw@tcp(host:3306)/pipewright?parseTime=true&charset=utf8mb4' \
  sh -c "$(curl -fsSL https://raw.githubusercontent.com/huangchengsir/pipewright/master/install.sh)"

Windows users: download the .zip from Releases.

curl -fsSLO https://raw.githubusercontent.com/huangchengsir/pipewright/master/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/huangchengsir/pipewright/master/.env.example
cp .env.example .env       # at minimum set PIPEWRIGHT_ADMIN_PASSWORD, and openssl rand -base64 32 for MASTER_KEY
docker compose up -d       # data persists in the named volume pipewright-data; see .env comments to switch to MySQL
③ docker run (fastest trial)
docker run -d -p 8080:8080 -v pipewright-data:/data \
  -e PIPEWRIGHT_ADMIN_PASSWORD=change-me \
  -e PIPEWRIGHT_MASTER_KEY=$(openssl rand -base64 32) \
  ghcr.io/huangchengsir/pipewright:latest
Build from source
make build          # frontend build → go:embed → single static binary ./pipewright (pure Go, no CGO)
./pipewright --version
Updating

Open Settings → System and click "Check for updates" to query the latest release; when a new version is available:

  • Binary deployment: click "Update now" to auto-download the new version + verify checksum + replace + restart (requires write permission to the binary file; installing to $HOME/.local/bin avoids sudo, and a root systemd service installed via SETUP_SERVICE=1 also satisfies this).
  • Docker deployment: the container doesn't replace its own image; follow the prompt to run docker compose pull && docker compose up -d on the host (the data volume is preserved).
Configuration (environment variables)
Variable Description Default
PIPEWRIGHT_ADDR HTTP listen address :8080
PIPEWRIGHT_RELEASE_REPO GitHub repo queried for update checks (change it for a fork) huangchengsir/pipewright
PIPEWRIGHT_DB_DRIVER Database driver: sqlite or mysql sqlite
PIPEWRIGHT_DB SQLite database path (when driver=sqlite) pipewright.db
PIPEWRIGHT_DB_DSN MySQL DSN (required when driver=mysql) none
PIPEWRIGHT_MASTER_KEY Credential vault master key (base64-encoded 32 bytes); or use _FILE to point to a file vault disabled if unset
PIPEWRIGHT_ADMIN_USERNAME Admin username on first launch admin
PIPEWRIGHT_ADMIN_PASSWORD Admin password on first launch none (must be set)
PIPEWRIGHT_RUNNER Run executor: default DAG (orchestrates stages/script/deploy_ssh/notify per the canvas); set legacy to fall back to the old fixed flow dag

Pipeline as code (GitOps)

Commit your pipeline structure to .pipewright.yml in the repo — same source of truth as your code, reviewable in a PR, evolving per branch — instead of relying on implicit drift in the canvas.

  • Enable: flip the "Pipeline as code" toggle on the project's pipeline page (per project).
  • How it works: once enabled, every run reads .pipewright.yml from the repo root on the branch being built (falling back to the project default branch when the branch is empty), and the pipeline spec in that file drives the run. Different branches can carry different .pipewright.yml. The file is fetched with the project's bound repo credential (ephemeral; no new exposure).
  • Never breaks a run: if the file is missing → falls back to the pipeline configured in the canvas (UI); if it exists but is invalid YAML → also falls back to the stored canvas config.
  • Scope: the YAML controls pipeline structure only (stages / jobs / needs / DAG layout). Variables & cache, environments & credentials, and trigger rules still come from the canvas (UI) settings — they are not in the YAML.
  • Schema is the same one used by the platform's "Import from YAML" (version + stages → jobs; a job uses a nested script: block for image/commands/env/workdir).
version: 1
stages:
  - id: stg_src             # needs references stages by id, so cross-stage deps need an explicit id
    name: Source
    kind: source
    jobs:
      - name: Gitee source
        type: git_source
  - id: stg_build
    name: Build
    kind: build
    needs: [stg_src]
    jobs:
      - name: Run tests
        type: script
        script:
          image: golang:1.23
          commands:
            - go vet ./...
            - go test ./...
          env:
            CGO_ENABLED: "0"
          workdir: src/app
  - id: stg_deploy
    name: Deploy
    kind: deploy
    needs: [stg_build]
    gate: true              # manual approval gate
    when:
      branches: [main, release/*]
    jobs:
      - name: SSH deploy
        type: deploy_ssh
        config:
          targetEnv: prod

You can also force pipeline-as-code on for all projects (ignoring the per-project toggle) via the global env var PIPEWRIGHT_PAC_RUNTIME=1, for back-compat / power users.

Tech Stack

  • Backend: Go · Chi (routing) · modernc/sqlite (pure Go, no CGO) · go-git · NaCl secretbox (vault) · argon2id · golang.org/x/crypto/ssh (agentless deployment)
  • Frontend: Vue 3 <script setup> · Vite · naive-ui · OKLCH dual theme · Monaco (read-only code browsing) · embedded into the binary via go:embed

Architecture

single static binary (cmd/pipewright)
├── internal/auth        auth + sessions + CSRF
├── internal/vault       encrypted credential vault (secretbox)
├── internal/audit       append-only audit + redaction
├── internal/project     project onboarding + repo detection
├── internal/pipeline    pipeline spec + build/deploy config + validation
├── internal/trigger     webhook + branch-mapping triggers
├── internal/run         run model + worker pool + logs + artifacts
├── internal/dagrun      DAG scheduling (stage-level + job-level, matrix expansion)
├── internal/build       isolated builds + image/artifacts + dependency caching
├── internal/target      generic SSH exec/session layer (shared by deploy + ops)
├── internal/deploy      SSH deploy execution + health gating + rollback
├── internal/notify      multi-channel notifications + event routing + templates
├── internal/httpapi     the sole outward HTTP surface (domain packages never touch HTTP)
└── web/                 Vue 3 frontend (embedded via go:embed)

Project Status

✅ Officially released and under active iteration — see the latest version in Releases (tag-driven releases: 6-platform binaries + ghcr multi-arch images). Already running in real production, carrying builds, deployments, and daily ops for multiple projects.

Contributing

PRs and issues welcome! Before you start, please read CONTRIBUTING.md (environment setup / testing / commit conventions) and follow the Code of Conduct. For security vulnerabilities, please use the private channel described in SECURITY.md.

License

MIT — see LICENSE.


Pipewright — CI, deployment, and ops in a single binary.

Documentation

Overview

Package pipewright is the module root. It embeds the built frontend (web/dist) so the whole platform ships as a single static binary (go:embed).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WebFS

func WebFS() fs.FS

WebFS 返回内嵌前端 SPA 的文件系统(根为 web/dist)。

Types

This section is empty.

Directories

Path Synopsis
cmd
pipewright command
Command pipewright 是平台入口:加载配置 → 打开存储(应用迁移)→ 装配 HTTP → 启动。
Command pipewright 是平台入口:加载配置 → 打开存储(应用迁移)→ 装配 HTTP → 启动。
internal
ai
Package ai 是「可配置 AI 提供商」的领域层(FR-24 / NFR-10 / Story 7.1)。
Package ai 是「可配置 AI 提供商」的领域层(FR-24 / NFR-10 / Story 7.1)。
anomaly
Package anomaly 是「可配置运行时异常检测与告警」的领域层(FR-23 · Story 6.5)。
Package anomaly 是「可配置运行时异常检测与告警」的领域层(FR-23 · Story 6.5)。
approval
Package approval 是人工审批门(Epic 8 · Story 8-4)的进程内协调器 + 持久化。
Package approval 是人工审批门(Epic 8 · Story 8-4)的进程内协调器 + 持久化。
artifactstore
Package artifactstore 是「构建产物物理存储」(制品库 · Story 8-16 / FR-8-16)。
Package artifactstore 是「构建产物物理存储」(制品库 · Story 8-16 / FR-8-16)。
audit
Package audit 是审计地基(NFR-7 / AC-SEC-03)。
Package audit 是审计地基(NFR-7 / AC-SEC-03)。
auth
Package auth 实现单管理员认证(argon2id 哈希、会话管理、登录失败锁定)。
Package auth 实现单管理员认证(argon2id 哈希、会话管理、登录失败锁定)。
build
Package build 是「隔离构建 + 镜像推送」的领域执行层(FR-5/FR-6/FR-7 · Story 3-3/3-5)。
Package build 是「隔离构建 + 镜像推送」的领域执行层(FR-5/FR-6/FR-7 · Story 3-3/3-5)。
buildcache
Package buildcache 是「构建依赖缓存」(build cache · P0 引擎能力)。
Package buildcache 是「构建依赖缓存」(build cache · P0 引擎能力)。
chain
Package chain 实现流水线串联(FR-8-11):上游流水线成功落终态后,按每项目配置的 「下游目标」列表,自动触发一个或多个下游流水线运行(可跨项目 / 同项目不同分支), 用于搭建 CD 链(如「应用构建成功 → 触发部署基础设施流水线」)。
Package chain 实现流水线串联(FR-8-11):上游流水线成功落终态后,按每项目配置的 「下游目标」列表,自动触发一个或多个下游流水线运行(可跨项目 / 同项目不同分支), 用于搭建 CD 链(如「应用构建成功 → 触发部署基础设施流水线」)。
config
Package config loads platform runtime configuration from the environment.
Package config loads platform runtime configuration from the environment.
cron
Package cron 是定时触发的最小实现(Epic 8 · Story 8-6):一个 5 字段 cron 解析器 + 分钟粒度调度器,无第三方依赖(项目刻意保持依赖精简)。
Package cron 是定时触发的最小实现(Epic 8 · Story 8-6):一个 5 字段 cron 解析器 + 分钟粒度调度器,无第三方依赖(项目刻意保持依赖精简)。
dag
Package dag 是流水线 DAG 调度引擎核心(Epic 8 · Story 8-3)。
Package dag 是流水线 DAG 调度引擎核心(Epic 8 · Story 8-3)。
dagrun
Package dagrun 把 DAG 调度内核(internal/dag)接进 run 引擎(Epic 8 · Story 8-1↔8-3 桥接)。
Package dagrun 把 DAG 调度内核(internal/dag)接进 run 引擎(Epic 8 · Story 8-1↔8-3 桥接)。
deploy
cmdlog.go:把部署链路在目标机真实执行的命令 + 其 stdout/stderr 实时回流到运行步骤日志, 让 deploy_ssh 步骤像 Jenkins 控制台一样看得到「具体执行了什么」(此前仅一行结果摘要)。
cmdlog.go:把部署链路在目标机真实执行的命令 + 其 stdout/stderr 实时回流到运行步骤日志, 让 deploy_ssh 步骤像 Jenkins 控制台一样看得到「具体执行了什么」(此前仅一行结果摘要)。
dnsprovider
Package dnsprovider 是「DNS 提供商集成层」(R3 E3.1–E3.4)的领域层。
Package dnsprovider 是「DNS 提供商集成层」(R3 E3.1–E3.4)的领域层。
dora
Package dora 计算 DORA 四指标(FR-8-15),对既有运行数据做**只读聚合**(不新增事件采集)。
Package dora 计算 DORA 四指标(FR-8-15),对既有运行数据做**只读聚合**(不新增事件采集)。
environments
Package environments 把「环境」做成可观测的一等只读对象(对标 GitLab environments): 按环境聚合部署历史(哪个 run、何时、什么产物、成功/失败、目标机、谁触发),并标出每环境 当前「活跃版本」(最近一次全成功部署),为一键回滚提供「上一次成功部署」的定位。
Package environments 把「环境」做成可观测的一等只读对象(对标 GitLab environments): 按环境聚合部署历史(哪个 run、何时、什么产物、成功/失败、目标机、谁触发),并标出每环境 当前「活跃版本」(最近一次全成功部署),为一键回滚提供「上一次成功部署」的定位。
gitauth
Package gitauth centralizes how an HTTPS git token is turned into BasicAuth credentials for clone / ls-remote across the codebase (source reader, project prober, build cloner, AI diff/analyze).
Package gitauth centralizes how an HTTPS git token is turned into BasicAuth credentials for clone / ls-remote across the codebase (source reader, project prober, build cloner, AI diff/analyze).
httpapi
Package httpapi is the single outward-facing surface of the platform.
Package httpapi is the single outward-facing surface of the platform.
i18n
Package i18n provides server-side localization of user-facing strings (primarily API error messages) for the 8 languages the web UI supports.
Package i18n provides server-side localization of user-facing strings (primarily API error messages) for the 8 languages the web UI supports.
library
Package library 是「流水线模板 + 变量组」复用基座的领域层(FR-8-13 · 对标 Jenkins Shared Library / 云效模板与变量组)。
Package library 是「流水线模板 + 变量组」复用基座的领域层(FR-8-13 · 对标 Jenkins Shared Library / 云效模板与变量组)。
mask
Package mask 是 secret 脱敏工具(AC-SEC-04)。
Package mask 是 secret 脱敏工具(AC-SEC-04)。
metrics
Package metrics 是服务器指标时序历史的领域层(异常检测「看趋势」折线图的数据源)。
Package metrics 是服务器指标时序历史的领域层(异常检测「看趋势」折线图的数据源)。
notify
Package notify 是多渠道通知的领域层(FR-19 · Story 5.1)。
Package notify 是多渠道通知的领域层(FR-19 · Story 5.1)。
oauth
Package oauth 是「多 provider OAuth 凭据接入」的领域层。
Package oauth 是「多 provider OAuth 凭据接入」的领域层。
pacloader
Package pacloader 实现「流水线即代码」(Pipeline-as-code)运行时覆盖(FR-8-12)。
Package pacloader 实现「流水线即代码」(Pipeline-as-code)运行时覆盖(FR-8-12)。
pipeline
Package pipeline 是「流水线配置编辑器与编排画布」的领域层(UX-DR5 / 部分 FR-9 / Story 2.2)。
Package pipeline 是「流水线配置编辑器与编排画布」的领域层(UX-DR5 / 部分 FR-9 / Story 2.2)。
pipelineyaml
Package pipelineyaml 是「流水线即代码」(`.pipewright.yml`)与领域模型 pipeline.Spec 之间的解析/序列化层(FR-8-12)。
Package pipelineyaml 是「流水线即代码」(`.pipewright.yml`)与领域模型 pipeline.Spec 之间的解析/序列化层(FR-8-12)。
previewenv
Package previewenv 是「Per-PR 预览环境」(R4 E4.1 · 差异化王牌)的领域层。
Package previewenv 是「Per-PR 预览环境」(R4 E4.1 · 差异化王牌)的领域层。
project
Package project 是「被纳管代码仓库」的领域层。
Package project 是「被纳管代码仓库」的领域层。
promotion
Package promotion 实现环境晋级流(Epic 8 · Story 8-7 / FR-8-7):把一次成功运行/产物 沿一条**有序环境链**(dev → staging → prod)逐级晋级,逐环境可设审批门,逐环境作用域 隔离变量/密钥。
Package promotion 实现环境晋级流(Epic 8 · Story 8-7 / FR-8-7):把一次成功运行/产物 沿一条**有序环境链**(dev → staging → prod)逐级晋级,逐环境可设审批门,逐环境作用域 隔离变量/密钥。
proxy
Package proxy 是「自动 HTTPS + 域名反向代理」(R1)的领域层。
Package proxy 是「自动 HTTPS + 域名反向代理」(R1)的领域层。
prstatus
Package prstatus 把流水线运行结果回写为代码平台的「提交状态/检查」(Epic 8 · Story 8-9 / FR-8-9)。
Package prstatus 把流水线运行结果回写为代码平台的「提交状态/检查」(Epic 8 · Story 8-9 / FR-8-9)。
qualitygate
Package qualitygate 是质量门禁的纯评估层(Epic 8 · FR-8-6)。
Package qualitygate 是质量门禁的纯评估层(Epic 8 · FR-8-6)。
repocache
Package repocache 是「代码管理区」(本地仓库镜像缓存 · Story 8-18 / FR-8-18)。
Package repocache 是「代码管理区」(本地仓库镜像缓存 · Story 8-18 / FR-8-18)。
retention
Package retention 实现运行数据的保留策略与定期清理(防止 runs/run_logs/run_steps/ artifacts 无限增长撑爆磁盘)。
Package retention 实现运行数据的保留策略与定期清理(防止 runs/run_logs/run_steps/ artifacts 无限增长撑爆磁盘)。
run
Package run 是「流水线运行」的领域层(FR-13 / Story 3.1)。
Package run 是「流水线运行」的领域层(FR-13 / Story 3.1)。
runner
Package runner 是「远程构建 runner 配置」领域层(FR-8-14 远程 runner 池续)。
Package runner 是「远程构建 runner 配置」领域层(FR-8-14 远程 runner 池续)。
store
Package store owns all SQLite access.
Package store owns all SQLite access.
storetest
Package storetest 提供跨方言(SQLite / MySQL)的测试夹具。
Package storetest 提供跨方言(SQLite / MySQL)的测试夹具。
target
Package target 是「目标服务器」的领域层 + 通用 SSH 执行/会话基座。
Package target 是「目标服务器」的领域层 + 通用 SSH 执行/会话基座。
testreport
Package testreport 解析测试报告(JUnit XML)与代码覆盖率(Cobertura XML),产出汇总 (通过/失败/跳过计数 + 可选覆盖率%),供「测试报告展示 + 质量门禁」消费(Epic 8 · FR-8-6)。
Package testreport 解析测试报告(JUnit XML)与代码覆盖率(Cobertura XML),产出汇总 (通过/失败/跳过计数 + 可选覆盖率%),供「测试报告展示 + 质量门禁」消费(Epic 8 · FR-8-6)。
trigger
Package trigger 是「项目触发设置与分支映射」的领域层(FR-1 / FR-2 / Story 2.3)。
Package trigger 是「项目触发设置与分支映射」的领域层(FR-1 / FR-2 / Story 2.3)。
vault
Package vault 是凭据加密保险库的领域层。
Package vault 是凭据加密保险库的领域层。
version
Package version 暴露构建期注入的版本元数据。
Package version 暴露构建期注入的版本元数据。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL