本文基于docker-compose来集中管理多个容器的部署,记录一下在docker部署nacos的方法以及遇到的问题。
Nacos镜像
直接采用官方提供的 nacos/nacos-server
即可,如果有特殊需要,可以自行编写Dockerfile实现。
MySQL镜像
由于nacos需要使用已经预填充数据表的mysql,而nacos官方已经提供了对应的sql文件,现在我们需要在mysql容器初始化时将nacos相关的数据表填充到数据库中。
预填充数据
下面使用 mysql:8.3
容器进行演示。
在这个容器的 layers 中发现,有一行 ENTRYPOINT ["docker-entrypoint.sh"]
,在容器文件中找到这个脚本,其部分内容如下:
_main() {
# if command starts with an option, prepend mysqld
if [ "${1:0:1}" = '-' ]; then
set -- mysqld "$@"
fi
# skip setup if they aren't running mysqld or want an option that stops mysqld
if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
mysql_check_config "$@"
# Load various environment variables
docker_setup_env "$@"
docker_create_db_directories "$@"
# If container is started as root user, restart as dedicated mysql user
if [ "$(id -u)" = "0" ]; then
mysql_note "Switching to dedicated user 'mysql'"
exec gosu mysql "$BASH_SOURCE" "$@"
fi
# there's no database, so it needs to be initialized
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
docker_verify_minimum_env
# check dir permissions to reduce likelihood of half-initialized database
ls /docker-entrypoint-initdb.d/ > /dev/null
docker_init_database_dir "$@"
mysql_note "Starting temporary server"
docker_temp_server_start "$@"
mysql_note "Temporary server started."
mysql_socket_fix
docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
mysql_expire_root_user
mysql_note "Stopping temporary server"
docker_temp_server_stop
mysql_note "Temporary server stopped"
echo
mysql_note "MySQL init process done. Ready for start up."
echo
else
mysql_socket_fix
fi
fi
exec "$@"
}
注意到其中有一部分是在容器初始化时检查某个文件夹内的sql文件并且自动执行其中的sql语句,这个文件夹就是 docker-entrypoint-initdb.d
。
也就是说只需要把我们需要预填充的数据放入容器根目录下的 /docker-entrypoint-initdb.d
文件夹内即可。
Dockerfile
有了上面的分析很快就能写出对应的Dockerfile
FROM mysql:8.3
LABEL authors="LovelyCat"
COPY nacos-preset.sql /docker-entrypoint-initdb.d/nacos-preset.sql
EXPOSE 3306
替换这里的 `nacos-preset.sql` 为对应的sql文件即可。
然后执行 docker build -t my-nacos-mysql .
,注意这里的标签是 my-nacos-mysql
,如果你改成其他名字,注意在下面的 docker-compose.yml
中也要一起修改。
Docker Compose
接下来是docker-compose.yml的编写:
version: '3'
services:
mysql:
image: my-nacos-mysql
container_name: mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=123456
healthcheck:
test: "/usr/bin/mysql --user=root --password=123456 --execute \"SHOW DATABASES;\""
interval: 3s
timeout: 1s
retries: 5
phpmyadmin:
image: phpmyadmin
container_name: mysql-web-manager
depends_on:
- mysql
ports:
- 8088:80
environment:
- PMA_ARBITRARY=1
nacos:
image: nacos/nacos-server
container_name: nacos
depends_on:
mysql:
condition: service_healthy
ports:
- 8848:8848
- 9848:9848
- 9849:9849
- 9555:9555
environment:
- MODE=standalone
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=123456
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_DB_PARAM=allowPublicKeyRetrieval=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
接着执行 docker-compose up -d
启动即可,进入nacos容器,看到 2024-06-23 15:39:54,106 INFO Nacos started successfully in stand alone mode. use external storage
的字样说明已经成功启动了。
同时我还添加了一个 phpmyadminn 用于快速管理 mysql 数据库,直接访问 `http://localhost:8088` 即可,服务器填 mysql 容器的名称即可。
常见问题
Public Key Retrieval is not allowed
在nacos官方提供的 application.yaml
中的mysql-url的参数中不包括 allowPublicKeyRetrieval
参数,但是可以通过环境变量 MYSQL_SERVICE_DB_PARAM
手动注入。
在上面的 docker-compose.yml
中我已经加上了,如果没有则会出现该错误。