资讯动态

Docker Compose一键部署Jira Software:编排设计、权限处理与故障排查指南

发布时间:2026/10/19 6:04:57 来源:尧图企业网站定制
前一阵帮几个小团队把 Jira Software 从手动安装的服务器迁到 docker-compose 管理折腾了几天踩了不少坑也把整套流程理顺了。标题里说的“一键部署”严谨一点讲是把基础服务一键拉起来——第一次初始化向导还是需要人工点几下因为业务数据模型需要确认但之后重建环境、迁移服务器、日常启停确实就是一条命令的事。这篇文章把我实际在用的 compose 方案、参数取舍和常见故障排查都记录下来给打算用容器部署 Jira 的团队一份能直接抄作业的参考。1. 先别急着敲命令想清楚这三个问题再动手1.1 单容器方案为什么总差一口气如果你只是在自己电脑上试用一条docker run就能把 Jira 跑起来官方镜像也没有问题。但放到团队环境里单容器方案的短板会很快暴露出来数据目录要不要挂载出来不挂载的话容器一删全没了。数据库怎么办Jira 自带的 H2 只适合试用多人同时用之后性能和稳定性都不够。宿主机重启之后容器能不能自动恢复--restart参数写没写环境变量、端口参数、数据卷散落在一条超长的docker run命令里几个月后自己都忘了当初是怎么配的。我见过有人把 Jira 跑在一个名字都记不清的容器里数据目录留在容器可写层某天清理 Docker 时随手docker rm了一下整个工单历史直接消失。这种事故不是个案。1.2 docker-compose 调度方案到底解决了什么docker-compose 说白了就是把“一组服务”的定义写成一份 YAML 文件交给 Docker 引擎统一拉起和管理。对 Jira 这种由“Web 应用 数据库 初始化任务”组成的场景来说它的价值非常具体服务之间通过内部网络互相访问Jira 连接数据库时直接写服务名postgres不需要猜 IP。端口映射、环境变量、数据卷挂载全部集中在一个文件里可评审、可版本化、可复制。换服务器时把 compose 文件和数据卷一搬一条docker compose up -d就能恢复业务。restart: always能保证宿主机重启后容器自动拉起不用人工干预。这种“配置即代码”的思路才是标题里“一键部署”成立的根本原因。1.3 什么场景不建议用 compose 硬扛startup 之前先把边界说清楚docker-compose 适合中小团队比如几十个人、并发在线使用不算夸张的场景一台 4 核 8G 的虚机完全够用。但如果你们已经有成熟的容器编排平台或者 Jira 要承载几百上千人的访问量那应该去看官方的 Helm/Operator 方案、外置负载均衡和高可用数据库而不是指望 compose 解决一切。另外提醒一句Jira 是商业软件部署前要准备正版授权码或官方试用授权。评估版 30 天自己测试没问题正式给团队用还是要走正常授权流程。2. 编排文件设计镜像、数据卷、初始化容器逐个说2.1 服务拆成三个角色依赖关系怎么定我用的方案里总共三个服务分工非常清楚服务名角色说明postgres元数据库存工单、项目、权限等结构化数据jira-init一次性初始化任务提前把数据卷权限准备好然后退出jiraJira 主应用Web 界面、附件、索引都在这个容器里为什么要专门塞一个 init 服务这是 compose 方案里最容易忽略、也最容易导致启动失败的细节。Jira 官方镜像里进程以 UID 2001 的用户身份运行而我们把./jira-home挂载进容器后这个目录在宿主机上的属主通常是 root。如果目录没有写权限Jira 启动时会因为无法读写配置目录而直接退出。init 容器的思路是用一个临时容器以 root 身份进入这个挂载目录把属主改成 2001然后退出。depends_on里让它先跑完Jira 再正式启动。这个容器我特别设置了restart: no它跑完就退出日志里看到Exited (0)属于正常现象不用慌。2.2 镜像版本和挂载目录怎么选才不坑自己镜像 tag 上我坚持一个原则绝不用 latest。latest标签随着官方更新会漂移上周还能用的配置下周升级完可能就不兼容了。实际推荐固定到具体版本号比如当前主流的 9.x 系列里挑一个稳定小版本。升级是主动操作不是被动踩雷。数据库镜像选了postgres:13-alpine体积小、内存占用低、启动快。选 13 是因为它在 Jira 官方兼容矩阵里表现很稳团队规模不大的情况下没必要去追最新大版本数据库。数据卷我用的是 bind mount也就是把宿主机的目录挂进去原因很朴素备份时能直接看到目录里的文件出问题时可以用常规的ls、du、tar去处理不需要钻进 Docker 的 volumes 目录里翻。./jira-home放 Jira 的配置、插件、附件、索引./pgdata放数据库文件。建议这两个目录放到不同磁盘或者至少确认磁盘余量充足——Jira 跑几个月之后附件和索引的增长速度比你预期得快。2.3 环境变量与 JVM 参数该给多少才合适官方镜像支持通过环境变量控制 JVM 参数核心的有三个JVM_MINIMUM_MEMORY初始堆大小JVM_MAXIMUM_MEMORY最大堆大小JVM_RESERVED_CODE_CACHE_SIZEJIT 编译缓存的预留空间默认值往往偏保守稍微多点并发就开始频繁 Full GC页面卡顿、接口超时都来了。我习惯在 4G 物理内存的机器上给 Jira 最大堆 2048m留出内存给 PostgreSQL 和操作系统如果机器内存到 8G可以再往上调。TZ要显式设成Asia/Shanghai不然容器默认 UTC日志时间和票面时间对不上排查问题会非常痛苦。3. 完整实操流程从空目录到可访问的 Jira3.1 准备阶段目录、网络、端口检查先确认环境要求 Docker Engine 20.10 以上并且用的是 docker-compose v2也就是集成在 Docker CLI 里的docker compose插件。老版本如果还停留在docker-composev1建议先升级因为后面会用到一个depends_on条件语法旧版不一定支持。在服务器上先建好工作目录并检查 8080 端口是否被占用mkdir -p /opt/jira-stack cd /opt/jira-stack ss -lntp | grep 8080 || echo 8080 is free如果端口被占后面可以映射成18080:8080但外部访问地址会变其它配置文件里也要跟着改建议一开始就确认好。3.2 编写 docker-compose.yml 并启动服务直接给一份我实际在用的完整配置services: postgres: image: postgres:13-alpine container_name: jira-postgres restart: always environment: POSTGRES_USER: jira POSTGRES_PASSWORD: 这里换成一个足够复杂的密码 POSTGRES_DB: jiradb volumes: - ./pgdata:/var/lib/postgresql/data networks: - jira-net jira-init: image: alpine:3.16 container_name: jira-init restart: no user: root volumes: - ./jira-home:/var/atlassian/application-data/jira command: /bin/sh -c mkdir -p /var/atlassian/application-data/jira chmod 700 /var/atlassian/application-data/jira chown -R 2001:2001 /var/atlassian/application-data/jira jira: image: atlassian/jira-software:9.12.5 container_name: jira restart: always depends_on: postgres: condition: service_started jira-init: condition: service_completed_successfully ports: - 8080:8080 environment: JVM_MINIMUM_MEMORY: 1024m JVM_MAXIMUM_MEMORY: 2048m JVM_RESERVED_CODE_CACHE_SIZE: 512m ATL_TOMCAT_PORT: 8080 TZ: Asia/Shanghai volumes: - ./jira-home:/var/atlassian/application-data/jira networks: - jira-net networks: jira-net: driver: bridge几个细节值得展开说POSTGRES_PASSWORD尽量用强密码别用123456这种PostgreSQL 在容器里默认只监听内网风险可控但密码管理习惯不值得冒险。depends_on里对postgres只要求服务已启动不需要等数据库就绪Jira 自身有重试机制数据库没完全初始化好时它会等一会。jira-init的condition: service_completed_successfully意思就是“必须成功退出后jira 再启动”。新版 compose 不要求写version字段写了反而不必要如果你还在用旧版docker-compose则需要加上version: 3.8。启动命令非常短docker compose up -d docker compose ps第一次会拉取镜像耐心等一下。启动过程中可以看日志确认没有报错docker compose logs -f jira看到类似Jira is starting...再到Server startup in xx ms表示应用容器起来了。此时 init 容器应该已经处于Exited (0)状态这是设计好的不用管它。3.3 通过安装向导完成数据库与站点配置浏览器访问http://服务器IP:8080会进入 Jira 的初始化界面。按下面的顺序操作选择语言选简体中文或英文都可以之后也能改。数据库类型选 PostgreSQL。关键一步数据库主机名填postgres不是localhost也不是 IP。因为 Jira 容器和 PostgreSQL 容器跑在同一张 Docker 桥接网络里服务名postgres就是可解析的主机名。填写数据库名jiradb、用户名jira、密码为前面 compose 里设置的值。点击测试连接确认后继续。设置站点标题和基础 URL。基础 URL 要填外部实际能访问的地址比如http://你的服务器IP:8080如果后面套了域名就填域名否则邮件通知里的链接全是错的。选择应用模式。生产团队选“生产”试用自己玩可以选“演示”演示模式会写入一批示例数据。等待数据库初始化完成这一步快则两三分钟慢则五分钟以上不要中途刷新页面。授权页面选择“评估版”或输入正式授权码。创建管理员账号完工。新手最容易卡在数据库主机名这一步。填localhost必错因为那指向的是 Jira 容器自己内部的回环地址里面并没有 PostgreSQL。3.4 验证部署状态与第一次完整备份初始化完成后建议做两层验证。一是确认 Web 界面能正常登录、创建项目二是看一眼健康状况curl -s http://localhost:8080/status这个接口正常会返回 JSON包含state、version之类的信息能看到运行中就算基本稳了。部署“成功”的验收标准我习惯再加一条能不能执行一次完整备份。第一次备份能成功以后才有底气做升级和迁移。我常用的备份方式是停掉 Jira保留数据库然后打包数据目录再备份数据库docker compose stop jira docker run --rm \ -v $(pwd)/jira-home:/data \ -v $(pwd)/backup:/backup \ alpine tar czf /backup/jira-home-$(date %F).tar.gz -C /data . docker exec jira-postgres pg_dump -U jira -Fc jiradb | cat ./backup/jiradb-$(date %F).dump docker compose start jira这里用临时 alpine 容器打包而不是直接在 Jira 容器里执行 tar是为了不触发应用自身的启动逻辑打包过程更干净。数据库的pg_dump -Fc是自定义格式恢复时用pg_restore对应处理比纯 SQL 方式更灵活也支持选择性恢复。4. 半年多维护下来最常踩的几个坑4.1 权限问题init 容器没生效就是最常见的启动失败原因实际部署中遇到最多的问题就是 Jira 容器启动后立刻退出日志里满屏Permission denied。原因基本都是./jira-home目录属主不对。init 容器虽然写了 chown但如果宿主机上原来已经手动创建过这个目录或者之前用 root 往里面放过文件再或者一个目录同时被多个容器反复挂载权限就乱了。处理方式不复杂chown -R 2001:2001 ./jira-home docker compose restart jirachmod 700就够了不要图省事改成777。Jira 的数据目录里含账号相关配置777会让宿主机上任何用户都能读没必要承担这种风险。4.2 内存不够导致的“半夜崩掉”Jira 是 Java 应用对内存的敏感度很高。默认 JVM 参数较小如果你们团队规模超过十个人建议直接按前面配置里的数值设置。内存不足最典型的现象是白天在线人数一多就卡或者凌晨索引重建、备份任务运行时容器被 OOM Kill。判断方法docker compose logs jira | grep -i native memory\|OutOfMemoryError\|Killed free -h解决方案就两条要么给机器加内存要么调低同时在线用户数/限制附件上传大小。JVM 在容器里不是配置调大就一定有性能物理内存不够时堆大小给的再高也会被内核杀掉。4.3 数据库连不上先看服务名和密码别急着改驱动初始化向导里最常见的问题是数据库连接测试失败。排查看三件事docker compose ps确认 postgres 容器状态是 Up。在向导里确认主机写的是postgres不是localhost。确认密码和 compose 里POSTGRES_PASSWORD一致。至于数据库驱动新版官方镜像基本已经内置了 PostgreSQL 驱动不需要手动把 jar 文件塞到容器的 lib 目录里。很多人遇到连接失败第一反应是“驱动版本不够”其实九成情况是上面三个原因。有个小技巧直接进数据库容器里看能不能连上能快速缩小排查范围docker exec -it jira-postgres psql -U jira -d jiradb -c select 1;4.4 升级陷阱先备份再动 tag最后看日志Jira 升级看起来很简单把 compose 里的镜像 tag 换成新版本然后docker compose up -d。但实际操作有讲究升级前必须做一次完整备份备份方式参照 3.4不能跳。跨大版本升级比如 8.x 到 9.x时Jira 有官方的升级路径要求有些版本不能一次跳太多得先升到中间版本再往上升。升级过程中不要动数据库也不要并发执行其它备份任务。如果升级失败最稳妥的回滚方式是改回原 tag恢复备份的数据库和数据目录再启动一遍。我把升级失败造成的教训记录得比较深刻。有次在测试环境偷懒没备份升级到一半插件不兼容Jira 直接起不来了。当时数据库虽然没坏但数据目录的配置已经被新版本改写了折腾了大半天才恢复到可用状态。从那以后只要是动版本号无论测试还是生产备份一步都不敢少。下面把几个高频问题整理成一张速查表方便遇到问题时对着查症状典型日志处理方式容器反复重启Permission denied检查 init 容器状态手动 chown 数据目录页面极卡/接口超时Full GC、OutOfMemoryError上调 JVM 堆内存检查宿主机物理内存向导里数据库连接失败connection refused确认数据库容器存活主机名用服务名检查密码升级后起不来Plugin 版本不兼容、db schema 版本低按官方升级路径逐级升先恢复备份邮件里的链接打不开无报错但链接指向 localhost修改基础 URL或检查反向代理转发配置如果你还在管理多套环境强烈建议把 compose 文件交到版本仓库里密码用环境变量注入而不是直接写在文件里。这样团队成员拿到仓库后一条命令就能拉起一套独立测试环境业务同学在测试环境乱点时也不会影响生产数据。最后说点个人体会docker-compose 部署 Jira Software 本身不难难的是把它当成一件需要长期维护的事。我踩过最贵的坑就是升级前心存侥幸跳过备份结果中途失败。所以建议每个团队把“部署后立即做一次完整备份、升级前再做一次”写进操作手册别等关键时刻才想起来。这套方案如果在你的环境里遇到别的问题按日志关键词逐层排查通常都能很快定位。运维的事本来就是一点一点磨出来的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑