Zusammenfassung der Anwendungspraxis für Docker-Container des Node.js-Dienstes

Zusammenfassung der Anwendungspraxis für Docker-Container des Node.js-Dienstes

In diesem Artikel wird die Verwendung und Installation von Docker-Befehlen nicht erläutert, da dies im vorherigen Artikel, in dem Sie erfahren, wie Sie Docker von Grund auf in die Praxis umsetzen, bereits ausführlich erläutert wurde. Wenn Sie sich nicht sicher sind, können Sie auf den Link klicken, um zurückzugehen und den Artikel noch einmal zu lesen. Der Schwerpunkt dieses Artikels liegt auf der Einführung in die Verwendung der Docker-Containerisierung für Node.js-Projekte und einiger praktischer Optimierungen sowie einiger häufiger Probleme. Wenn Sie weitere Fragen zur Verwendung haben, können Sie natürlich gerne eine Nachricht im Kommentarbereich hinterlassen.

Über den Autor: Wu Yuejun, Nodejs-Entwickler, ein Jugendlicher der 90er Jahre, der Technologie liebt und gerne teilt, öffentliches Konto „Nodejs Technology Stack“, Github-Open-Source-Projekt www.nodejs.red

Was können Sie aus diesem Artikel lernen?

  • Erfahren Sie, wie Sie einen Node.js-Dienst mit Docker in einen Container packen.
  • Dynamisches Festlegen von Umgebungsvariablen zum Erstellen verschiedener Versionen mit einer Docker-Datei
  • So authentifizieren Sie private Node.js-NPM-Pakete beim Erstellen von Images
  • Zu beachtende Probleme bei der Verwendung der Docker-Containerisierung des Egg.js-Frameworks
  • Optimieren der Docker-Imagegröße und Buildzeit

Dockerisieren einer Node.js-Anwendung

In diesem Artikel erstellen wir zunächst eine einfache Node.js-Anwendung, erstellen dann ein Docker-Image für die Anwendung und bauen und führen es aus.

Erstellen eines Node.js-Projekts

Zuerst müssen wir eine app.js erstellen, um einen HTTP-Dienst zu starten, und dann verwenden wir Docker, um dieses Programm auszuführen.

const http = erfordern('http');
konstanter PORT = 30010;

const server = http.createServer((req, res) => {
 res.end('Hallo Docker');
})

server.listen(PORT, () => {
 console.log('Läuft auf http://localhost:', PORT, 'NODE_ENV', process.env.NODE_ENV);
});

Dann erstellen wir eine Datei package.json, die Ihre Anwendung und die erforderlichen Abhängigkeiten beschreibt. Studenten, die Node.js geschrieben haben, sollten damit sehr vertraut sein. Hier habe ich zwei Befehle, npm run dev und npm run pro , in Skripte eingefügt, weil ich zeigen möchte, wie man zur Build-Zeit Parameter übergibt, um Umgebungsvariablen dynamisch festzulegen.

{ 
 "Name": "Hallo-Docker", 
 "version": "1.0.2",
 "Beschreibung": "", 
 "Autor": "Mai",
 "main": "app.js", 
 "Skripte": {
 "dev": "NODE_ENV=dev Knoten app.js",
 "pro": "NODE_ENV=pro node app.js"
 }
}

Docker-Datei

Dies sind die Informationen, die in einer Dockerfile-Datei enthalten sind. Diese Befehle werden auch in Erste Schritte mit Docker und Praxis erklärt.

VON Knoten:10.0-alpine

Führen Sie den Befehl apk --update add tzdata \ aus.
 && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asien/Shanghai" > /etc/Zeitzone \
 && apk del tzdata

RUN mkdir -p /usr/src/nodejs/

ARBEITSVERZEICHNIS /usr/src/nodejs/

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/nodejs/package.json
Führen Sie den Befehl cd /usr/src/nodejs/ aus.
FÜHREN Sie npm i aus

# Code kopieren
KOPIEREN ./usr/src/nodejs/

EXPOSE 30010

CMD npm ausführen dev

Erstellen Sie eine .dockerignore-Datei auf derselben Ebene wie das Dockerfile, um zu vermeiden, dass Ihre lokalen Debugdateien, Node_Module und andere Dateien in den Docker-Container verschoben werden.

.git
Knotenmodule
npm-debug.log

An diesem Punkt können Sie mit dem folgenden Befehl ein Docker-Image erstellen:

$ Docker-Image erstellen -t mayjun/hallo-docker

Dann können Sie einen Docker-Container über den Befehl docker run -d -p 30010:30010 mayjun/hello-docker ausführen, aber ich habe eine Frage. Ich unterscheide zwischen Produktion und Test. Laut dem obigen CMD npm run dev kann nur eine Umgebung gepackt werden. Natürlich können Sie auch eine Datei erstellen, um sie oder andere Methoden zu implementieren.

Dynamisches Festlegen von Umgebungsvariablen

Um die oben genannten Fragen zu lösen, besteht meine Idee darin, beim Erstellen des Images Parameter zu übergeben, um die Umgebungsvariablen dynamisch festzulegen und die Dockerfile-Datei zu ändern. Siehe die folgende Implementierung:

EXPOSE 30010

ARG node_env # Neu hinzugefügt ENV NODE_ENV=$node_env # Neu hinzugefügt CMD npm run ${NODE_ENV} # Ändern

Nachfolgend finden Sie eine Erläuterung des obigen Codes

  • Die ARG-Direktive definiert eine Variable, die Benutzer zur Build-Zeit mit dem Flag --build-arg= des Docker-Build-Befehls an den Builder ARG node_env übergeben können.
  • Verwenden Sie ENV, um auf diese Variable ENV NODE_ENV=$node_env im Dockerfile zu verweisen.
  • Dieser Schritt verwendet CMD npm run ${NODE_ENV}

Jetzt müssen nur noch die Parameter beim Erstellen des Images dynamisch übergeben werden.

$ docker image build --build-arg node_env=dev -t mayjun/hello-docker:1.0.2 . # Eine Testumgebung erstellen $ docker image build --build-arg node_env=pro -t mayjun/hello-docker:1.0.2 . # Eine Produktionsumgebung erstellen

Ausführen des Containers

$ docker run -d -p 30010:30010 mayjun/hallo-docker:1.0.2
$ Docker ps
CONTAINER ID BILD BEFEHL ERSTELLT STATUS PORTS NAMEN
2bc6e62cd0e8 mayjun/hello-docker:1.0.2 "/bin/sh -c 'npm run..." vor 3 Minuten Vor 3 Minuten 0.0.0.0:30010->30010/tcp elastic_bouman

Containerprotokolle anzeigen

Docker-Protokolle -f 2bc6e62cd0e8

> [email protected] dev /usr/src/nodejs
> NODE_ENV=dev node app.js

Wird ausgeführt auf http://localhost:30010 NODE_ENV dev

Ich habe den obigen Code in einen Spiegel mayjun/hello-docker:1.0.2 gepackt, der gezogen und angezeigt werden kann docker pull mayjun/hello-docker:1.0.2

Private NPM-Pakete für Docker und Node.js

Wenn Sie in Ihrem Projekt private NPM-Pakete verwenden, tritt beim Installieren des privaten NPM-Pakets während des Image-Erstellungsprozesses von Docker ein Fehler 404 auf. Wenn es sich außerhalb des Containers befindet, können wir uns mit npm login bei einem Konto mit Berechtigungen für private NPM-Pakete anmelden, um dieses Problem zu lösen. Dies ist jedoch in Docker nicht möglich.

Erstellen eines Authentifizierungstokens

Um private Pakete zu installieren, müssen wir „ Authentifizierungstoken erstellen “, damit wir in der Continuous-Integration-Umgebung und im Docker-Container auf unsere privaten NPM-Pakete zugreifen können. Informationen zum Erstellen dieser Token finden Sie unter https://docs.npmjs.com/creating-and-viewing-authentication-tokens.

Durchführung

Beim Erstellen der Dockerfile-Datei müssen wir die folgenden beiden Befehle hinzufügen:

# 528das62-e03e-4dc2-ba67-********** Dieses Token ist das für Sie erstellte Authentifizierungstoken
RUN echo "//registry.npmjs.org/:_authToken=528das62-e03e-4dc2-ba67-**********" > /root/.npmrc
Führen Sie cat /root/.npmrc aus

Egg-Framework Docker-Containerisierung

Wenn es in Egg egg-scripts start --daemon lautet, entfernen Sie „--daemon“ und verwenden Sie nur „egg-scripts start“, sonst kann der Docker-Container nicht gestartet werden.

Sehen Sie sich das folgende Codebeispiel an und ändern Sie package.json. Die Docker-Datei ist dieselbe wie die erste Dockerized Node.js-Anwendung oben.

Paket.json

{
 "Skripte": {
 "start": "egg-scripts start" // entfernen --daemon
 }
}

Sie können sich auch auf die Egg-Probleme beziehen: „Docker-Container kann nicht ausgeführt werden, ist das schon mal jemandem passiert?“ https://github.com/eggjs/egg/issues/1543

Optimierung der Docker-Imagegröße und -Build-Zeit

Wenn ein Bild nicht optimiert ist, ist seine Größe normalerweise sehr groß. Im Folgenden sind einige in der Praxis durchgeführte Optimierungen aufgeführt.

RUN/COPY-Schichtung

Jede Anweisung im Dockerfile erstellt eine Image-Ebene. Jede Image-Ebene kann wiederverwendet und zwischengespeichert werden, ohne dass die Anweisungen im Dockerfile geändert oder Projektdateien kopiert werden müssen.

Der folgende Code befindet sich im Image-Repository mayjun/hello-docker:latest. Im folgenden Beispiel wird das NPM-Modul nach der Änderung des Quellcodes neu installiert, unabhängig davon, ob sich package.json geändert hat. Das ist offensichtlich nicht gut, daher müssen wir es unten verbessern.

# ...

ARBEITSVERZEICHNIS /usr/src/nodejs/hello-docker
KOPIEREN . /usr/src/nodejs/hello-docker

Führen Sie npm install aus

# ...

Der verbesserte Code lautet wie folgt. Wir erweitern package.json. Wenn package.json nicht geändert wird, wird das NPM-Paket nicht neu installiert, was auch die Bereitstellungszeit verkürzt.

# ...

ARBEITSVERZEICHNIS /usr/src/nodejs/

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/app/package.json
RUN cd /usr/src/app/
FÜHREN Sie npm i aus

# Code kopieren
KOPIEREN . /usr/src/app/

# ...

Optimierung des Node.js Alpine-Images

mayjun/hello-docker:1.0.0 Dieses Image kann auch im Docker-Repository gesucht werden. Es ist vor der Optimierung etwa 688 MB groß.

$ Docker-Bilder REPOSITORY-TAG BILD-ID ERSTELLT GRÖSSE mayjun/hello-docker 1.0.0 7217fb3e9daa vor 5 Sekunden 688 MB

Optimieren mit Alpine

Alpine ist eine sehr kleine Linux-Distribution. Wenn Sie die Größe des Images deutlich reduzieren möchten, ist die Auswahl der Alpine-Version von Node.js am einfachsten. Darüber hinaus ist die Standardzeitzone von Alpine nicht die nationale Zeitzone, sodass die Docker-Datei die Zeitzone konfigurieren muss.

VON Knoten:10.0-alpine

Führen Sie den Befehl apk --update add tzdata \ aus.
 && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asien/Shanghai" > /etc/Zeitzone \
 && apk del tzdata

RUN echo "Asia/Shanghai" > /etc/Zeitzone

RUN mkdir -p /usr/src/nodejs/

ARBEITSVERZEICHNIS /usr/src/nodejs/

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/app/package.json
RUN cd /usr/src/app/
FÜHREN Sie npm i aus

# Code kopieren
KOPIEREN . /usr/src/app/

EXPOSE 30010
CMD npm starten

Habe eine Version mayjun/hello-docker:1.1.0 neu verpackt und die Wirkung noch einmal überprüft. Man sieht, dass die Bilddatei von 688 MB auf 85,3 MB verkleinert wurde. Diese Größenoptimierung ist immer noch sehr groß.

$ Docker-Bilder
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
mayjun/hello-docker 1.1.0 169e05b8197d vor 3 Minuten 85,3 MB

Packen Sie devDependencies nicht in Produktionsumgebungen

Einige in der Testumgebung verwendete Pakete sollten beim Spiegeln der Produktionsumgebung nicht einbezogen werden. Das heißt, das devDependencies-Objekt in der Datei package.json kann gefiltert werden, indem der Parameter --production nach npm i angegeben wird.

Die Verbesserungen sind wie folgt:

VON Knoten:10.0-alpine

# Weglassen...

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/app/package.json
RUN cd /usr/src/app/
RUN npm i --production # Änderungen hier # Ausgelassen...

Habe eine Version mayjun/hello-docker:1.2.0 neu verpackt und den Effekt erneut überprüft. Sie können sehen, dass die Bilddatei von 85,3 MB auf 72,3 MB reduziert wurde

$ Docker-Bilder
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
mayjun/hello-docker 1.2.0 f018aa578711 vor 3 Sekunden 72,3 MB

Häufig gestellte Fragen

Frage 1

Der folgende Befehl meldet beim Löschen des Bildes den folgenden Fehler:

$ Docker rmi 6b1c2775591e
Fehlerantwort vom Daemon: Konflikt: 6b1c2775591e kann nicht gelöscht werden (muss erzwungen werden) – auf das Image wird in mehreren Repositories verwiesen

Wenn Sie vorsichtig sind, stellen Sie möglicherweise fest, dass die Image-ID 6b1c2775591e sowohl auf das Repository „Hello-Docker“ als auch auf das von „mayjun/hello-docker“ verweist, weshalb das Löschen fehlgeschlagen ist.

$ Docker-Bilder
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
mysql 5.7 383867b75fd2 vor 6 Tagen 373 MB
hallo-docker latest 6b1c2775591e vor 7 Tagen 675MB
mayjun/hello-docker latest 6b1c2775591e vor 7 Tagen 675 MB

Geben Sie das zu löschende Repository und Tag an. Überprüfen Sie nach der Ausführung des Löschbefehls noch einmal, dass das Repository mayjun/hello-docker verschwunden ist.

$ docker rmi mayjun/hallo-docker
$ Docker-Bilder   
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
mysql 5.7 383867b75fd2 vor 6 Tagen 373 MB
hallo-docker latest 6b1c2775591e vor 7 Tagen 675MB

Frage 2

Beim Ausführen des Befehls zum Löschen des Bilds wird der folgende Fehler gemeldet:

$ Docker rmi 9be467fd1285
Fehlerantwort vom Daemon: Konflikt: 9be467fd1285 kann nicht gelöscht werden (kann nicht erzwungen werden) – Image wird vom laufenden Container 1febfb05b850 verwendet.

Laut Eingabeaufforderung läuft ein Container. Sie müssen zuerst den Container stoppen, den Container löschen und dann das Image löschen.

$ docker container kill 1febfb05b850 # Container stoppen $ docker rm 1febfb05b850 # Container löschen $ docker rmi 9be467fd1285 # Image löschen

Frage 3

Das festgelegte Arbeitsverzeichnis (WORKDIR) sollte mit den folgenden Angaben übereinstimmen

...
ARBEITSVERZEICHNIS /usr/src/nodejs/

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/node/package.json # Verzeichnisinkonsistenz AUSFÜHREN cd /usr/src/node/ # Verzeichnisinkonsistenz AUSFÜHREN npm i
...

Wenn beispielsweise die obige Konfiguration nicht mit dem Arbeitsverzeichnis und dem tatsächlichen COPY-Verzeichnis übereinstimmt, wird der folgende Fehler gemeldet:

Ändern Sie es dann wie folgt

...
ARBEITSVERZEICHNIS /usr/src/nodejs/

# npm-Paket hinzufügen
KOPIEREN Sie package.json /usr/src/nodejs/package.json # Wechseln Sie zum gleichen RUN cd /usr/src/nodejs/ # Wechseln Sie zum gleichen RUN npm i
...

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Lernen Sie, wie Sie mit TypeScript Node.js-Anwendungen entwickeln
  • Luvit schreibt Lua-Anwendungen wie Node.js
  • Eine kurze Diskussion über Node.js-Unterprozesse und Anwendungsszenarien
  • Weitergabe von Anwendungstipps zur Verbesserung der Node.js-Leistung
  • Wie gut kennen Sie sich mit den grundlegenden Anwendungen von Node.js aus?

<<:  MYSQL8.0.13 kostenlose Installationsversion Konfiguration Tutorial Beispiel detaillierte Erklärung

>>:  Tutorial zur kostenlosen Konfiguration der MySQL 8.0.13-Installationsversion in einer Windows-Umgebung

Artikel empfehlen

So migrieren Sie das Datenverzeichnis in Docker

Inhaltsverzeichnis Datenträgernutzung anzeigen Da...

Detaillierte Analyse der MySQL Master-Slave-Replikation

Vorwort: In MySQL sollte die Master-Slave-Archite...

So simulieren Sie eine Aufzählung mit JS

Vorwort Im aktuellen JavaScript gibt es kein Konz...

Detaillierte Erläuterung der Nginx-Zugriffsbeschränkungskonfiguration

Was ist die Nginx-Zugriffsbeschränkungskonfigurat...

Wie versteht JS Daten-URLs?

Inhaltsverzeichnis Überblick Erste Schritte mit D...

Einführung in die MySQL-Ansicht und Tutorial zur grundlegenden Bedienung

Vorwort Ansicht ist ein sehr nützliches Datenbank...

Methode zum dynamischen Laden von Geojson basierend auf Vue+Openlayer

Laden eines oder mehrerer Features <Vorlage>...

So starten Sie mehrere MySQL-Instanzen in CentOS 7.0 (mysql-5.7.21)

Konfigurationsanweisungen Linux-System: CentOS-7....

html+css+js zur Realisierung der Funktion der Fotovorschau und des Bildhochladens

Vorwort: Wenn wir Webseiten erstellen, müssen wir...

Beispiel für die Erschöpfung der MySQL-Auto-Increment-ID

Anzeigedefinitions-ID Wenn die in der Tabelle def...

MySQL Serie 4 SQL-Syntax

Inhaltsverzeichnis Tutorial-Reihe 1. Einführung u...

Detaillierte Erklärung der Filter und Anweisungen in Vue

Inhaltsverzeichnis benutzerdefinierte Vue-Direkti...