Nacos + MySQL + Docker
一、配置一览
1、镜像构建相关文件
之前使用 PostgreSQL 作为数据源需要自己构建镜像,并添加 PostgreSQL 数据源插件,因为 MySQL 是官方默认支持的数据源,所以可以直接使用官方镜像,取代手动构建:nacos-server image | hub.docker.com
1.1 选择使用 MySQL 作为数据源
Nacos 可以使用内置数据源,内置数据源不需要做任何配置,也可以配置外置数据源,默认的是 MySQL。
生产使用建议至少主备模式,或者采用高可用数据库。
选择使用 MySQL 作为数据源不需要做额外的配置,也不需要使用额外的插件。
之前在 Docker 中配置了 MySQL 主从环境,使用的是 MySQL 的 9.2.0 版本。
1.2 docker-startup.sh
| 1 | !/bin/bash | 
1.3 application.properties
application.properties 配置文件示例如下:
| 1 | # spring | 
配置文件中有许多环境变量,可以在启动容器时指定。
1.4 Dockerfile
远程下载 Nacos 安装包版本的 dockerfile 文件如下:
| 1 | FROM alpine:latest | 
远程下载为从 GitHub 上面下载,可能在一些网络环境中下载速度过慢,可以用本地的 Nacos 安装包来构建镜像:
| 1 | FROM alpine:latest | 
使用如下命令来构建 Docker 镜像:
| 1 | docker build -t z2huo/nacos-dev:2.4.2-alpine -f local-nacos-package.dockerfile . | 
2、容器相关文件
2.1 .env
| 1 | image=z2huo/nacos-dev:2.4.2-alpine | 
可以使用官方提供的镜像:
| 1 | image=nacos/nacos-server:v2.4.2.1 | 
2.2 nacos-cluster.env
支持的环境变量,可以查看:nacos-docker README | github
| 1 | MODE=cluster | 
2.3 cluster.conf
此配置文件需要直接挂载到容器中,或者直接使用环境变量 NACOS_SERVERS
| 1 | nacos-1:8848 | 
2.4 application.properties
如果有很多自定义配置的需求,建议直接对 application.properties 文件进行挂卷,取代使用环境变量。
2.4.1 通用配置
| 1 | #*************** Spring Boot Related Configurations ***************# | 
上面的配置文件中需要修改数据库配置:
| 1 | spring.datasource.platform=mysql | 
2.4.2 各个容器的配置
| 1 | spring.profiles.include=common | 
| 1 | spring.profiles.include=common | 
| 1 | spring.profiles.include=common | 
2.5 compose.yaml
2.5.1 挂载 application.properties 配置
| 1 | # 使用 application.properties 来配置容器 | 
Docker Compose 中的配置:
- 在 networks中定义的mysql-master-slave-net网络,该网络是之前在 Docker 中部署的 MySQL 主从复制容器所使用的桥接网络,该网络需要配置external: true表示使用的是当前 Compose 之外的网络。
- 挂载 application.properties配置文件,用来替代构建的镜像中的配置文件
- 不用挂载 cluster.conf文件,因为在docker-startup.sh文件中,print_servers方法中会向cluster.conf文件中写入内容。
- 需要暴露 4 个端口- 7848,Raft 集群通信端口,用于 Nacos 集群节点之间的 Raft 协议通信。Raft 是 Nacos 默认的集群选举和数据一致性协议,集群节点通过此端口进行 Leader 选举和日志复制。
- 8848,HTTP API 端口。提供主要的 HTTP API 服务接口,用于客户端与 Nacos 服务端之间的交互。涵盖服务注册、服务发现、配置管理等功能。
- 9848,服务健康检查端口。提供服务端的健康检查和监控接口。用于获取 Nacos 服务端的运行状态信息(如 CPU 使用率、负载、集群状态等)。
- 9849,Grpc 通信端口。用于 Nacos 内部服务和客户端之间基于 gRPC 协议的通信。支持更高效的长连接通信,特别是在 Nacos 2.x 中,gRPC 替代了部分 HTTP 通信,成为主要的注册与心跳通信协议。
 
如果你有很多自定义配置的需求,强烈建议在生产环境对
application.properties文件进行挂卷定义.
2.5.2 使用环境变量配置
| 1 | # 使用环境变量配置 | 
nacos-cluster.env 文件配置如下:
| 1 | MODE=cluster | 
2.6 MySQL Nacos DDL
建库语句如下:
| 1 | create database if not exists nacos | 
建表语句如下:
| 1 | /******************************************/ | 
二、部署过程
通过上面提供的 Dockerfile 构建 Nacos 镜像。
在 MySQL 中创建 Nacos 数据库,并执行建表语句。
执行 docker compose up -d 启动 Nacos 容器。
容器启动后,可以在容器中看到如下日志:
| 1 | 2025-05-03 04:49:30 ,--. | 
浏览器中访问 Nacos 地址 localhost: 8848/nacos,查看集群节点:
三、其他
1、MySQL 密码认证问题
启动容器后,容器日志中有异常如下:
| 1 | Caused by: com.mysql.cj.exceptions.UnableToConnectException: Public Key Retrieval is not allowed | 
是由于 MySQL 的安全认证机制与客户端配置不兼容导致的,在 Nacos 的 application.properties 配置文件中使用了明文密码。
MySQL 8+ 默认使用 caching_sha2_password 插件,该插件要求客户端在身份验证时通过 SSL/TLS 加密传输密码。若未启用 SSL 或未允许公钥检索,客户端无法获取服务器的公钥进行加密,从而触发此错误。
使用如下的数据库连接 URL:
| 1 | jdbc:mysql://mysql-master:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false | 
连接中添加额外的参数:
- allowPublicKeyRetrieval=true,允许客户端从服务器检索公钥。
- useSSL=false,禁用 SSL。
但是使用如上配置会降低安全性。
2、shell 脚本回车换行符问题
办公室的电脑是 Windows 的,默认使用的是 CRLF,Docker 容器中使用的 Linux,只支持 \n,不支持 \r\n,在 Windows 中构建镜像时,需要确认并修改一下 Shell 脚本的换行符类型为 LF 之后再构建镜像。否则在容器启动时执行 Shell 脚本时会有如下错误:
| 1 | : not foundbin/docker-startup.sh: line 6: | 
3、Nacos 服务接口占用问题
Nacos 服务端运行时,默认会占用多个端口,每个端口都有其特定用途。以 Nacos 默认的端口举例
- 8848,主端口号,通过 server.port配置属性指定,默认的管理控制台端口,用于服务注册、发现、配置管理的 RESTful API
- 9848,客户端 gRPC 请求,用于 Nacos 2.0+ 版本客户端与服务端之间的 gRPC 通信,由客户端主动发起连接
- 9849,服务端 gRPC 请求,用于 Nacos 2.0+ 版本集群模式下不同服务端节点之间的数据同步和通信
- 7848,Jraft 请求,用于 Nacos 集群模式下服务端节点间的 Raft 一致性算法通信(如选主、日志复制)
上面的端口号是根据 server.port 来计算的。
| 1 | package com.alibaba.nacos.api.common; | 
| 1 | package com.alibaba.nacos.common.remote.client.grpc; | 
| 1 | package com.alibaba.nacos.common.remote.client.grpc; | 
| 1 | package com.alibaba.nacos.common.remote.client.grpc; | 
所以在单机模式下部署 Nacos 集群,不能简单地为每个实例配置连续的主端口,比如选择的主端口号为:8848、8849、8850,因为这样会导致其他端口冲突。
在 Docker 容器中部署又有所不同,每个容器内部端口配置相同是不存在冲突的,但是需要将容器中的端口暴露给宿主机,此时如果暴露的端口和 Nacos 容器使用的端口不一致时,gRPC 客户端会连接不上服务端(不知道为啥,并且在 Dubbo 配置中暂时还没有找到指定与 Nacos 通信端口的配置),比如在 Dubbo 中使用 Nacos 作为配置中心、注册中心和元数据中心时。
例如容器端口映射如下:
| 1 | - "7848:7848" | 
客户端与服务端之间 gRPC 通信端口映射宿主机和容器中端口不匹配,比如 9868:9848 导致 Dubbo 客户端连接不到 Nacos,报错如下:
| 1 | o.a.d.c.s.n.NacosDynamicConfiguration : [DUBBO] Failed to create nacos config service client. Reason: server status check failed., dubbo version: 3.3.5, current host: 198.18.0.1, error code: 5-34. This may be caused by , go to https://dubbo.apache.org/faq/5/34 to find instructions. | 
相关链接
nacos-server image | hub.docker.com
OB links
[[Docker 中部署 Nacos 集群]]
[[CR、LF、CRLF]]
OB tags
#微服务 #SpringCloud #Docker #Nacos