Add MONGO_ROOT_PASSWORD to docs, config wizard, CCP, and prod compose

Follow-up to security audit commit — propagates MongoDB auth
(--auth flag) across all deployment paths:

- mkdocs environment-variables.md: add MONGO_ROOT_PASSWORD + MONGO_ROOT_USER,
  update ENCRYPTION_KEY description (now required in all environments),
  add to secret generation and full-stack variable lists
- config.sh: generate MONGO_ROOT_PASSWORD alongside Rocket.Chat credentials
- docker-compose.prod.yml: add --auth + credentials to MongoDB, update
  Rocket.Chat MONGO_URL with auth params
- CCP env.hbs: add MONGO_ROOT_USER/PASSWORD to chat block
- CCP docker-compose.yml.hbs: same MongoDB auth + MONGO_URL changes
- CCP secret-generator.ts: add mongoRootPassword to InstanceSecrets

Bunker Admin
This commit is contained in:
bunker-admin 2026-03-27 08:57:48 -06:00
parent 1bf19fff0e
commit 82a66a97d0
6 changed files with 37 additions and 10 deletions

View File

@ -58,6 +58,7 @@ export interface InstanceSecrets {
jitsiJicofoAuthPassword: string;
jitsiJvbAuthPassword: string;
rocketchatAdminPassword: string;
mongoRootPassword: string;
}
export function generateSecrets(adminEmail: string): InstanceSecrets & { adminEmail: string } {
@ -82,5 +83,6 @@ export function generateSecrets(adminEmail: string): InstanceSecrets & { adminEm
jitsiJicofoAuthPassword: randomHex(16),
jitsiJvbAuthPassword: randomHex(16),
rocketchatAdminPassword: randomPassword(16),
mongoRootPassword: randomHex(16),
};
}

View File

@ -510,13 +510,16 @@ services:
image: {{registryUrl}}/mongo:6.0
container_name: {{containerPrefix}}-mongodb
restart: unless-stopped
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--auth", "--keyFile", "/data/replica.key"]
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_ROOT_USER:-rocketchat}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_ROOT_PASSWORD}"
volumes:
- {{containerPrefix}}-mongodb-data:/data/db
networks:
- {{networkName}}
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "try { rs.status().ok } catch(e) { rs.initiate({_id:'rs0',members:[{_id:0,host:'{{containerPrefix}}-mongodb:27017'}]}).ok }"]
test: ["CMD", "mongosh", "-u", "${MONGO_ROOT_USER:-rocketchat}", "-p", "${MONGO_ROOT_PASSWORD}", "--authenticationDatabase", "admin", "--quiet", "--eval", "try { rs.status().ok } catch(e) { rs.initiate({_id:'rs0',members:[{_id:0,host:'{{containerPrefix}}-mongodb:27017'}]}).ok }"]
interval: 10s
timeout: 10s
retries: 10
@ -533,8 +536,8 @@ services:
condition: service_started
environment:
ROOT_URL: http://chat.{{domain}}
MONGO_URL: mongodb://{{containerPrefix}}-mongodb:27017/rocketchat?replicaSet=rs0
MONGO_OPLOG_URL: mongodb://{{containerPrefix}}-mongodb:27017/local?replicaSet=rs0
MONGO_URL: mongodb://${MONGO_ROOT_USER:-rocketchat}:${MONGO_ROOT_PASSWORD}@{{containerPrefix}}-mongodb:27017/rocketchat?replicaSet=rs0&authSource=admin
MONGO_OPLOG_URL: mongodb://${MONGO_ROOT_USER:-rocketchat}:${MONGO_ROOT_PASSWORD}@{{containerPrefix}}-mongodb:27017/local?replicaSet=rs0&authSource=admin
TRANSPORTER: monolith+nats://{{containerPrefix}}-nats:4222
PORT: "3000"
ADMIN_USERNAME: rcadmin

View File

@ -190,11 +190,15 @@ ENABLE_CHAT=true
ROCKETCHAT_URL=http://{{containerPrefix}}-rocketchat:3000
ROCKETCHAT_ADMIN_USER=rcadmin
ROCKETCHAT_ADMIN_PASSWORD={{secrets.rocketchatAdminPassword}}
MONGO_ROOT_USER=rocketchat
MONGO_ROOT_PASSWORD={{secrets.mongoRootPassword}}
{{else}}
ENABLE_CHAT=false
ROCKETCHAT_URL=
ROCKETCHAT_ADMIN_USER=
ROCKETCHAT_ADMIN_PASSWORD=
MONGO_ROOT_USER=
MONGO_ROOT_PASSWORD=
{{/if}}
# Jitsi Meet (Video Conferencing)

View File

@ -472,6 +472,17 @@ generate_all_secrets() {
((kept++))
fi
# MongoDB (required for Rocket.Chat — runs with --auth)
local mongo_pass
mongo_pass=$(generate_password 24)
if update_env_var_if_empty "MONGO_ROOT_PASSWORD" "$mongo_pass"; then
success "MongoDB root password"
((generated++))
else
info "MongoDB root password (kept existing)"
((kept++))
fi
# Gancio
local gancio_pass
gancio_pass=$(generate_password 20)

View File

@ -841,8 +841,8 @@ services:
condition: service_started
environment:
- ROOT_URL=http://chat.${DOMAIN:-cmlite.org}
- MONGO_URL=mongodb://mongodb-rocketchat:27017/rocketchat?replicaSet=rs0
- MONGO_OPLOG_URL=mongodb://mongodb-rocketchat:27017/local?replicaSet=rs0
- MONGO_URL=mongodb://${MONGO_ROOT_USER:-rocketchat}:${MONGO_ROOT_PASSWORD}@mongodb-rocketchat:27017/rocketchat?replicaSet=rs0&authSource=admin
- MONGO_OPLOG_URL=mongodb://${MONGO_ROOT_USER:-rocketchat}:${MONGO_ROOT_PASSWORD}@mongodb-rocketchat:27017/local?replicaSet=rs0&authSource=admin
- TRANSPORTER=monolith+nats://nats-rocketchat:4222
- PORT=3000
- ADMIN_USERNAME=${ROCKETCHAT_ADMIN_USER:-rcadmin}
@ -891,14 +891,17 @@ services:
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/mongo:6.0
container_name: mongodb-rocketchat
restart: unless-stopped
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--auth", "--keyFile", "/data/replica.key"]
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER:-rocketchat}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD:?MONGO_ROOT_PASSWORD must be set in .env}
volumes:
- mongodb-rocketchat-data:/data/db
logging: *default-logging
networks:
- changemaker-lite
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "try { rs.status().ok } catch(e) { rs.initiate({_id:'rs0',members:[{_id:0,host:'mongodb-rocketchat:27017'}]}).ok }"]
test: ["CMD", "mongosh", "-u", "${MONGO_ROOT_USER:-rocketchat}", "-p", "${MONGO_ROOT_PASSWORD}", "--authenticationDatabase", "admin", "--quiet", "--eval", "try { rs.status().ok } catch(e) { rs.initiate({_id:'rs0',members:[{_id:0,host:'mongodb-rocketchat:27017'}]}).ok }"]
interval: 10s
timeout: 10s
retries: 10

View File

@ -83,7 +83,7 @@ The primary database for both the Express API and the Fastify Media API (shared)
| Variable | Default | Description |
|----------|---------|-------------|
| `ENCRYPTION_KEY` | — | :material-alert-circle:{ .text-red } AES key for encrypting secrets stored in the database (SMTP passwords, API keys, etc.). Generate with `openssl rand -hex 32`. **Must not** reuse a JWT secret. Required in production (`NODE_ENV=production`). |
| `ENCRYPTION_KEY` | — | :material-alert-circle:{ .text-red } AES key for encrypting secrets stored in the database (SMTP passwords, API keys, etc.). Generate with `openssl rand -hex 32`. **Must not** reuse a JWT secret. **Required in all environments** (no longer falls back to JWT secret in development). |
---
@ -381,6 +381,8 @@ Self-hosted team chat for volunteer coordination. Requires MongoDB (auto-configu
| `ROCKETCHAT_ADMIN_PASSWORD` | — | :material-alert-circle:{ .text-red } Rocket.Chat admin password. |
| `ROCKETCHAT_URL` | `http://rocketchat-changemaker:3000` | Internal container URL. |
| `ROCKETCHAT_EMBED_PORT` | `8891` | Port for iframe embedding in admin. |
| `MONGO_ROOT_USER` | `rocketchat` | MongoDB admin username. |
| `MONGO_ROOT_PASSWORD` | — | :material-alert-circle:{ .text-red } MongoDB admin password. MongoDB runs with `--auth` enabled. |
---
@ -585,8 +587,9 @@ echo "INITIAL_ADMIN_PASSWORD=$(openssl rand -base64 18)"
# Vaultwarden
echo "VAULTWARDEN_ADMIN_TOKEN=$(openssl rand -hex 32)"
# Rocket.Chat
# Rocket.Chat + MongoDB
echo "ROCKETCHAT_ADMIN_PASSWORD=$(openssl rand -hex 16)"
echo "MONGO_ROOT_PASSWORD=$(openssl rand -hex 24)"
# Gancio
echo "GANCIO_ADMIN_PASSWORD=$(openssl rand -hex 16)"
@ -644,6 +647,7 @@ echo "JITSI_JVB_AUTH_PASSWORD=$(openssl rand -hex 16)"
N8N_USER_PASSWORD=...
VAULTWARDEN_ADMIN_TOKEN=...
ROCKETCHAT_ADMIN_PASSWORD=...
MONGO_ROOT_PASSWORD=...
GANCIO_ADMIN_PASSWORD=...
JITSI_APP_SECRET=...
JITSI_JICOFO_AUTH_PASSWORD=...