|

楼主 |
发表于 2025-5-3 19:48:49
|
显示全部楼层
docker-compose比较全的.txt
services:
mongodb:
image: mongo:6.0
container_name: mongodb
restart: unless-stopped
volumes:
- ./data/mongo:/data/db
- ./data/log:/var/log/mongodb
- ./data/mongodb-keyfile:/opt/mongo-keyfile
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
environment:
MONGO_INITDB_ROOT_USERNAME: rocketchat
MONGO_INITDB_ROOT_PASSWORD: f78gwiN4ZZIC9k # 从 .env 文件读取
command: >
mongod
--replSet rs0
--keyFile /opt/mongo-keyfile
--auth
--bind_ip_all
networks:
- rocketchat_net
# ports:
# - "27017:27017"
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet | grep 1
interval: 10s
timeout: 10s
retries: 10
security_opt:
- no-new-privileges:true
read_only: false # MongoDB需要写权限
tmpfs:
- /tmp:rw,noexec,nosuid,size=256M
ulimits:
nofile:
soft: 64000
hard: 64000
mongo-init:
image: mongo:6.0
depends_on:
mongodb:
condition: service_healthy
restart: "no"
environment:
MONGO_INITDB_ROOT_USERNAME: rocketchat
MONGO_INITDB_ROOT_PASSWORD: f78gwiN4ZZIC9k
entrypoint: >
sh -c "
echo '等待 MongoDB 启动...';
until mongosh --host mongodb -u rocketchat -p f78gwiN4ZZIC9k --authenticationDatabase admin --eval 'db.runCommand({ ping: 1 })' >/dev/null 2>&1; do
sleep 5;
done;
echo '初始化 MongoDB 复制集...';
mongosh --host mongodb -u rocketchat -p f78gwiN4ZZIC9k --authenticationDatabase admin --eval '
try {
rs.initiate({
_id: \"rs0\",
members: [ { _id: 0, host: \"mongodb:27017\" } ]
});
} catch (e) { print(e); }
';
echo '创建 rocketchat 用户...';
mongosh --host mongodb -u rocketchat -p f78gwiN4ZZIC9k --authenticationDatabase admin --eval '
try {
const dbname = "rocketchat";
const username = "rocketchat";
const db = db.getSiblingDB(dbname);
const user = db.getUser(username);
if (!user) {
print("用户不存在,正在创建...");
db.createUser({
user: username,
pwd: "'f78gwiN4ZZIC9k'",
roles: [
{ role: "readWrite", db: dbname },
{ role: "clusterMonitor", db: "admin" },
{ role: "read", db: "local" }
]
});
} else {
print("用户已存在,跳过创建。");
}
} catch (err) {
print("创建用户时出错:", err);
}
';
"
networks:
- rocketchat_net
rocketchat-builder:
image: node:14-alpine # 直接使用Node 14镜像
container_name: rocketchat-builder
volumes:
# 添加缓存卷
- ./meteor-cache:/root/.meteor:rw
- ./npm-cache:/tmp/npm_cache
- ./yarn-cache:/tmp/yarn_cache
- ./rocketchat-src:/app
- ./rocketchat-build:/build
working_dir: /app
environment:
# 增加构建缓存和镜像加速
METEOR_OFFLINE_CATALOG: 1
NPM_CONFIG_CACHE: /tmp/npm_cache
YARN_CACHE_FOLDER: /tmp/yarn_cache
METEOR_ALLOW_SUPERUSER: true
NPM_CONFIG_LEGACY_PEER_DEPS: true
METEOR_DISABLE_OPTIMISTIC_CACHING: 1 # 避免缓存问题
BUILD_TIMEOUT: 3600 # 防止构建超时
restart: "no"
tmpfs:
- /tmp:rw,exec,size=2G # 加速临时文件操作
command: >
sh -c "
# 使用国内Meteor镜像
export METEOR_PACKAGE_SERVER_URL=https://mirrors.tuna.tsinghua.edu.cn/meteor
# 安装基础工具
apk add --no-cache git curl jq &&
# 清空并克隆源码(强制覆盖)
echo '正在获取Rocket.Chat 7.5.1源码...';
rm -rf /app/* /app/.[!.]* 2>/dev/null || true;
git clone --depth 1 --branch 7.5.1 https://gitee.com/mirrors/Rocket.Chat.git /tmp/rocketchat &&
cp -a /tmp/rocketchat/. /app/ &&
rm -rf /tmp/rocketchat;
# 安装Meteor
echo '正在安装Meteor...';
curl https://install.meteor.com | sed 's/RELEASE=".*"/RELEASE="2.13"/' | sh
export PATH=\$PATH:\$HOME/.meteor;
# 修复package.json(移除workspace协议)
echo '修复依赖配置...';
apk update && apk add --no-cache jq
jq 'walk(if type == "object" then with_entries(select(.key != "workspaces")) else . end)' package.json > temp.json
mv temp.json package.json
# 清理并安装依赖
echo '安装依赖...';
rm -rf node_modules package-lock.json .meteor/local;
meteor npm install --legacy-peer-deps --production;
# 构建
echo '开始构建...';
meteor build --server-only --directory /build;
echo '构建完成!';
# 构建后验证
if [ ! -f /build/bundle/main.js ]; then
echo '错误:构建产物未生成!';
exit 1;
fi
# 构建后清理(减少镜像体积)
meteor npm cache clean --force &&
rm -rf /tmp/*
"
networks:
- rocketchat_net
rocketchat:
user: "node" # 明确指定非root用户
read_only: true # 只读模式(除挂载卷外)
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
image: registry.rocket.chat/rocketchat/rocket.chat:7.5.1
container_name: rocketchat
restart: always
depends_on:
mongodb:
condition: service_healthy
mongo-init:
condition: service_completed_successfully
rocketchat-builder:
condition: service_completed_successfully
volumes:
- ./rocketchat-build/bundle:/app/bundle:ro # 在 rocketchat 中只读即可
- ./data/rocketchat/uploads:/app/uploads
command: >
sh -c "
echo "正在等待 MongoDB..."
until mongosh 'mongodb://rocketchat_app:f78gwiN4ZZIC9k@mongodb:27017/rocketchat?replicaSet=rs0&authSource=admin' --eval 'db.runCommand({ ping: 1 })' >/dev/null; do
sleep 5
done
cd /app/bundle/programs/server &&
npm ci --omit=dev --no-audit || {
echo "npm ci 失败,尝试 fallback 到 npm install";
npm install --production --no-optional --no-audit;
} &&
export NODE_ENV=production &&
npm install -g pm2@latest &&
pm2-runtime start /app/bundle/main.js --name rocketchat
"
environment:
MONGO_URL: "mongodb://rocketchat_app:f78gwiN4ZZIC9k@mongodb:27017/rocketchat?replicaSet=rs0&authSource=admin"
MONGO_OPLOG_URL: "mongodb://rocketchat_app:f78gwiN4ZZIC9k@mongodb:27017/local?replicaSet=rs0&authSource=admin"
# 增加监控配置
OVERCLOCK: true
INSTANCE_IP: 127.0.0.1
DISABLE_METEOR_DDP: true
BIND_IP: 0.0.0.0
HTTP_FORWARDED_COUNT: 1
CACHE_LIMIT: 2000
# 禁用调试端点
DISABLE_DEBUG_MODE: true
# 限制会话时长(单位:小时)
SESSION_UPDATE_INTERVAL: 24
SESSION_LIFETIME: 720
# 禁用敏感API
RESTRICT_API_ACCESS: true
# 限制文件上传类型
UPLOAD_ALLOWED_MIME_TYPES: '"["image/*","application/pdf"]"'
ROOT_URL: https://chat.chaoren.group
PORT: 3000
sysctls:
- net.core.somaxconn=65535
- net.ipv4.tcp_max_syn_backlog=65535
networks:
- rocketchat_net
ports:
- "3000:3000"
networks:
rocketchat_net:
driver: bridge
attachable: true
ipam:
config:
- subnet: 172.28.0.0/16
gateway: 172.28.5.254
enable_ipv6: false
driver_opts:
com.docker.network.bridge.name: br-rocketchat
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
com.docker.network.bridge.enable_ip_masquerade: "true"
# 禁用容器间通信(需显式链接)
com.docker.network.bridge.enable_icc: "false"
# 启用流量过滤
com.docker.network.bridge.enable_ebtables: "true"
# 禁用MAC地址生成(增强隐私)
com.docker.network.bridge.enable_mac_spoofing: "false" |
|