OneDev Docker Compose 部署指南
在 Docker 化的 Ubuntu 22.04 服务器上用 Docker Compose 部署 OneDev 16.9.3:镜像选型、持久化、免交互初始化、JVM 配置、备份与版本升级全流程实测。
OneDev Docker Compose 部署指南
> 目标:在装有 Docker 的 Ubuntu 22.04 服务器上,用 Docker Compose 一键部署 OneDev 16.9.3,完成数据持久化、首启初始化、日常运维与版本升级。全文命令与回显均在 Docker 29.8.1 + Compose v5.5.1 环境实测通过。
一、环境信息
本文实测环境:
- 操作系统:Ubuntu 22.04(x86_64)
- Docker:29.8.1(Server 版本,
docker version --format 'Docker {{.Server.Version}}'实测输出) - Docker Compose:v5.5.1(
docker compose version实测输出) - OneDev 镜像:
1dev/server:16.9.3(与latest同为 digest 镜像bd6762b58343,体积 1.33GB,实测docker images输出) - 宿主机端口规划:HTTP
6630→ 容器6610,SSH6631→ 容器6611 - 数据目录:
/opt/data/onedev-compose/data(挂载到容器/opt/onedev) - 部署目录:
/opt/data/onedev-compose(存放docker-compose.yml)
二、镜像选型说明
官方镜像仓库为 Docker Hub 的 1dev/server,提供版本号 tag(如 16.9.3)与滚动 tag latest。实测两者当前指向同一镜像 ID bd6762b58343:
$ docker images 1dev/server
REPOSITORY TAG IMAGE ID SIZE
1dev/server 16.9.3 bd6762b58343 1.33GB
1dev/server latest bd6762b58343 1.33GB
选型建议:生产固定版本号 tag(如 16.9.3),升级动作显式可控;latest 适合临时验证,随官方发版漂移(OneDev 发版频率很高,实测 2026-10-02 至 10-17 的 16 天内发布 10 个版本),用 latest 意味着每次 pull 都可能引入行为变化。
💡 说明:镜像内置 JRE 17 与 Git,宿主机不需要安装 Java;镜像首次启动会把发行包自解压到挂载的数据目录(见第四章 4.3 节实测日志),因此数据目录挂载是必需项而非可选项。
三、前置条件
- 服务器已安装 Docker 与 Compose 插件,实测版本确认命令:
$ docker version --format 'Docker {{.Server.Version}}'
Docker 29.8.1
$ docker compose version
Docker Compose version v5.5.1
- 规划好的两个宿主端口未被占用(本文用
6630/6631,避免与常见服务冲突):
ss -lntp | grep -E ':6630|:6631' || echo "端口空闲"
-
资源预留:官方口径 OneDev 在 2 核 2GB 机器上即可流畅运行;数据目录所在分区按「Git 仓库 + 构建日志 + 数据库」的体量预留,起步 20GB。
-
镜像拉取(约 1.33GB,国内网络慢时可为 Docker 守护进程配置镜像加速或代理):
docker pull 1dev/server:16.9.3
四、部署步骤
4.1 编写 docker-compose.yml
创建部署目录并写入编排文件(实测使用的原文):
mkdir -p /opt/data/onedev-compose
vi /opt/data/onedev-compose/docker-compose.yml
services:
onedev:
image: 1dev/server:16.9.3
container_name: onedev-compose
restart: unless-stopped
ports:
- "6630:6610"
- "6631:6611"
volumes:
- /opt/data/onedev-compose/data:/opt/onedev
逐项解释:
image:固定版本号 tag,生产不追latest;container_name:固定容器名,便于docker logs/exec定位;restart: unless-stopped:宿主机重启后自动拉起(手动docker stop除外);ports:宿主6630映射容器 HTTP6610,宿主6631映射容器 SSH6611(Git over SSH);端口可按需调整宿主侧数字;volumes:把宿主目录挂载为容器内/opt/onedev,全部运行数据(数据库、Git 仓库、日志、构建工作区)落在宿主文件系统。
⚠️ 注意:官方
docker run方式会额外挂载宿主/var/run/docker.sock(用于「容器型作业执行器」调度宿主 Docker)。若不在 compose 里挂它,OneDev 照常运行,但容器型作业执行器不可用,构建请走server-shell执行器(在构建规范的命令步骤设runInContainer: false)或远程 agent——这也是本指南实测采用的执行方式。
4.2 启动服务
cd /opt/data/onedev-compose
docker compose up -d
确认状态(实测输出):
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
onedev-compose 1dev/server:16.9.3 "/root/bin/entrypoin…" onedev 2 hours ago Up 2 hours 0.0.0.0:6630->6610/tcp, [::]:6630->6610/tcp, 0.0.0.0:6631->6611/tcp, [::]:6631->6611/tcp
4.3 首次启动:发行包落盘与初始化
首次启动有一个数据目录填充过程:镜像内 /app 的发行包会被复制到挂载卷 /opt/onedev。实测 docker logs onedev-compose 开头 8 行:
11:19:50 INFO - Launching application from '/app'...
11:19:50 INFO - Starting application...
11:19:51 INFO - Populating /opt/onedev...
11:19:52 INFO - Successfully populated /opt/onedev
11:19:52 INFO - Stopping application...
11:19:52 INFO i.onedev.commons.bootstrap.Bootstrap - Launching application from '/opt/onedev'...
11:19:52 INFO io.onedev.commons.loader.AppLoader - Starting application...
11:19:54 INFO io.onedev.server.OneDev - Starting cluster
之后应用改为从 /opt/onedev 启动,全部数据落盘宿主目录。约半分钟后服务就绪,实测确认:
$ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:6630
200
数据目录随即出现完整发行结构(实测 ls /opt/data/onedev-compose/data):
3rdparty-licenses agent bin boot conf incompatibilities IN_DOCKER
internaldb lib license.txt logs readme.txt release.properties
site temp test
💡 说明:由于未配置免交互初始化变量(见第六章),服务就绪后日志会出现等待初始化的提示(实测原文):
WARN - Please set up the server at http://localhost:6610——这是正常现象,表示等待浏览器向导。
4.4 浏览器初始化向导
浏览器访问 http://<服务器IP>:6630,按向导完成初始化:
- 设置管理员账号:登录名、密码、邮箱;
- 选择数据库:试用保持默认内嵌数据库;生产建议选 MySQL/PostgreSQL/MariaDB 并填连接信息;
- 确认服务器 URL:填
http://<服务器IP>:6630(保持与外部访问端口一致,否则 Git clone 地址与 Webhook 回调会指向错误端口)。
向导完成后进入主界面,即与裸机部署的 OneDev 完全同构。
五、数据持久化说明
OneDev 的全部状态都落在挂载目录 /opt/data/onedev-compose/data:
| 子目录/文件 | 内容 | 是否需要备份 |
|---|---|---|
internaldb/ | 内嵌 HSQLDB 数据文件 | 是(或改用外接库) |
site/ | Git 裸仓、构建日志、附件 | 是 |
conf/ | server.properties、hibernate.properties、wrapper.conf | 是 |
db-backup/ | backup-db.sh 生成的备份 zip | 建议外传 |
logs/ | server.log 等运行日志 | 按需 |
temp/ | 构建工作区(用后即清) | 否 |
迁移整站 = 拷走整个 data 目录:在新机器上用同一份 compose 文件启动(数据目录指向拷贝来的目录),所有项目、构建历史、账号原样恢复。注意容器内端口恒为 6610/6611,迁移后只需改 compose 的宿主端口映射。
数据库备份用发行包自带脚本在容器内执行,必须显式指定备份文件路径(实测无参执行会直接报错:Missing backup file parameter. Usage: backup-db.sh <path to database backup file>)。实测完整执行:
docker exec onedev-compose /opt/onedev/bin/backup-db.sh /opt/onedev/db-backup/backup-$(date +%Y%m%d%H%M%S).zip
实测输出尾部(逐表导出 XML 后打包):
13:21:57 INFO - Exporting table 'EntityIdCounter'...
13:21:57 INFO - Converting table rows to XML...
13:21:57 INFO - Writing resulting XML to file 'EntityIdCounters.xml...
13:21:57 INFO -
13:21:57 INFO - Database is successfully backed up to /opt/onedev/db-backup/backup-20261017212150.zip
13:21:57 INFO - Stopping application...
宿主侧即可看到产物(实测):
$ ls -la /opt/data/onedev-compose/data/db-backup/
-rw-r--r-- 1 root root 14530 10月 17 21:21 backup-20261017212150.zip
⚠️ 注意:
backup-db.sh执行完毕会自动停止应用(日志尾部Stopping application...是脚本行为,不是故障)。compose 场景下执行完执行docker compose restart拉起服务(实测重启后curl http://localhost:6630返回 200)。该脚本只备份数据库;Git 仓库与构建日志在site/,完整灾备要「备份 zip + data 目录」两件套。
六、环境变量表
OneDev 镜像支持两组环境变量,均在 docker-compose.yml 的 environment: 段注入。
免交互初始化(首次启动前设置,仅初始化时生效):
| 变量名 | 必填 | 说明 |
|---|---|---|
initial_user | 是 | 管理员登录名 |
initial_password | 二选一 | 管理员密码(或用 initial_password_file) |
initial_password_file | 二选一 | 存放密码的文件路径 |
initial_email | 是 | 管理员邮箱 |
initial_server_url | 是 | 服务器对外根地址,需以 http:// 或 https:// 开头 |
initial_ssh_root_url | 否 | SSH 根地址(ssh://<host>:<port> 形式),留空则从 server_url 推导 |
设置后首次启动跳过浏览器向导,直接完成初始化,适合脚本化交付。
外接数据库(改用外部 MySQL/PostgreSQL/MariaDB 时设置):
| 变量名 | 示例值 |
|---|---|
hibernate_dialect | org.hibernate.dialect.MySQL5InnoDBDialect(MySQL/MariaDB);PostgreSQL 必须用 OneDev 自带方言 io.onedev.server.persistence.PostgreSQLDialect |
hibernate_connection_driver_class | com.mysql.cj.jdbc.Driver(MySQL)/ org.postgresql.Driver |
hibernate_connection_url | jdbc:mysql://数据库地址:3306/onedev?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false |
hibernate_connection_username | 数据库账号(需建表权限) |
hibernate_connection_password | 数据库密码(或 hibernate_connection_password_file 指向密码文件) |
⚠️ 注意:连接串不要省略端口号;外接库需预先创建空库(OneDev 自动建表)。改环境变量后需
docker compose up -d重建容器生效。
七、配置参数说明
容器化部署后,运行期配置在挂载目录内维护,改完 docker compose restart 生效:
data/conf/server.properties:服务端口与集群参数。实测内容(挂载后自动生成):
http_host=0.0.0.0
http_port=6610
ssh_port=6611
cluster_port=5710
容器内端口不要改(镜像入口按 6610 探活),要改对外端口只动 compose 的 ports: 宿主侧;server_name 可留空(默认用主机名)。
data/conf/wrapper.conf:JVM 参数。默认堆上限为物理内存 50%(set.default.max_memory_percent=50);固定堆写法(实测有效):
wrapper.java.initmemory=256
wrapper.java.maxmemory=512
修改后在容器内验证生效值:
docker exec onedev-compose ps -ef | grep [j]ava
# 输出中应出现 -Xms256m -Xmx512m
data/conf/hibernate.properties:未通过环境变量指定外接库时,可直接改此文件切换数据库(注释/解注释对应段落)。
八、配置文件挂载
除整目录挂载外,也可只挂单个配置文件精细控制,例如把调优好的 JVM 配置与数据分离管理:
volumes:
- /opt/data/onedev-compose/data:/opt/onedev
- /opt/data/onedev-compose/conf/wrapper.conf:/opt/onedev/conf/wrapper.conf
挂载单文件时注意:宿主文件必须先于容器启动存在(否则 Docker 会建出同名目录导致启动失败);且首次填充完成后 conf/ 已在数据目录内,单文件挂载属于可选优化,整目录挂载(本文方案)已覆盖绝大多数场景。
九、等价 docker run
与本文 compose 等价的单命令启动方式(官方推荐形态):
docker run --name onedev -d --restart always \
-v /opt/data/onedev/data:/opt/onedev \
-p 6610:6610 -p 6611:6611 \
1dev/server:16.9.3
若需要容器型作业执行器,额外追加 -v /var/run/docker.sock:/var/run/docker.sock。两者的取舍:docker run 简单直接,适合单机快速验证;compose 把端口、目录、重启策略与后续扩展(外接数据库、agent 网络)声明式固化,便于长期维护与版本升级,生产建议 compose。
十、常用运维命令
以下命令均在实测环境验证可用:
# 状态查看
docker compose ps
# 实时日志(服务端启动/运行日志)
docker compose logs -f onedev
# 进入容器执行管理脚本(备份数据库,路径必填;执行完会自动停应用,需再 restart)
docker exec onedev-compose /opt/onedev/bin/backup-db.sh /opt/onedev/db-backup/backup-$(date +%Y%m%d%H%M%S).zip
docker compose restart
# 重置管理员密码(忘记密码时)
docker exec -it onedev-compose /opt/onedev/bin/reset-admin-password.sh
# 重启服务(改配置后)
docker compose restart
# 停止与启动
docker compose down # 停止并移除容器,data 目录保留
docker compose up -d # 重新拉起
版本升级流程(以 16.9.3 → 新版本为例,实测操作路径):
cd /opt/data/onedev-compose
docker exec onedev-compose /opt/onedev/bin/backup-db.sh /opt/onedev/db-backup/backup-$(date +%Y%m%d%H%M%S).zip # 1. 先备份
docker compose restart # 备份脚本会自动停应用,重启拉起
tar czf onedev-data-$(date +%F).tgz -C /opt/data/onedev-compose data # 2. 整目录冷备(可选但建议)
docker pull 1dev/server:<新版本号> # 3. 拉新镜像
# 4. 编辑 docker-compose.yml,把 image 的 tag 改为新版本号
docker compose up -d # 5. 重建容器,数据卷原样保留
docker compose logs -f onedev # 6. 观察启动与数据迁移日志
回滚 = 把 tag 改回旧版本号再 up -d,并视情况用第 1 步的备份包恢复数据库。
十一、常见问题
Q1:首次访问提示 "Please set up the server",是不是部署失败了?
不是。这是初始化向导等待提示(实测日志原文 WARN - Please set up the server at http://localhost:6610),按 4.4 节完成浏览器向导即可;若希望跳过向导,用第六章的 initial_* 免交互变量重建。
Q2:构建任务报无法调度到容器执行器?
compose 文件未挂载宿主 Docker socket 时,容器型作业执行器不可用。两种解法:挂载 /var/run/docker.sock;或保持现状,在构建规范命令步骤设 runInContainer: false 走 server-shell 执行器(实测可用,构建正常)。
Q3:宿主端口想换成 80/22 风格怎么办?
只改 compose ports: 的宿主侧数字(如 "80:6610"),容器内侧 6610/6611 不动;同时把向导/环境变量里的服务器 URL 端口改成新的宿主端口,避免 Git clone 地址错误。
Q4:升级后打不开或数据异常?
先看 docker compose logs -f onedev 的启动与数据库迁移日志;确认升级前做过 backup-db.sh;异常时回滚镜像 tag 并用备份包在容器内 restore-db.sh 恢复。
Q5:数据目录可以放 NFS/网络盘吗? 不建议。OneDev 对 HSQLDB 与 Git 对象库有本地文件语义假设(锁文件、fsync),网络盘容易出现锁异常;跨机迁移用「整目录拷贝 + 备份包」而不是共享盘。
十二、参考链接
- 官方镜像与 Docker 部署文档:https://docs.onedev.io/installation-guide/run-as-docker-container
- 官方网站与文档站:https://onedev.io / https://docs.onedev.io
- 源码仓库:https://github.com/theonedev/onedev
- 相关篇目:《OneDev 介绍与选型指南》《OneDev 16.9.3 核心原理详解》《Ubuntu 22.04 安装 OneDev 16.9.3 指南》
- 相关文档:《Forgejo 16.0 Docker Compose 部署指南》《Ubuntu 22.04 上用 Docker Compose 部署 n8n 2.43.7》《Kestra 2.0.6 Docker Compose 部署指南》