MongoDB na VPS — instalacja, konfiguracja i replica set
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS / Bazy danych
MongoDB to dokumentowa baza NoSQL, w której dane są przechowywane jako dokumenty BSON (Binary JSON). Zamiast tabel i wierszy masz kolekcje i dokumenty — każdy dokument może mieć inną strukturę, co daje ogromną elastyczność. Jest idealna do aplikacji z niejednorodną strukturą danych: katalogi produktów e-commerce, systemy CMS, IoT, logi zdarzeń. Ten artykuł przeprowadzi Cię przez instalację MongoDB 7 na Ubuntu, zabezpieczenie instancji, tworzenie użytkowników i konfigurację replica set dla wysokiej dostępności.
Instalacja MongoDB 7 na Ubuntu 22.04
# Importuj klucz GPG MongoDB curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor # Dodaj repozytorium MongoDB echo "deb [ arch=amd64,arm64 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.list # Instalacja sudo apt update && sudo apt install -y mongodb-org # Uruchomienie i autostart sudo systemctl enable --now mongod sudo systemctl status mongod # Weryfikacja wersji mongod --version # db version v7.0.x
Konfiguracja mongod.conf — bezpieczeństwo i wydajność
Domyślna konfiguracja MongoDB nasłuchuje na wszystkich interfejsach bez uwierzytelniania — to poważny błąd bezpieczeństwa. Poniżej kompletna konfiguracja dla VPS:
# /etc/mongod.conf
storage:
dbPath: /var/lib/mongodb
wiredTiger:
engineConfig:
cacheSizeGB: 1 # 50% RAM domyslnie, zmniejsz na VPS 2GB
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
logRotate: reopen
net:
port: 27017
bindIp: 127.0.0.1 # KRYTYCZNE: NIE 0.0.0.0 na produkcji!
# Dla replica set dodaj: 127.0.0.1,10.0.0.1 (IP lokalne)
security:
authorization: enabled # ZAWSZE wlaczone na produkcji
operationProfiling:
slowOpThresholdMs: 100 # Loguj zapytania wolniejsze niz 100ms
replication:
replSetName: "rs0" # Tylko dla replica set Tworzenie użytkowników i zarządzanie dostępem
# Polacz sie z mongoshellem (przed wlaczeniem auth)
mongosh
# Stworz uzytkownika administratora
use admin
db.createUser({
user: "adminUser",
pwd: "TajneHaslo!123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
})
# Wyjdz, uruchom mongod z auth i zaloguj sie
exit
mongosh -u adminUser -p --authenticationDatabase admin
# Stworz uzytkownika aplikacji z ograniczonymi uprawnieniami
use myapp_db
db.createUser({
user: "appUser",
pwd: "AppHaslo!456",
roles: [ { role: "readWrite", db: "myapp_db" } ]
})
# Weryfikacja uzytkownikow
use admin
db.system.users.find({}, {user: 1, roles: 1}).pretty()
# String polaczenia dla aplikacji
# mongodb://appUser:[email protected]:27017/myapp_db Replica Set — 3-węzłowy klaster z automatycznym failover
Replica set to minimum, które należy wdrożyć w produkcji. Trzy węzły na trzech serwerach (lub jeden primary + dwa secondary na jednym VPS do testów) zapewniają automatyczny failover. Poniżej konfiguracja dla 3 VPS-ów z prywatnymi IP:
# Na KAZDYM z 3 wezlow: ustaw replSetName w mongod.conf
# replication:
# replSetName: "rs0"
# net:
# bindIp: 127.0.0.1,10.0.0.1 (IP prywatne tego wezla)
# Na wezle PRIMARY (node1) - inicjalizuj replica set
mongosh
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "10.0.0.1:27017", priority: 2 },
{ _id: 1, host: "10.0.0.2:27017", priority: 1 },
{ _id: 2, host: "10.0.0.3:27017", priority: 1 }
]
})
# Sprawdz status
rs.status()
# Szukaj: "stateStr": "PRIMARY" na jednym, "SECONDARY" na pozostalych
# Sprawdz kto jest primary
rs.isMaster()
# lub: db.adminCommand({ isMaster: 1 })
# Testuj failover - zatrzymaj primary i obserwuj
# sudo systemctl stop mongod (na node1)
# rs.status() na node2/3 pokaze nowy PRIMARY po ~10s
# Connection string z failover dla aplikacji:
# mongodb://user:[email protected]:27017,10.0.0.2:27017,10.0.0.3:27017/mydb?replicaSet=rs0 Backup i restore — mongodump / mongorestore
# Backup calej instancji mongodump \ --uri="mongodb://adminUser:[email protected]:27017/?authSource=admin" \ --out=/backup/mongo-$(date +%Y%m%d) # Backup jednej bazy mongodump \ --uri="mongodb://appUser:[email protected]:27017/myapp_db" \ --out=/backup/myapp-$(date +%Y%m%d) # Kompresja mongodump --uri="..." --archive=/backup/mongo.gz --gzip # Restore mongorestore \ --uri="mongodb://adminUser:[email protected]:27017/?authSource=admin" \ --dir=/backup/mongo-20260410 # Restore z archiwum mongorestore \ --uri="mongodb://adminUser:[email protected]:27017/?authSource=admin" \ --archive=/backup/mongo.gz --gzip # Cron - codziennie o 3:00 # 0 3 * * * mongodump --uri="..." --archive=/backup/mongo-$(date +\%Y\%m\%d).gz --gzip # Czyszczenie po 7 dniach: # 0 4 * * * find /backup -name "mongo-*.gz" -mtime +7 -delete
Indeksy i optymalizacja zapytań z explain()
mongosh
use myapp_db
# Tworzenie indeksow
db.users.createIndex({ email: 1 }, { unique: true })
db.orders.createIndex({ userId: 1, createdAt: -1 }) // indeks zlozony
db.products.createIndex({ name: "text", description: "text" }) // full-text
# Listowanie indeksow
db.users.getIndexes()
# Analiza zapytania - KLUCZOWE dla wydajnosci
db.orders.find({ userId: "abc123" }).sort({ createdAt: -1 }).explain("executionStats")
// Szukaj: "IXSCAN" (uzywa indeksu) vs "COLLSCAN" (pelny skan = wolno)
// totalDocsExamined powinno byc bliskie nReturned
// Znajdz wolne zapytania (profiler)
db.setProfilingLevel(1, { slowms: 100 }) // loguj > 100ms
db.system.profile.find().sort({ ts: -1 }).limit(5).pretty()
// Statystyki kolekcji
db.orders.stats()
db.orders.totalIndexSize() MongoDB vs PostgreSQL — kiedy co wybrać
| Kryterium | MongoDB | PostgreSQL |
|---|---|---|
| Schemat danych | Elastyczny (schemaless) | Ściśle zdefiniowany |
| Transakcje | Od 4.0 (multi-document ACID) | Pełne ACID od zawsze |
| Skalowanie poziome | Natywny sharding | Citus lub partycjonowanie |
| JOIN-y | $lookup (wolniejsze) | Natywne, wydajne |
| Full-text search | Wbudowany ($text) | tsvector + GIN index |
| Use case | CMS, IoT, e-commerce, logi | Finanse, ERP, relacyjne dane |
| Licencja | SSPL (ograniczenia cloud) | PostgreSQL (permissive) |