公司 二开版 Nacos Docker 镜像构建
记录时间:2026-08-06
环境:Docker 20.10+ / Docker Compose / 信创 ARM64 + x86 混合部署
版本:Nacos 2.4.3 技术二开版背景:二开代码是技术直接丢过来的(仓库
http://192.168.111.14:9980/xxx/gzeportnacos),没给任何说明,只要求构建成 Docker 镜像。只能自己对着官方 nacos-docker 的构建方式搭,本文档按「编译 → 构建 → 运行」全流程整理,照着走就能复现,遇到问题看文末常见问题。
基于 Nacos 2.4.3 技术二开版(适配 Oracle/达梦/金仓等多数据库 + 定制”xxxx统一配置中心”控制台界面),构建方式对齐官方 nacos-docker v2.4.3。
与官方唯一差异:官方镜像通过 curl 下载官方编译好的 nacos-server.tar.gz,本二开版改为 COPY 本地编译产物 console/target/nacos-server.jar(二开 jar 必须由本项目源码编译产出)。
一、与官方 nacos-docker 的差异
镜像主体与官方 nacos-docker v2.4.3 一致,仅以下 4 处因二开需求调整:
| 位置 | 官方做法 | 二开做法 | 原因 |
|---|---|---|---|
Dockerfile |
curl 下载官方 nacos-server.tar.gz 解压 |
COPY console/target/nacos-server.jar |
二开 jar 必须由本项目源码编译产出 |
application.properties db 段 |
jdbc:mysql://${MYSQL_SERVICE_HOST}:port/db 拼接 |
${DB_URL} 整串占位 |
兼容 Oracle/达梦/金仓/MySQL,URL 格式各异,无法用 host/port 拼接 |
application.properties 鉴权忽略路径 |
/console-fe/public/** |
/console-ui/public/** |
二开前端目录名为 console-ui |
其余配置项(
server/auth/metrics/naming.distro/cmdb/console等)与环境变量均与官方完全一致。
二、目录结构
项目根/
├── .dockerignore # 构建上下文排除清单(排除大体积 tar.gz/zip、IDE、日志等)
└── build/
├── Dockerfile # 镜像构建文件(基于 alpine + openjdk8-jre)
├── bin/
│ └── docker-startup.sh # 启动脚本(源自官方,环境变量驱动)
├── conf/
│ └── application.properties # Docker 专用配置(主体对齐官方,db 段保留二开适配)
├── env/
│ └── nacos.env # 环境变量示例(数据库 / JVM / 鉴权)
├── docker-compose.yml # 单机编排示例(默认 Derby)
├── docker-compose-cluster.yml # 集群编排示例(3 节点)
├── docker-compose-mysql.yaml # 单机 + MySQL(无外部库时临时验证)
├── docker-compose-kb.yaml # 单机 + 金仓 Kingbase(外部库)
└── README.md # 本文档
镜像内布局(与官方一致,BASE_DIR=/home/nacos):
/home/nacos/
├── bin/docker-startup.sh
├── conf/application.properties
├── target/nacos-server.jar
└── logs/
三、前置条件
- 已安装 Docker(建议 20.10+)和 Docker Compose。
- 已完成源码编译,产出
console/target/nacos-server.jar。 - 数据库:默认使用内嵌 Derby(零依赖,无需额外准备)。若要切换外部数据库(Oracle/MySQL/达梦/金仓),需先建库并执行对应脚本(如 Oracle 用
distribution/conf/nacos-oracle.sql、MySQL 用mysql-schema.sql)。
四、编译源码(产出 nacos-server.jar)
在项目根目录执行:
⚠️ PowerShell 下
-D参数必须加引号,否则会被错误拆分(详见常见问题 Q1)。
# Windows PowerShell
mvn -Prelease-nacos "-Dmaven.test.skip=true" clean install -U
# Windows cmd / Linux bash
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
编译成功后确认产物存在:
Test-Path console\target\nacos-server.jar # 应输出 True
构建产物:console/target/ 与 distribution/ 两个 jar 的关系
编译后会出现两个 nacos-server.jar,它们是同一个文件(MD5 完全一致),只是位置和用途不同:
| 路径 | 身份 | 来源 |
|---|---|---|
console/target/nacos-server.jar |
源头 | console 模块 mvn package 直接产出(console/pom.xml 中 finalName=nacos-server) |
distribution/target/nacos-server-2.4.3/nacos/target/nacos-server.jar |
组装副本 | distribution 的 maven-assembly-plugin(release-nacos.xml)把上面的 jar 复制进发行包 |
distribution/.../nacos/是完整发行包目录(含bin/ conf/ target/jar LICENSE NOTICE),模拟官方nacos-server.tar.gz解压结构,供”传统 tar 包部署”使用;- 复制关系见
distribution/release-nacos.xml的<source>../console/target/nacos-server.jar</source>。
Docker 构建用 console/target/nacos-server.jar(本 Dockerfile 即采用此路径):路径短、不依赖 assembly 长路径、mvn package 即可产出;镜像的 bin/ conf/ 由 build/ 目录单独提供,不需要整个发行包。
验证两者一致性:
md5sum console/target/nacos-server.jar distribution/target/nacos-server-2.4.3/nacos/target/nacos-server.jar
五、构建镜像
在项目根目录(gzeportnacos-main/)执行:
docker build -f build/Dockerfile -t gzeport/nacos-server:2.4.3 .
-f build/Dockerfile:指定 Dockerfile 路径。-t gzeport/nacos-server:2.4.3:镜像名与标签,需与docker-compose.yml中的image一致。- 末尾
.:构建上下文为项目根目录(受.dockerignore约束)。
构建成功后确认镜像已生成:
docker images gzeport/nacos-server:2.4.3 # 应列出对应镜像及大小
多架构构建(buildx,amd64 + arm64)
如需同时产出 linux/amd64 与 linux/arm64 镜像(x86 服务器与 Apple Silicon / ARM 服务器混用),使用 docker buildx。
前提:Docker Desktop(Mac/Win)已内置 buildx 与跨架构模拟(qemu binfmt),可直接使用;Linux 需先开启 binfmt:
# 仅 Linux 需要;Mac/Windows Docker Desktop 可跳过
docker run --privileged --rm tonistiigi/binfmt --install all
创建 builder 并构建推送(多架构镜像必须 --push,不能 --load 到本地):
# 创建专用 builder(一次性)
docker buildx create --use --name multiarch --driver docker-container
# 多架构构建并推送,镜像名需带 registry 前缀
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f build/Dockerfile \
-t <你的registry>/gzeport/nacos-server:2.4.3 \
--push .
验证多架构产物:
docker manifest inspect <你的registry>/gzeport/nacos-server:2.4.3
# 输出应包含 "architecture": "amd64" 与 "arm64" 两个 platform
注意事项:
– arm64 构建慢 3~5 倍(qemu 模拟 apk install openjdk8),请耐心等待。
– 建议先单测 arm64 再合构建:docker buildx build --platform linux/arm64 -f build/Dockerfile -t test/nacos-arm64 .,确认能过 JDK 安装步骤。
– arm64 风险点:当前基础镜像 alpine + apk openjdk8-jre-base 在 arm64 上若报 JDK 安装失败,需切换到 eclipse-temurin:8-jre-alpine,详见常见问题 Q4。
六、运行
⚠️ 任何方式都必须传入
NACOS_AUTH_TOKEN(Base64,解码 ≥ 32 字节)。Nacos 2.2.1+ 启动时强制校验 token,缺失或过短会直接启动失败(与是否开启鉴权无关)。下列方式 A/B/C 均经env/nacos.env提供;方式 B2 演示用-e直接传入。
方式 A:docker-compose(推荐)
cd build
docker-compose up -d
查看日志 / 停止:
docker-compose logs -f
docker-compose down
compose 已内置健康检查(
/nacos/v1/console/health/readiness,间隔 10s,起始等待 30s),可用docker inspect或docker-compose ps观察状态。
方式 B:docker run(Linux)
# 方式 B1:用 env-file(推荐,NACOS_AUTH_TOKEN 等已在 env/nacos.env 配好)
docker run -d --name gzeport-nacos \
-p 8848:8848 -p 9848:9848 -p 9849:9849 \
--env-file build/env/nacos.env \
-e MODE=standalone \
gzeport/nacos-server:2.4.3
# 方式 B2:不挂 env-file,直接传关键变量(至少要有 NACOS_AUTH_TOKEN,否则启动失败)
docker run -d --name gzeport-nacos \
-p 8848:8848 -p 9848:9848 -p 9849:9849 \
-e MODE=standalone \
-e NACOS_AUTH_TOKEN=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkw \
gzeport/nacos-server:2.4.3
方式 C:集群模式(3 节点)
cd build
docker-compose -f docker-compose-cluster.yml up -d
集群模式要点:
– NACOS_SERVERS 已在 compose 中配置为三节点容器名(nacos1 nacos2 nacos3),容器间通过 Docker 内置 DNS 以 hostname 寻址。
– 三节点必须使用同一外部数据库(Oracle/MySQL/达梦/金仓,需在 env/nacos.env 配置 DB_* + DB_NUM=1),集群模式不支持 Derby 嵌入式存储。
– 仅 nacos1 映射宿主 8848/9848/9849,nacos2/nacos3 映射到 8858/9858、8868/9868 避免端口冲突。
– 节点扩缩容:修改 docker-compose-cluster.yml 增减 service,并同步更新每个节点的 NACOS_SERVERS。
访问控制台:http://localhost:8848/nacos (默认账号 nacos / nacos)
七、端口说明
| 端口 | 用途 |
|---|---|
| 8848 | HTTP 接口与 Web 控制台 |
| 9848 | 客户端 gRPC(Nacos 2.x 客户端主要通信端口,必须映射) |
| 9849 | 服务端间 Raft gRPC(集群模式需要) |
八、数据库配置
镜像内置 application.properties 主体对齐官方 nacos-docker v2.4.3(server / auth / metrics / naming.distro / cmdb / console 等配置项与环境变量完全一致),仅 db 连接段因二开需兼容 Oracle / 达梦 / 金仓 / MySQL 而保留整串 DB_URL 占位。官方为 MySQL 专属的 jdbc:mysql://${MYSQL_SERVICE_HOST}:... 拼接式,无法覆盖 Oracle 等 URL 格式。
默认行为:不配置任何 DB_* 变量时,Nacos 单机自动走内嵌 Derby(零依赖,对齐官方默认)。配置下列变量后才会启用外部数据库,无需重建镜像即可切换。
支持的数据库类型
| 数据库 | SPRING_DATASOURCE_PLATFORM |
DB_DRIVER |
建库脚本 | JDBC URL 示例 | 适用 |
|---|---|---|---|---|---|
| Derby(内嵌,默认) | 空(不配) | 不配 | derby-schema.sql(自动) |
不需要 | 单机零依赖,不支持集群 |
| MySQL | mysql |
com.mysql.cj.jdbc.Driver |
mysql-schema.sql |
jdbc:mysql://host:3306/nacos?... |
单机/集群 |
| Oracle | oracle |
oracle.jdbc.OracleDriver |
nacos-oracle.sql |
jdbc:oracle:thin:@host:1521:sid |
单机/集群 |
| 达梦 DM | dm |
dm.jdbc.driver.DmDriver |
nacos-dm.sql |
jdbc:dm://host:5236?schema=NACOS |
单机/集群 |
| 金仓 Kingbase | kingbase |
com.kingbase8.Driver |
nacos-kingbase.sql |
jdbc:kingbase8://host:54321/db?schema=NACOS&... |
单机/集群 |
所有外部数据库驱动(Oracle
ojdbc8+orai18n/ 达梦 / 金仓)均已通过 Maven 依赖打进nacos-server.jar,镜像内无需单独放置驱动。
建库 SQL 来源:本镜像 distribution/conf/ 已自带各库建库脚本。官方各数据库适配插件及最新 SQL 位于 nacos-group/nacos-plugin 仓库:
| 数据库 | 二开自带脚本(distribution/conf/) |
官方插件模块参考 |
|---|---|---|
| Derby | derby-schema.sql(内嵌自动初始化,无需手动执行) |
随 Nacos 主仓库 |
| MySQL | mysql-schema.sql |
随 Nacos 主仓库 |
| Oracle | nacos-oracle.sql |
nacos-oracle-datasource-plugin-ext/schema |
| 达梦 DM | nacos-dm.sql |
nacos-dm-datasource-plugin-ext/schema/nacos-dm.sql |
| 金仓 Kingbase | nacos-kingbase.sql |
nacos-kingbase-datasource-plugin-ext/schema |
其他国产库(SQL Server / OceanBase / openGauss / 虚谷 / 崖山等)可在该仓库找到对应
nacos-{db}-datasource-plugin-ext模块的schema/目录。
启用外部数据库(除 Derby 外)需配置以下变量:
| 环境变量 | 默认值(Derby 模式下为空) | 说明 |
|---|---|---|
DB_NUM |
0 |
>0 才启用外部存储;Derby 模式保持 0 |
SPRING_DATASOURCE_PLATFORM |
空 | 数据库平台:oracle / mysql / dm / kingbase |
DB_URL |
空 | JDBC 连接串 |
DB_USER |
空 | 数据库用户名 |
DB_PASSWORD |
空 | 数据库密码 |
DB_DRIVER |
org.apache.derby.jdbc.EmbeddedDriver |
JDBC 驱动类(外部库必须配,官方要求;Derby 模式默认内嵌驱动) |
DB_CONNECTION_TEST_QUERY |
空 | 连接探活 SQL(可选) |
Derby 模式下
DB_DRIVER默认内嵌驱动;切换外部库时必须配置DB_DRIVER(官方文档 要求driverClassName必填)。
切换到 MySQL 的示例(修改 env/nacos.env):
DB_NUM=1
SPRING_DATASOURCE_PLATFORM=mysql
DB_URL=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
DB_USER=root
DB_PASSWORD=your_password
DB_DRIVER=com.mysql.cj.jdbc.Driver
DB_CONNECTION_TEST_QUERY=SELECT 1
达梦 / 金仓同理,驱动已打进
nacos-server.jar,切换平台 + URL + 驱动即可。
参考文档
- 多数据源 / 数据源插件配置(
db.num>1、driverClassName、spring.sql.init.platform等说明):Nacos 数据源插件官方文档 - 其他国产数据库(达梦、人大金仓等)适配参考:Nacos 用户问题历史 – 国产数据库
九、关键环境变量(节选)
| 变量 | 默认值 | 说明 |
|---|---|---|
MODE |
cluster |
启动模式,单机必须设为 standalone |
NACOS_APPLICATION_PORT |
8848 |
Nacos HTTP 端口(对齐官方) |
SERVER_SERVLET_CONTEXTPATH |
/nacos |
Web 上下文路径(对齐官方) |
PREFER_HOST_MODE |
ip |
集群寻址 ip / hostname |
NACOS_SERVERS |
空 | 集群节点列表,空格分隔,如 ip1:8848 ip2:8848 |
JVM_XMS / JVM_XMX / JVM_XMN |
1g / 1g / 512m |
堆内存参数 |
NACOS_AUTH_ENABLE |
false |
是否开启鉴权 |
NACOS_AUTH_TOKEN |
空 | 鉴权 Token(Base64),开启鉴权时必须设置 |
NACOS_AUTH_IDENTITY_KEY / VALUE |
空 | 服务端身份标识,开启鉴权时必须设置 |
完整变量列表参考 官方属性配置列表。
十、常见问题
Q1:PowerShell 执行 mvn 报 Unknown lifecycle phase ".test.skip=true"
PowerShell 会把 -Dmaven.test.skip=true 错误拆分。解决:给 -D 参数加引号,或用 --% 停止解析:
mvn -Prelease-nacos "-Dmaven.test.skip=true" clean install -U
# 或
mvn --% -Prelease-nacos -Dmaven.test.skip=true clean install -U
Q2:容器启动报 bin/docker-startup.sh: not found 或 \r 相关错误
Windows 下 git 可能将 *.sh 换行转成 CRLF。本 Dockerfile 已内置 sed -i 's/\r$//' 兜底,正常不触发;若仍出现:
# 建议在 .gitattributes 中固定 *.sh 为 LF,或执行 dos2unix
dos2unix build/bin/docker-startup.sh
Q3:启动卡住或报数据库连接失败(如 ORA-12541、[db-load-error])
确认数据库实例可达、账号密码正确、对应建库脚本已执行(Oracle 用 nacos-oracle.sql、MySQL 用 mysql-schema.sql)。容器内可 docker exec -it gzeport-nacos sh 排查。若暂无外部数据库,单机模式默认走内嵌 Derby(零依赖),无需任何 DB 配置。
Q4:多架构构建 arm64 报 openjdk8-jre-base 安装失败
当前基础镜像 alpine + apk openjdk8-jre-base(对齐官方)。alpine 的 openjdk8 在 arm64 可能不可用,切到多架构原生 JDK 镜像:
FROM eclipse-temurin:8-jre-alpine # 替换 alpine:latest
RUN apk add --no-cache curl iputils ncurses vim libcurl bash # 删去 openjdk8-jre-base
ENV JAVA_HOME=/opt/java/openjdk # temurin 路径
ENV JAVA=/opt/java/openjdk/bin/java
其余 COPY、启动脚本、配置无需改动,nacos-server.jar 是 Java 字节码,天然跨架构。
实测 amd64/arm64 下
apk openjdk8-jre-base均安装成功,本节作兜底方案保留。
Q5:启动报 Failed to load driver class / db.pool.config 绑定 HikariDataSource 失败
根因:db.pool.config.driverClassName 值为空字符串,HikariCP 的 setDriverClassName("") 抛异常。官方数据源插件文档明确:外置数据库必须配置 driverClassName(PostgreSQL/Oracle 示例均显式配置)。
本镜像处理(兼顾 Derby 默认与外部库必填):
db.pool.config.driverClassName=${DB_DRIVER:org.apache.derby.jdbc.EmbeddedDriver}
- Derby 内嵌模式(
DB_NUM=0,默认):DB_DRIVER不配 → 默认org.apache.derby.jdbc.EmbeddedDriver(nacos-server.jar 自带),HikariCP 正常 - 外部库(
DB_NUM=1):必须用DB_DRIVER指定驱动类(如oracle.jdbc.OracleDriver),满足官方必填要求
遇到的问题:曾尝试删除 driverClassName 行(以为 HikariCP 能按 URL 自动推断驱动),Derby 模式虽可启动,但违背了官方对外部库的必填要求。最终纠正为”默认 EmbeddedDriver + DB_DRIVER 覆盖”:Derby 模式有有效默认值不报错,外部库显式配 DB_DRIVER 满足官方要求。
排查:若仍报错,检查 DB_DRIVER 拼写、对应驱动是否打进 jar(Oracle/达梦/金仓驱动已在 nacos-server.jar)。