把项目管理搬回自己服务器:Windshift部署与避坑
简介
什么是 Windshift?
Windshift是一个开源的自托管工作管理平台,目标是把Jira的深度保留下来,同时去掉Jira的沉重。它用一个Go二进制文件打包了Svelte前端,默认使用内嵌SQLite,也可以换成PostgreSQL。
对于受够了 Jira 每年涨价、插件生态层层收费,又不想退到 Trello 那种只能看板的团队,Windshift 提供了一个折中方案:工作项、Epic、Sprint、自定义工作流、自动化、服务台、SLA、知识库、测试管理,全部内置。
主要特点
- Jira 级的规划能力:看板、
Backlog、迭代、Epic与子任务、层级树、路线图、仪表盘一应俱全,支持工作项类型的自由配置 - 每个工作区独立配置:工作项类型、自定义字段、界面、状态、工作流、优先级、权限都按工作区隔离,互不干扰
- JQL 风格查询语言:内置
Windshift Query Language,过滤条件可以保存为共享集合(Collection),驱动看板、列表、日历、路线图 - 事件驱动自动化:规则可以在事件发生时改字段、发通知、创建工作项,不需要再买
Marketplace上的自动化插件 - 服务台一体化:SLA 指标与目标、队列视图、预设回复、审批、客户门户全部内置,无需单独部署
Jira Service Management - 替代周边工具:知识库页面顶掉
Confluence,测试用例/测试运行顶掉Xray、Zephyr,资产CMDB顶掉Insight,时间跟踪也是原生的 - Jira 导入器:内置迁移工具,支持
Jira Cloud与Data Center的项目、评论、附件、worklog、看板、Sprint、自定义字段导入 - 九种语言:含简体中文、阿拉伯语(完整
RTL镜像布局)、日韩俄德法西葡 - 单二进制、无外部依赖:不需要
Java,不需要Elasticsearch集群,约70 MB一个文件,树莓派也能跑 - 开源免费:基于
AGPL-3.0协议开源,无用户数限制,无需License Key
应用场景
- 团队从 Jira 迁移:受够了按人头计费与插件订阅,用内置导入器把项目整体搬过来,数据留在自己服务器上
- 中小团队自建项目管理:五到五十人的团队,不想维护
Confluence + Jira + Xray + Insight这一套,一个容器全解决 - 外包与客户支持:客户门户 +
SLA+ 队列,对外提供工单入口,对内用同一套工作项跟踪进度 - 研发流程闭环:关联
GitHub、GitLab、Gitea、Forgejo,分支和PR直接绑到工作项上,提交记录自动回流 - 内网/合规环境:完全离线可用,数据不出机房,适合对数据主权有要求的场景

Windshift 是一个把 Jira 核心能力和周边插件压缩进单个容器的自托管方案,适合想拿回数据控制权、又不愿意在功能上做减法的团队。
安装
官方镜像只发布在 ghcr.io,群晖的 Docker 套件搜不到,需要用命令行拉取。
本文写作时,最新稳定版本为
v0.9.1(2026-10-21发布),老苏选择了最新的main

准备工作
通过 SSH 登录到您的群晖,执行下面的命令,先创建数据目录,并生成一个固定的密钥:
1 | # 新建文件夹 windshift 和 子目录 |
SSO_SECRET用于签名会话Cookie和加密SSO凭据。一旦更换,所有人会被踢下线,已保存的SSO/集成凭据也会失效。
env.txt
配置文件主要就下面几个参数需要调整
SERVER_IP:服务器IPPORT:主机端口SSO_SECRET:上一步中openssl rand -hex 32生成POSTGRES_PASSWORD:数据库密码
1 | # ============================================================================= |
记得保存时要用 UTF-8 编码

docker-compose.yml
将下面的内容保存为 docker-compose.yml 文件:
1 | # Windshift — 纯 HTTP + 服务器 IP 部署(内网/测试用) |
PostgreSQL默认max_connections是100。Windshift的连接预算是「副本数 × (MAX_READ_CONNS+5) + 预留」,启动时会检查这个预算是否安全,超了会在日志里告警。
执行以下命令启动:
1 | # 进入 windshift 目录 |

运行
在浏览器中访问 http://<群晖IP>:8256 即可进入语言设置

接下来是管理员设置

模块默认即可

刚开始使用,还需要创建工作区

输入名称名称和键值(Key)
创建第一块工作区时有个坑:Key 不是名称。它是工作项编号的前缀(如
DEV-123),规则是从源码里写死的——只允许A-Z a-z 0-9,长度 2 到 10 位,不能有空格、中文、连字符。名称可以随便用中文,但Key请单独填一段英文缩写,比如DEV、OPS、CS。Key全局唯一,且建好后改动会让所有历史工作项编号前缀一起变,建议一次定好。

接下来还需要创建工作项

例如:编写 Windshift 安装教程

还可以设置更详细的子项、附件、说明等

更具体的使用请参考官方的说明文档
注意事项
/tmp的tmpfs不能省:镜像是scratch构建,里面没有/tmp目录。缺少这个挂载,大附件上传会在超出32 MiB内存阈值后写盘失败。必须用短语法- /tmp:exec,size=64M,Docker默认的noexec会让git无法执行askpass辅助程序。- 明文 HTTP 只支持 localhost:
BASE_URL填http://192.168.0.100:8080时,容器能正常启动,但日志会报Failed to create CORS middleware ... insecure origin patterns,之后浏览器所有请求返回CORS_CONFIG_ERROR。两种解法:加反向代理做HTTPS(推荐),或在内网可信环境下显式开启ALLOW_INSECURE_HTTP=true。 - Passkey 与 PWA 需要 HTTPS:明文
HTTP下账号密码登录正常,但Passkey注册、PWA安装、Web Push推送都无法使用,因为浏览器要求安全上下文,且裸IP不是合法的RP ID。 USE_PROXY只在有反代时为 true:为true会信任X-Forwarded-Proto和X-Forwarded-For,直接暴露端口时可被伪造,导致IP限流与安全日志失真。用Traefik/Nginx时改为true,并停止对外暴露8080。- 备份
/data整个目录:SQLite模式下数据库、附件、插件、生成的VAPID密钥都在同一个卷里。用PostgreSQL也别漏了附件目录,数据库备份不能覆盖它。 - 内存给足 2G:看板、树视图、
SSE长连接都比较吃内存。1G能跑起来,但几十人同时在线会开始换页。WINDSHIFT_MEMORY_LIMIT_MB与容器的mem_limit要成对调整。 pull_policy: always的意义:如果跟随main这类可变tag,Dokploy等平台执行compose up -d前不会自动pull,可能一直跑旧镜像。固定版本号(如v0.9.1)最稳。- 中文界面已内置:九种语言里包含简体中文,登录后在个人设置里切换,不需要额外装语言包。
参考文档
Windshiftapp/core: Self-hosted, open-source work management platform and Jira alternative (AGPL v3)
地址:https://github.com/Windshiftapp/coreWindshift 官方网站
地址:https://windshift.shDocker 部署文档(含反向代理、PostgreSQL、WebAuthn 说明)
地址:https://windshift.sh/self-hosting/02-deployment/01-docker配置项完整说明(环境变量与命令行参数对照)
地址:https://windshift.sh/self-hosting/03-configuration/01-options