Andocken einer Anwendung, die auf React, Express und MongoDB basiert

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 Dockerfileund 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-Dateibaum

Anwendung 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 Dockerfileim 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.jsonund installieren Sie in diesem Containerordner die Abhängigkeiten. Dann /appkopieren 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 nginxErgebnisse 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 Dockerfilesieht 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 Dockerfileim 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 Dockerfilewir 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, 8080an 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 apiund clientden Container mit MongoDB zu bringen. Zu diesem Zweck verwenden wir die Datei docker-compose.ymlim Stammverzeichnis des übergeordneten Repositorys. Dies geschieht aufgrund der Tatsache, dass von diesem Ort aus auf Dateien Dockerfilefü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 Projektdateien

Nun werden wir diedocker-compose.ymlfolgenden 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, apiund 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 apiund clientgibt es einen Schlüssel, builddessen Wert den Pfad zu den Dateien der Dockerfileentsprechenden Dienste (zu den Stammverzeichnissen apiund client) enthält. Die in den Dateien zugewiesenen Container-Ports sind im von DockerfileDocker Compose gehosteten Netzwerk geöffnet. Dadurch können Anwendungen interagieren. Bei der Konfiguration des Dienstes apiwird 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.ymlfolgenden 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?


All Articles