在拿铁熊猫 LattePanda 上配置基于 MongoDB 4.4.0 的 Rocket.Chat 聊天平台
背景
Rocket.Chat是一个基于JavaScript开发的开源聊天平台,常用于架设公司内部的通讯服务。Rocket.Chat使用MongoDB作为存放用户信息和聊天记录的数据库,使用默认方式安装(Docker或Snap)时,会为服务器自动安装5.0版本的MongoDB。但是自5.0版本开始,MongoDB必须在支持AVX指令集的处理器上才能正常运行。
近期友人购入了一台拿铁熊猫LattePanda 3 Delta,考虑到我们经常在公共聊天平台上传递密码等敏感信息,一旦账号被盗后果严重,因此我们考虑使用Rocket.Chat在上面搭建一个私人聊天平台。但是我在搭建过程中遇到了MongoDB无法运行导致Rocket.Chat也不能正常工作的情况,使用 docker logs
指令看到MongoDB发生了如下段错误:
经查找有关资料发现是因为LattePanda 3 Delta不支持AVX指令集,只能运行4.4.0及以下版本的MongoDB。下面我将记录我的搭建过程,希望对存在类似问题的人有所帮助。
1. 安装Docker并下载Rocket.Chat配置文件
使用Snap安装会直接尝试安装MongoDB 5.0,从而因为MongoDB安装失败导致Rocket.Chat也安装失败,因此只能使用Docker安装。
-
安装Docker和Docker Compose,此步骤不过多赘述。
-
创建一个空文件夹,用来存放Rocket.Chat的Docker Compose服务配置文件,切换当前目录到该文件夹下并执行以下指令以下载配置文件1
curl -L https://raw.githubusercontent.com/RocketChat/Docker.Official.Image/master/compose.yml -O
文件内容如下:
volumes: mongodb_data: { driver: local } services: rocketchat: image: registry.rocket.chat/rocketchat/rocket.chat:${RELEASE:-latest} restart: always labels: traefik.enable: "true" traefik.http.routers.rocketchat.rule: Host(`${DOMAIN:-}`) traefik.http.routers.rocketchat.tls: "true" traefik.http.routers.rocketchat.entrypoints: https traefik.http.routers.rocketchat.tls.certresolver: le environment: MONGO_URL: "${MONGO_URL:-\ mongodb://${MONGODB_ADVERTISED_HOSTNAME:-mongodb}:${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017}/\ ${MONGODB_DATABASE:-rocketchat}?replicaSet=${MONGODB_REPLICA_SET_NAME:-rs0}}" MONGO_OPLOG_URL: "${MONGO_OPLOG_URL:\ -mongodb://${MONGODB_ADVERTISED_HOSTNAME:-mongodb}:${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017}/\ local?replicaSet=${MONGODB_REPLICA_SET_NAME:-rs0}}" ROOT_URL: ${ROOT_URL:-http://localhost:${HOST_PORT:-3000}} PORT: ${PORT:-3000} DEPLOY_METHOD: docker DEPLOY_PLATFORM: ${DEPLOY_PLATFORM:-} REG_TOKEN: ${REG_TOKEN:-} depends_on: - mongodb expose: - ${PORT:-3000} ports: - "${BIND_IP:-0.0.0.0}:${HOST_PORT:-3000}:${PORT:-3000}" mongodb: image: docker.io/bitnami/mongodb:${MONGODB_VERSION:-5.0} restart: always volumes: - mongodb_data:/bitnami/mongodb environment: MONGODB_REPLICA_SET_MODE: primary MONGODB_REPLICA_SET_NAME: ${MONGODB_REPLICA_SET_NAME:-rs0} MONGODB_PORT_NUMBER: ${MONGODB_PORT_NUMBER:-27017} MONGODB_INITIAL_PRIMARY_HOST: ${MONGODB_INITIAL_PRIMARY_HOST:-mongodb} MONGODB_INITIAL_PRIMARY_PORT_NUMBER:${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017} MONGODB_ADVERTISED_HOSTNAME: ${MONGODB_ADVERTISED_HOSTNAME:-mongodb} MONGODB_ENABLE_JOURNAL: ${MONGODB_ENABLE_JOURNAL:-true} ALLOW_EMPTY_PASSWORD: ${ALLOW_EMPTY_PASSWORD:-yes}
-
输入以下指令以下载环境变量配置文件1
wget https://raw.githubusercontent.com/RocketChat/Docker.Official.Image/master/env.example mv env.example .env
文件内容如下:
### Rocket.Chat configuration # Rocket.Chat version # see:- https://github.com/RocketChat/Rocket.Chat/releases #RELEASE= # MongoDB endpoint (include ?replicaSet= parameter) #MONGO_URL= # MongoDB endpoint to the local database #MONGO_OPLOG_URL= # IP to bind the process to #BIND_IP= # URL used to access your Rocket.Chat instance #ROOT_URL= # Port Rocket.Chat runs on (in-container) #PORT= # Port on the host to bind to #HOST_PORT= ### MongoDB configuration # MongoDB version/image tag #MONGODB_VERSION= # See:- https://hub.docker.com/r/bitnami/mongodb ### Traefik config (if enabled) # Traefik version/image tag #TRAEFIK_RELEASE= # Domain for https (change ROOT_URL & BIND_IP accordingly) #DOMAIN= # Email for certificate notifications #LETSENCRYPT_EMAIL=
该文件中的配置在部署时将会替换
compose.yml
中使用类似格式${arg:-default}
标出的参数。
2. 修改MongoDB有关配置
-
去掉
.env
文件中#MONGODB_VERSION=
前的#
,并在其后输入本次要配置的版本4.4.0
MONGODB_VERSION=4.4.0
-
(可选)修改
compose.yml
,在mongodb
标签内,与volumes
、environment
标签同级的位置加入以下配置expose: - ${MONGO_PORT:-27017} ports: - ${MONGO_BIND_IP:-127.0.0.1}:${MONGO_HOST_PORT:-27017}:27017
这样在容器启动后,MongoDB会部署在主机的
MONGO_HOST_PORT
端口上,该端口号在此处默认为27017
,在.env
中可以修改MONGO_HOST_PORT
的值。这么做的好处是便于从主机直接访问MongoDB来进行删除聊天记录等维护操作,同时还有利于其它基于MongoDB的服务共享数据库。如果不映射MongoDB的端口,使用如下指令也可以访问Docker容器内的MongoDB。sudo docker exec -it <MongoDB的Container ID> mongo
此处
MONGO_BIND_IP
为127.0.0.1
,这是为了保证只从主机上访问MongoDB,该IP也可以为0.0.0.0
或直接不提供(此时为缺省值0.0.0.0
)。需要注意的是,当该值为0.0.0.0
时,外部主机也可以访问MongoDB,而Rocket.Chat要求MongoDB必须支持匿名访问(至少我没有找到让Rocket.Chat使用指定账户登录MongoDB的方法),如果防火墙配置存在问题,未知第三方就可以匿名登录主机的数据库从而窃取聊天记录。Ubuntu可以使用以下指令查看防火墙配置。
sudo ufw status
仅当
ufw
启动,且27017
对外关闭时,才建议MONGO_BIND_IP
取0.0.0.0
。 -
启动MongoDB容器
在compose.yml
所在的目录中使用如下指令部署容器。sudo docker-compose up -d
之后使用如下指令可以查看当前已启动的容器。
sudo docker ps -a
不出意外的话,应该可以看到MongoDB成功启动,Rocket.Chat容器会在数秒后直接退出,这是因为我们还没有配置Rocke.Chat有关的参数。
3. 修改Rocket.Chat有关配置
-
配置
MONGO_URL
使用如下指令可以看到Rocket.Chat此时的报错如图所示。sudo docker logs <Rocket.Chat的Container ID>
经过多次尝试后,我发现这是因为不知道为什么,Docker无法正确识别默认参数中给出的MONGO_URL
和MONGO_OPLOG_URL
,可以在.env
中直接给出MongoDB的地址。将
.env
文件中#MONGO_URL=
和#MONGO_OPLOG_URL=
前的#
去掉并修改为如下内容。MONGO_URL=mongodb://mongodb:27017/rocketchat?replicaSet=rs0&authSource=admin MONGO_OPLOG_URL=mongodb://mongodb:27017/local?replicaSet=rs0&authSource=admin
链接中之所以能写
mongodb:27017
是因为在MongoDB的容器配置文件中给出了有关参数,链接末尾的replicaSet=rs0
和authSource=admin
不能省,前者replicaSet=rs0
在原始的compose.yml
配置中也有给出,后者authSource=admin
是Rocket.Chat Docs中给出的配置1,缺少其中任何一个,Rocket.Chat在连接MongoDB时都会发生超时,docker logs
查找到的错误信息如下。
虽然两个链接本应可以写作username:password@mongodb:27017
来指定登录数据库的账号密码,但经我实测发现这么做不行,依然会导致连接超时。 -
配置
ROOT_URL
再次使用sudo docker-compose up -d
,Rocket.Chat容器能正常运行,但访问localhost:3000
只能看到Unknown path
字样,从docker logs
中能查到如下报错信息。
经反复测试后发现是因为Docker无法正确读取.env
中的ROOT_URL
参数,所以只能直接在compose.yml
中修改,即将compose.yml
中的ROOT_URL: ${ROOT_URL:-http://localhost:${HOST_PORT:-3000}}
直接改为
ROOT_URL: <Your Root Url, For example: localhost:3000>
-
(可选)映射上传文件的保存路径
我希望用户上传的文件保存在文件系统中而不是数据库中,因此需要将Rocket.Chat保存用户上传的文件的路径映射到主机上。在
compose.yml
中,rocketchat
标签内,与environment
,expose
和ports
标签同级的位置加入以下配置。volumes: - /home/rocketchat:/app/uploads:rw user: root
此处
user: root
不能省去,否则Rocket.Chat会因为对目录没有写入权限而使用户无法上传文件。在配置完成后,可用管理员账户在Rocket.Chat网页端的
设置 > 文件上传
位置找到存储类型
设置,GridFS
表示将上传的文件储存在数据库中,FileSystem
表示将上传的文件以文件形式储存在主机上。如果使用
FileSystem
,需要在下方的File System
标签内设置文件的存储位置,此位置为Docker容器内的路径,在使用上述配置(将容器内/app/uploads
映射到主机/home/rocketchat
)的情况下,需要在此填入/app/uploads
-
启动Rocket.Chat容器
最后再一次执行sudo docker-compose up -d
通过
docker ps -a
可以看到Rocket.Chat容器正常运行,浏览器访问localhost:3000
,可以正常显示出Rocket.Chat的网页端界面,到此配置完成。
参考Rocket.Chat Docs配置文档,链接:Docker & Docker Compose ↩ ↩ ↩