官方RocketMQ镜像启动服务失败
项目需要部署RocketMQ,于是找到了RocketMQ官方的Docker镜像,在启动的过程中发现,只要挂载宿主机目录,容器便无法正常启动,启动过程和容器日志均没有看到明显的报错,只看到 container STATUS: Exited (253) 1 second ago
原因
查看官方Dockerfile,可以看到在镜像中创建了一个名为rocketmq
的组和用户,并且gid和uid都指定3000
,并将RockerMQ目录的所属组和用户更改为rocketmq
用户。当需要将容器中RockerMQ目录中的文件或目录映射到宿主机中时,就必须保证指定的宿主机目录权限与容器中的一致,如果出现权限不一致的问题,就会导致容器启动失败的问题。
...
# 定义组名,用户名,并分配相应的ID
ARG user=rocketmq
ARG group=rocketmq
ARG uid=3000
ARG gid=3000
...
# 创建组和用户
RUN groupadd -g ${gid} ${group} \
&& useradd -u ${uid} -g ${gid} -m -s /bin/bash ${user}
...
# RockerMQ目录更改所属组和用户
RUN chown -R ${uid}:${gid} ${ROCKETMQ_HOME}
...
# 指定容器以哪个用户运行
USER ${user}
...
解决方法
更改宿主机挂载目录所属组和用户
在宿主机创建与容器中相同的组和用户,并设置gid和uid为3000。这里用户名不一定要一样,但是gid和uid必须要和容器中的一致,设置为3000。
# 创建组和用户
groupadd -g 3000 rocketmq
useradd -u 3000 -g 3000 -M -s /bin/bash rocketmq
# 修改宿主机挂载目录的所属组和用户
chown -R rocketmq:rocketmq data
重新制作Docker image
除了更改宿主机挂载目录所属组和用户,也可以通过重制镜像解决问题,稍修改下官方Dockerfile,去掉创建组,创建用户,RocketMQ目录授权,指定容器启动用户的部分,重新build即可,具体参考下面的Dockerfile。
Dockerfile
FROM openjdk:8-slim
ARG version
ENV ROCKETMQ_VERSION=${version}
ENV ROCKETMQ_HOME=/rocketmq
ENV MQ_SERVER_HEAP_OPTS="-Xms2g -Xmx2g"
ENV MQ_BROKER_HEAP_OPTS="-Xms4g -Xmx4g"
WORKDIR /
RUN apt-get update -y; \
apt-get install wget gpg unzip vim net-tools -y; \
wget -O rocketmq.zip https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip; \
wget -O rocketmq.zip.asc https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip.asc; \
wget -O KEYS https://www.apache.org/dist/rocketmq/KEYS; \
gpg --import KEYS; \
gpg --batch --verify rocketmq.zip.asc rocketmq.zip ; \
unzip rocketmq.zip ; \
mv rocketmq-${ROCKETMQ_VERSION} rocketmq; \
sed -i '/Xms/{s/-Xms4g -Xmx4g/${MQ_SERVER_HEAP_OPTS}/;}' ${ROCKETMQ_HOME}/bin/runserver.sh; \
sed -i '/Xms/{s/-Xms8g -Xmx8g/${MQ_BROKER_HEAP_OPTS}/;}' ${ROCKETMQ_HOME}/bin/runbroker.sh; \
rm -rf rocketmq.zip rocketmq.zip.asc KEYS; \
apt-get remove wget gpg unzip -y; \
apt autoremove -y; \
rm -rf /var/lib/apt/lists
# expose namesrv port
EXPOSE 9876
# expose broker ports
EXPOSE 10909 10911 10912
WORKDIR ${ROCKETMQ_HOME}/bin
如果不想自己做镜像,可以使用下面的docker-compose.yaml快速的启动一个RocketMQ实例。
docker-compose.yaml
version: '3'
services:
namesrv:
image: buall/rocketmq:4.9.3
container_name: rmqnamesrv
ports:
- 9876:9876
command: sh mqnamesrv
broker:
image: buall/rocketmq:4.9.3
container_name: rmqbroker
volumes:
- broker_data:/root/store
ports:
- 10909:10909
- 10911:10911
- 10912:10912
command: sh mqbroker -n namesrv:9876
depends_on:
- namesrv
volumes:
broker_data: