<< All versions
Skill v1.0.0
currentAutomated scan100/100bagelhole/devops-security-agent-skills/mongodb
──Details
PublishedSeptember 29, 2026 at 03:02 PM
Content Hashsha256:81aa71477d9e0471...
Git SHA0365f57a079b
──Files
Files (1 file, 9.9 KB)
SKILL.md9.9 KBactive
SKILL.md · 422 lines · 9.9 KB
version: "1.0.0" name: mongodb description: Administer MongoDB databases. Configure replica sets, sharding, and backups. Use when managing MongoDB deployments. license: MIT metadata: author: devops-skills version: "1.0"
MongoDB
Administer, optimize, and secure MongoDB NoSQL databases in development and production environments.
When to Use
- You need a document-oriented database with flexible schemas.
- Your data is semi-structured or heavily nested (JSON-like documents).
- You need horizontal scaling through sharding.
- Your application benefits from rich querying and aggregation pipelines.
Prerequisites
- Linux server (Debian/Ubuntu or RHEL-based) or Docker.
- Root or sudo access for package installation.
- MongoDB 7.x recommended for production (6.x still supported).
Installation and Setup
bash
# Debian / Ubuntu — MongoDB 7curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmorecho "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.listsudo apt updatesudo apt install -y mongodb-org# Start and enablesudo systemctl enable --now mongod# Verifymongosh --eval "db.version()"
Initial User Setup
javascript
// Connect without auth first// mongoshuse admin// Create admin userdb.createUser({user: "admin",pwd: "strong_admin_password",roles: [{ role: "userAdminAnyDatabase", db: "admin" },{ role: "readWriteAnyDatabase", db: "admin" },{ role: "clusterAdmin", db: "admin" }]})// Create an application-scoped useruse mydbdb.createUser({user: "myapp",pwd: "strong_app_password",roles: [{ role: "readWrite", db: "mydb" }]})
Enable authentication in /etc/mongod.conf:
yaml
security:authorization: enabled
bash
sudo systemctl restart mongod# Now connect with credentialsmongosh -u myapp -p strong_app_password --authenticationDatabase mydb
mongosh Commands Reference
javascript
// Show databases and collectionsshow dbsuse mydbshow collections// Insert documentsdb.users.insertOne({ name: "Alice", email: "alice@example.com", age: 30 })db.users.insertMany([{ name: "Bob", email: "bob@example.com", age: 25 },{ name: "Carol", email: "carol@example.com", age: 35 }])// Query documentsdb.users.find({ age: { $gte: 25 } }).sort({ name: 1 }).limit(10)db.users.findOne({ email: "alice@example.com" })db.users.countDocuments({ age: { $gte: 30 } })// Updatedb.users.updateOne({ email: "alice@example.com" },{ $set: { age: 31 }, $currentDate: { updatedAt: true } })db.users.updateMany({ age: { $lt: 30 } },{ $set: { tier: "junior" } })// Deletedb.users.deleteOne({ email: "bob@example.com" })db.users.deleteMany({ tier: "junior" })
Indexing
javascript
// Single-field indexdb.users.createIndex({ email: 1 }, { unique: true })// Compound indexdb.orders.createIndex({ userId: 1, createdAt: -1 })// Text index for searchdb.articles.createIndex({ title: "text", body: "text" })db.articles.find({ $text: { $search: "mongodb scaling" } })// TTL index — auto-delete documents after 30 daysdb.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })// List indexesdb.users.getIndexes()// Drop an indexdb.users.dropIndex("email_1")// Explain a query to verify index usagedb.orders.find({ userId: 42 }).explain("executionStats")
Aggregation Pipeline Examples
javascript
// Revenue per statusdb.orders.aggregate([{ $group: {_id: "$status",totalRevenue: { $sum: "$total" },count: { $sum: 1 }}},{ $sort: { totalRevenue: -1 } }])// Top 5 customers by order value (with a join)db.orders.aggregate([{ $group: {_id: "$userId",spent: { $sum: "$total" },orderCount: { $sum: 1 }}},{ $sort: { spent: -1 } },{ $limit: 5 },{ $lookup: {from: "users",localField: "_id",foreignField: "_id",as: "user"}},{ $unwind: "$user" },{ $project: {_id: 0,name: "$user.name",email: "$user.email",spent: 1,orderCount: 1}}])// Daily signup trenddb.users.aggregate([{ $group: {_id: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } },signups: { $sum: 1 }}},{ $sort: { _id: 1 } },{ $limit: 30 }])
Replica Set Setup
A replica set requires a minimum of three members (or two data-bearing nodes plus an arbiter).
Configuration File for Each Member
yaml
# /etc/mongod.conf (adjust port and dbPath per member)storage:dbPath: /var/lib/mongodbnet:port: 27017bindIp: 0.0.0.0replication:replSetName: rs0security:authorization: enabledkeyFile: /etc/mongodb-keyfile
bash
# Generate a shared keyfile for internal authopenssl rand -base64 756 > /etc/mongodb-keyfilechmod 400 /etc/mongodb-keyfilechown mongodb:mongodb /etc/mongodb-keyfile# Copy this file to all replica set members
Initialize the Replica Set
javascript
// Connect to the first member// mongosh --port 27017rs.initiate({_id: "rs0",members: [{ _id: 0, host: "mongo1:27017", priority: 2 },{ _id: 1, host: "mongo2:27017", priority: 1 },{ _id: 2, host: "mongo3:27017", priority: 1 }]})// Check statusrs.status()// View replication lag per memberrs.printReplicationInfo()rs.printSecondaryReplicationInfo()
Backup and Restore
bash
# Full dump of all databasesmongodump --uri="mongodb://admin:secret@localhost:27017" --out=/backups/full_$(date +%F)# Single databasemongodump --uri="mongodb://myapp:secret@localhost:27017/mydb" --out=/backups/mydb_$(date +%F)# Compressed dumpmongodump --uri="mongodb://admin:secret@localhost:27017" --gzip --out=/backups/gz_$(date +%F)# Restore all databasesmongorestore --uri="mongodb://admin:secret@localhost:27017" /backups/full_2025-01-15/# Restore a single database, dropping existing data firstmongorestore --uri="mongodb://admin:secret@localhost:27017" \--drop --db mydb /backups/mydb_2025-01-15/mydb/# Restore compressed dumpmongorestore --uri="mongodb://admin:secret@localhost:27017" --gzip /backups/gz_2025-01-15/
Docker Compose Setup
yaml
# docker-compose.ymlversion: "3.9"services:mongo1:image: mongo:7restart: unless-stoppedports:- "27017:27017"environment:MONGO_INITDB_ROOT_USERNAME: adminMONGO_INITDB_ROOT_PASSWORD: secretvolumes:- mongo1_data:/data/db- ./mongo-keyfile:/etc/mongodb-keyfile:rocommand: >mongod--replSet rs0--keyFile /etc/mongodb-keyfile--bind_ip_allhealthcheck:test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]interval: 10stimeout: 5sretries: 5mongo2:image: mongo:7restart: unless-stoppedvolumes:- mongo2_data:/data/db- ./mongo-keyfile:/etc/mongodb-keyfile:rocommand: >mongod--replSet rs0--keyFile /etc/mongodb-keyfile--bind_ip_allmongo3:image: mongo:7restart: unless-stoppedvolumes:- mongo3_data:/data/db- ./mongo-keyfile:/etc/mongodb-keyfile:rocommand: >mongod--replSet rs0--keyFile /etc/mongodb-keyfile--bind_ip_allmongo-init:image: mongo:7restart: "no"depends_on:mongo1:condition: service_healthyentrypoint: >mongosh --host mongo1 -u admin -p secret --authenticationDatabase admin --eval 'rs.initiate({_id: "rs0",members: [{ _id: 0, host: "mongo1:27017", priority: 2 },{ _id: 1, host: "mongo2:27017", priority: 1 },{ _id: 2, host: "mongo3:27017", priority: 1 }]})'volumes:mongo1_data:mongo2_data:mongo3_data:
bash
# Generate keyfile before startingopenssl rand -base64 756 > mongo-keyfilechmod 400 mongo-keyfiledocker compose up -d# Connectmongosh "mongodb://admin:secret@127.0.0.1:27017/?replicaSet=rs0&authSource=admin"
Monitoring Queries
javascript
// Server status summarydb.serverStatus().connectionsdb.serverStatus().opcounters// Current operations (look for long-running queries)db.currentOp({ secs_running: { $gte: 5 } })// Collection statsdb.orders.stats()// Index sizesdb.orders.stats().indexSizes// Profiler — log slow queries (> 100ms)db.setProfilingLevel(1, { slowms: 100 })db.system.profile.find().sort({ ts: -1 }).limit(5)// Replica set lagrs.printSecondaryReplicationInfo()
Configuration Tuning
yaml
# /etc/mongod.conf — production recommendationsstorage:dbPath: /var/lib/mongodbjournal:enabled: truewiredTiger:engineConfig:cacheSizeGB: 4 # ~50% of RAM, leave rest for OS cachecollectionConfig:blockCompressor: snappynet:port: 27017bindIp: 0.0.0.0maxIncomingConnections: 500operationProfiling:mode: slowOpslowOpThresholdMs: 100
Troubleshooting
| Symptom | Likely Cause | Fix | |
|---|---|---|---|
COLLSCAN in explain output | Missing index on queried field | Create an appropriate index | |
Replica member stuck in RECOVERING | Oplog window exceeded | Resync by removing data and restarting the member | |
too many open files | OS file descriptor limit too low | Set ulimit -n 65535 in service file | |
| High memory usage | WiredTiger cache too large | Reduce cacheSizeGB in config | |
| Slow aggregation pipelines | No index on $match stage fields | Add index; place $match as early as possible in pipeline | |
| Authentication failure | Wrong authenticationDatabase | Specify --authenticationDatabase admin for admin users |
Related Skills
- redis - Caching layer in front of MongoDB
- database-backups - Automated backup strategies
- postgresql - Alternative relational database