Der Autor des Artikels, dessen Übersetzung wir heute veröffentlichen, möchte darüber sprechen, wie React-, Express- und MongoDB-basierte Webanwendungen in Docker-Container gepackt werden. Hier werden die Funktionen zum Erstellen der Struktur von Dateien und Ordnern solcher Projekte, zum Erstellen von Dateien Dockerfile
und zum Verwenden der Docker Compose-Technologie betrachtet.
Arbeitsbeginn
Der Einfachheit halber gehe ich davon aus, dass Sie bereits eine funktionierende Anwendung haben, die von den Client- und Serverteilen präsentiert wird und mit der Datenbank verbunden ist.Es ist am besten, wenn sich der Client- und der Servercode im selben Ordner befinden. Der Code kann sich in einem Repository befinden, aber in verschiedenen Repositorys gespeichert werden. In diesem Fall sollten die Projekte mit dem Befehl in einem Ordner zusammengefasst werden git submodule
. Ich habe genau das getan.Übergeordneter Repository-DateibaumAnwendung reagieren
Hier habe ich ein Projekt verwendet, das mit der Create React App erstellt und für die Unterstützung von TypeScript konfiguriert wurde. Dies ist ein einfaches Blog, das mehrere visuelle Elemente enthält.Erstellen Sie zunächst eine Datei Dockerfile
im Stammverzeichnis client
. Führen Sie dazu einfach den folgenden Befehl aus:$ touch Dockerfile
Öffnen Sie die Datei und geben Sie die folgenden Befehle ein. Wie bereits erwähnt, verwende ich es in meiner TypeScript-Anwendung, daher muss ich es zuerst erstellen. Dann müssen Sie das Geschehene nehmen und alles im Format statischer Ressourcen bereitstellen. Um dies zu erreichen, verwende ich den zweistufigen Prozess zum Erstellen eines Docker-Images.Der erste Schritt besteht darin, Node.js zum Erstellen der Anwendung zu verwenden. Ich verwende als Basisbild ein Alpenbild. Dies ist ein sehr kompaktes Bild, das sich positiv auf die Größe des Behälters auswirkt.FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build
So beginnt unsere Dockerfile
. Zuerst kommt das Team node:12-alpine as builder
. Dann legen wir das Arbeitsverzeichnis fest - in unserem Fall dieses /app
. Aus diesem Grund wird im Container ein neuer Ordner erstellt. Kopieren package.json
und installieren Sie in diesem Containerordner die Abhängigkeiten. Dann /app
kopieren wir alles aus dem Ordner /services/client
. Die Arbeiten werden durch die Montage des Projekts abgeschlossen.Jetzt müssen Sie das Hosting für die neu erstellte Assembly organisieren. Verwenden Sie dazu NGINX. Und wieder wird dies die alpine Version des Systems sein. Wir tun dies nach wie vor, um Platz zu sparen.FROM nginx:1.16.0-alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Hier werden die nginx
Ergebnisse der im vorherigen Schritt erhaltenen Projektassembly in den Ordner kopiert. Dann öffnen Sie den Port 80
. An diesem Port wartet der Container auf Verbindungen. Die letzte Zeile der Datei wird zum Starten von NGINX verwendet.Dies ist alles, was erforderlich ist, um den Client-Teil der Anwendung anzudocken. Das Ergebnis Dockerfile
sieht folgendermaßen aus:FROM node:12-alpine as build
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Express-API
Unsere Express-API ist auch ganz einfach. Hier wird zur Organisation der Endpunkte die RESTful-Technologie verwendet. Endpunkte werden verwendet, um Veröffentlichungen zu erstellen, die Autorisierung zu unterstützen und andere Probleme zu lösen. Beginnen wir mit dem Erstellen Dockerfile
im Stammverzeichnis api
. Wir werden so handeln wie zuvor.Während der Entwicklung der Serverseite der Anwendung habe ich die Funktionen von ES6 verwendet. Um den Code auszuführen, muss ich ihn daher kompilieren. Ich habe beschlossen, den Code mit Babel zu verarbeiten. Wie Sie vielleicht erraten haben, wird auch hier der mehrstufige Montageprozess verwendet.FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build
Alles hier ist dem sehr ähnlich, das Dockerfile
wir für den Client-Teil des Projekts verwendet haben, daher werden wir nicht auf Details eingehen. Es gibt jedoch eine Funktion:RUN apk --no-cache add --virtual builds-deps build-base python
Bevor ich Passwörter in der Datenbank speichere, habe ich sie mit bcrypt gehasht . Dies ist ein sehr beliebtes Paket, aber es gibt einige Probleme bei der Verwendung in alpinen Bildern. Hier können folgende Fehlermeldungen auftreten:node-pre-gyp WARN Pre-built binaries not found for bcrypt@3.0.8 and node@12.16.1 (node-v72 ABI, musl) (falling back to source compile with node-gyp)
npm ERR! Failed at the bcrypt@3.0.8 install script.
Dies ist ein weithin bekanntes Problem. Ihre Lösung besteht darin, zusätzliche Pakete und Python zu installieren, bevor npm-Pakete installiert werden.Der nächste Schritt beim Erstellen des Images, wie im Fall des Clients, besteht darin, das, was im vorherigen Schritt erstellt wurde, mit Node.js auszuführen.FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080
USER node
CMD ["node", "index.js"]
Hier gibt es eine weitere Funktion, die darin besteht, nur die Pakete zu installieren, die für das Projekt in der Produktion vorgesehen sind. Wir brauchen Babel nicht mehr - schließlich wurde bereits im ersten Schritt der Montage alles zusammengestellt. Als Nächstes öffnen wir den Port, 8080
an dem die Serverseite der Anwendung auf das Eintreffen von Anforderungen wartet, und führen Node.js aus.Hier ist die Zusammenfassung Dockerfile
:FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build
FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080
USER node
CMD ["node", "index.js"]
Docker komponieren
Die letzte Phase unserer Arbeit besteht darin, die Container api
und client
den Container mit MongoDB zu bringen. Zu diesem Zweck verwenden wir die Datei docker-compose.yml
im Stammverzeichnis des übergeordneten Repositorys. Dies geschieht aufgrund der Tatsache, dass von diesem Ort aus auf Dateien Dockerfile
für die Client- und Serverteile des Projekts zugegriffen werden kann.Erstellen Sie eine Datei docker-compose.yml
:$ touch docker-compose.yml
Die Struktur der Projektdatei sollte nun wie folgt aussehen.Die endgültige Struktur der ProjektdateienNun werden wir diedocker-compose.yml
folgenden Befehlehinzufügen:version: "3"
services:
api:
build: ./services/api
ports:
- "8080:8080"
depends_on:
- db
container_name: blog-api
client:
build: ./services/client
ports:
- "80:80"
container_name: blog-client
db:
image: mongo
ports:
- "27017:27017"
container_name: blog-db
Alles ist sehr einfach angeordnet. Wir haben drei Dienstleistungen: client
, api
und db
. Es gibt keine Auswahl für MongoDB Dockerfile
- Docker lädt das entsprechende Image von seinem Hub herunter und erstellt daraus einen Container. Dies bedeutet, dass unsere Datenbank leer ist, aber für den Anfang passt dies zu uns.In den Abschnitten api
und client
gibt es einen Schlüssel, build
dessen Wert den Pfad zu den Dateien der Dockerfile
entsprechenden Dienste (zu den Stammverzeichnissen api
und client
) enthält. Die in den Dateien zugewiesenen Container-Ports sind im von Dockerfile
Docker Compose gehosteten Netzwerk geöffnet. Dadurch können Anwendungen interagieren. Bei der Konfiguration des Dienstes api
wird zusätzlich der Schlüssel verwendetdepends_on
. Er teilt Docker mit, dass Sie vor dem Starten dieses Dienstes warten müssen, bis der Container vollständig gestartet ist db
. Dadurch können wir Fehler im Container verhindern api
.Und - hier ist noch eine kleine Sache im Zusammenhang mit MongoDB. In der Backend-Codebasis müssen Sie die Datenbankverbindungszeichenfolge aktualisieren. Normalerweise zeigt es an localhost
:mongodb://localhost:27017/blog
Mit der Docker Compose-Technologie müssen wir jedoch auf den Namen des Containers verweisen:mongodb://blog-db:27017/blog
Der letzte Schritt unserer Arbeit besteht darin, all dies zu starten, indem Sie den docker-compose.yml
folgenden Befehl im Projektstammordner ausführen (in dem sich die Datei befindet ):$ docker-compose up
Zusammenfassung
Wir haben uns eine einfache Technik zum Containerisieren von Anwendungen angesehen, die auf React, Node.js und MongoDB basiert. Wir glauben, dass Sie es bei Bedarf problemlos an Ihre Projekte anpassen können.PS Wir haben den Marktplatz auf der RUVDS-Website gestartet . Das dortige Docker- Image wird mit einem Klick installiert. Sie können den Betrieb von Containern auf dem VPS überprüfen . Neukunden erhalten 3 Tage kostenlos Testkosten.Liebe Leser! Verwenden Sie Docker Compose?