← Zurück zur Übersicht MongoDB & Node.js: Datenhaltung im Docker-Container

MongoDB & Node.js: Datenhaltung im Docker-Container

[WERBUNG: CONTENT OBEN]

MongoDB & Node.js API lokal mit Docker Compose

Wer kennt es nicht: Du möchtest "nur mal kurz" eine Datenbank für ein neues Projekt evaluieren. Statt dir das System mit lokalen MongoDB-Installationen und verschiedenen Versionen vollzumüllen, ist Docker die weitaus elegantere Lösung.

Aber Infrastruktur allein liefert keinen echten Mehrwert! Eine isolierte Datenbank bringt dir nichts, wenn du nicht weißt, wie deine Applikation damit kommuniziert. Deshalb bauen wir in diesem Tutorial kein nacktes Datenbank-Setup, sondern ein vollständiges Praxisbeispiel bestehend aus einer MongoDB und einer minimalen Node.js (Express) REST-API, die direkt auf die Datenbank zugreift.


1. Projektordner erstellen (Hygiene & Sicherheit zuerst)

Wir wollen dein Dateisystem sauber halten. Gehe niemals davon aus, dass Dateien "einfach so" irgendwo gespeichert werden sollten. Wir zwingen uns ausnahmslos dazu, einen dedizierten, isolierten Ordner für unser neues Projekt zu erstellen.

Führe folgenden Befehl in deinem Terminal aus, um den Ordner zu erstellen und direkt dorthin zu wechseln:

mkdir mongodb-node-tutorial && cd mongodb-node-tutorial

Ab sofort legen wir alle Dateien in diesem neuen Workspace ab. Du hast somit die volle Kontrolle und Sicherheit über deine Projektdateien.


2. Infrastructure as Code: docker-compose.yaml

Wir verzichten auf unübersichtliche und lange docker run-Befehle im Terminal. Stattdessen setzen wir auf "Infrastructure as Code" in Form einer Docker Compose Datei.

Erstelle die folgende Datei:

mongodb-node-tutorial/docker-compose.yaml:

version: '3.8'

services:
  database:
    image: mongo:6-jammy
    container_name: mongodb_tutorial_db
    ports:
      - "27017:27017" # Port für externe Tools (z.B. MongoDB Compass)
    volumes:
      - mongo-data:/data/db # Persistente Datenhaltung
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=securepassword
    restart: unless-stopped

  api:
    build: .
    container_name: mongodb_tutorial_api
    ports:
      - "3000:3000"
    environment:
      - MONGO_URI=mongodb://admin:securepassword@database:27017/shop?authSource=admin
    depends_on:
      - database
    restart: unless-stopped

volumes:
  mongo-data:

Warum ist das gut? Wir definieren hier zwei Services: Die database (MongoDB) und unsere api. Die API wartet auf die Datenbank (depends_on) und kommuniziert mit ihr sicher im internen Docker-Netzwerk.


3. Die Praxis: Eine echte Node.js API

Damit die Datenbank auch einen Zweck hat, schreiben wir schnell einen kleinen API-Service.

Wir benötigen zuerst eine package.json, um unsere benötigten Bibliotheken (express für den Webserver und mongoose für die MongoDB-Verbindung) zu definieren.

mongodb-node-tutorial/package.json:

{
  "name": "mongodb-node-api",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^8.0.0"
  }
}

Als Nächstes folgt die Logik für unseren Server:

mongodb-node-tutorial/server.js:

const express = require('express');
const mongoose = require('mongoose');

const app = express();
app.use(express.json());

// Verbindung zur MongoDB herstellen (nutzt die Umgebungsvariable aus der docker-compose.yaml)
const MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost:27017/shop';

mongoose.connect(MONGO_URI)
  .then(() => console.log('✅ Erfolgreich mit MongoDB verbunden!'))
  .catch(err => console.error('❌ Fehler bei der MongoDB Verbindung:', err));

// Definiere ein einfaches Daten-Schema
const Product = mongoose.model('Product', new mongoose.Schema({
  name: String,
  price: Number
}));

// Route: Neues Produkt erstellen
app.post('/products', async (req, res) => {
  try {
    const product = new Product(req.body);
    await product.save();
    res.status(201).json(product);
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Route: Alle Produkte abrufen
app.get('/products', async (req, res) => {
  const products = await Product.find();
  res.json(products);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`🚀 API Server läuft auf Port ${PORT}`);
});

Zum Schluss benötigen wir noch einen Bauplan (Dockerfile), um unsere Node.js API in einen Container zu packen:

mongodb-node-tutorial/Dockerfile:

FROM node:20-alpine

# Setze das Arbeitsverzeichnis im Container
WORKDIR /app

# Kopiere die Package-Dateien und installiere Abhängigkeiten
COPY package*.json ./
RUN npm install

# Kopiere den restlichen Quellcode (die server.js)
COPY . .

# Öffne Port 3000
EXPOSE 3000

# Starte die Anwendung
CMD ["npm", "start"]

4. Setup starten und testen

Jetzt haben wir alles zusammen. Dank Docker Compose reicht ein einziger Standard-Befehl in unserem Ordner, um die Datenbank herunterzuladen, unsere API zu bauen und beide miteinander zu verknüpfen:

docker compose up -d --build

⚠️ 📸 SCREENSHOT ANFRAGE: Hier einen Screenshot vom Terminal einfügen, der zeigt, wie Docker die Images baut und die Container erfolgreich startet.

Warte einige Sekunden, bis der Container hochgefahren ist. Du kannst dir die Server-Logs mit docker compose logs -f api ansehen. Wenn du "✅ Erfolgreich mit MongoDB verbunden!" liest, ist alles startklar!

Teste die Anwendung

Öffne ein neues Terminal und sende ein Test-Produkt an deine API (mit einem HTTP POST Request):

curl -X POST http://localhost:3000/products \
  -H "Content-Type: application/json" \
  -d '{"name": "Gaming Tastatur", "price": 99.99}'

Anschließend kannst du prüfen, ob das Produkt erfolgreich in der MongoDB gespeichert wurde:

curl http://localhost:3000/products

Die Antwort des Servers sollte dein neu erstelltes Produkt inklusive einer _id aus der MongoDB enthalten. Glückwunsch! Deine Full-Stack-Infrastruktur steht.

⚠️ 📸 SCREENSHOT ANFRAGE: Hier einen Screenshot vom Browser oder Terminal (curl) einfügen, der die erfolgreiche JSON-Antwort mit der MongoDB _id zeigt.

Fazit: Du hast gelernt, wie man eine MongoDB nicht isoliert, sondern im direkten Zusammenspiel mit einer Node.js Anwendung konfiguriert und wie essenziell ein sauberes Arbeitsverzeichnis ist.

[WERBUNG: CONTENT UNTEN]