Der Autor wählte die Electronic Frontier Foundation, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.
Shipit ist ein universelles Automatisierungs- und Bereitstellungswerkzeug für Node.js-Entwickler. Es bietet einen Aufgabenablauf, der auf dem populären Orchestrator-Paket, der Anmeldung und den interaktiven SSH-Befehlen über OpenSSH und einer erweiterbaren API basiert. Entwickler können Shipit zur Automatisierung von Erstellungs- und Bereitstellungs-Workflows für eine breite Palette von Node.js-Anwendungen verwenden.
Der Shipit-Workflow ermöglicht Entwicklern nicht nur die Konfiguration von Aufgaben, sondern auch die Angabe der Reihenfolge, in der sie ausgeführt werden; ob sie synchron oder asynchron und in welcher Umgebung sie ausgeführt werden sollen.
In diesem Tutorial werden Sie Shipit installieren und konfigurieren, um eine Node.js-Anwendung aus Ihrer lokalen Entwicklungsumgebung in Ihrer Produktivumgebung bereitzustellen. Sie werden Shipit verwenden, um Ihre Anwendung bereitzustellen und den Remote-Server zu konfigurieren, indem Sie:
rsync
, git
und ssh
).Bevor Sie dieses Tutorial beginnen, benötigen Sie Folgendes:
rsync
und git
.
git
auf Linux-Distributionen zu installieren, folgen Sie dem Tutorial So installieren Sie Git.Git
. Dieses Tutorial verwendet GitHub.Anmerkung: Windows-Benutzer müssen das Windows-Subsystem für Linux installieren, um die Befehle in diesem Leitfaden auszuführen.
Shipit erfordert ein Git-Repository zur Synchronisierung zwischen dem lokalen Entwicklungsrechner und dem Remote-Server. In diesem Schritt erstellen Sie ein Remote-Repository auf Github.com
. Obwohl jeder Anbieter etwas anders ist, sind die Befehle in gewisser Weise übertragbar.
Um ein Repository zu erstellen, öffnen Sie Github.com
in Ihrem Webbrowser und melden Sie sich an. Sie werden feststellen, dass in der oberen rechten Ecke einer beliebigen Seite ein +-Symbol vorhanden ist. Klicken Sie auf + und klicken Sie dann auf New Repository.
Geben Sie einen kurzen, einprägsamen Namen für Ihr Repository ein, z. B. hello-world
. Beachten Sie, dass der Name, den Sie hier wählen, als der Projektordner repliziert wird, von dem aus Sie auf Ihrem lokalen Rechner arbeiten werden.
Fügen Sie optional eine Beschreibung Ihres Repositorys hinzu.
Legen Sie die Sichtbarkeit Ihres Repository –entweder öffentlich oder privat – nach Ihren Wünschen fest.
Stellen Sie sicher, dass das Repository mit einem .gitignore
initialisiert wird, wählen Sie Node
aus der Dropdown-Liste Add gitgnore
aus. Dieser Schritt ist wichtig, um zu vermeiden, dass unnötige Dateien (wie der Ordner node_modules
) zu Ihrem Repository hinzugefügt werden.
Klicken Sie auf die Schaltfläche Create repository.
Das Repository muss jetzt von Github.com
zu Ihrem lokalen Rechner geklont werden.
Öffnen Sie Ihr Terminal und navigieren Sie zu dem Ort, an dem Sie alle Node.js-Projektdateien speichern möchten. Beachten Sie, dass bei diesem Vorgang ein Unterordner innerhalb des aktuellen Verzeichnisses erstellt wird. Führen Sie den folgenden Befehl aus, um das Repository auf Ihren lokalen Rechner zu klonen:
- git clone https://github.com/your-github-username/your-github-repository-name.git
Sie müssen your-githug-username
und your-github-repository-name
ersetzen, um Ihren Github-Benutzernamen und den zuvor angegebenen Repository-Namen widerzuspiegeln.
Anmerkung: Wenn Sie die Zweifaktor-Authentifizierung (2FA) auf Github.com
aktiviert haben, müssen Sie beim Zugriff auf Github über die Befehlszeile anstelle Ihres Passworts ein persönliches Zugriffstoken oder einen SSH-Schlüssel verwenden. Die Github-Hilfeseite zum Thema 2FA bietet weitere Informationen.
Sie sehen eine Ausgabe, die der nachfolgenden ähnelt:
OutputCloning into 'your-github-repository-name'...
remote: Enumerating objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Unpacking objects: 100% (3/3), done.
Wechseln Sie in das Repository, indem Sie den folgenden Befehl ausführen:
- cd your-github-repository-name
Innerhalb des Repositorys befinden sich eine einzige Datei und ein einziger Ordner, beides Dateien, die von Git zur Verwaltung des Repositorys verwendet werden. Sie können dies wie folgt überprüfen:
- ls -la
Sie sehen eine Ausgabe, die der folgenden ähnelt:
Outputtotal 8
0 drwxr-xr-x 4 asciant staff 128 22 Apr 07:16 .
0 drwxr-xr-x 5 asciant staff 160 22 Apr 07:16 ..
0 drwxr-xr-x 13 asciant staff 416 22 Apr 07:16 .git
8 -rw-r--r-- 1 asciant staff 914 22 Apr 07:16 .gitignore
Nachdem Sie nun ein funktionierendes git
-Repository konfiguriert haben, erstellen Sie die Datei shipit.js
, die Ihren Bereitstellungsprozess verwaltet.
In diesem Schritt erstellen Sie ein Beispielprojekt Node.js und fügen dann die Shipit-Pakete hinzu. Dieses Tutorial bietet eine Beispielanwendung – den Node.js Web-Server, der HTTP-Anfragen akzeptiert und mit Hello World
im Klartext antwortet. Um die Anwendung zu erstellen, führen Sie den folgenden Befehl aus:
- nano hello.js
Fügen Sie den folgenden Beispiel-Anwendungscode zu hello.js
hinzu (aktualisiert die Variable APP_PRIVATE_IP_ADDRESS
auf die IP-Adresse Ihres App-Servers im privaten Netzwerk):
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080, 'APP_PRIVATE_IP_ADDRESS');
console.log('Server running at http://APP_PRIVATE_IP_ADDRESS:8080/');
Erstellen Sie jetzt Ihre package.json
-Datei für Ihre Anwendung:
- npm init -y
Dieser Befehl erzeugt eine package.json
-Datei, die Sie zur Konfiguration Ihrer Node.js-Anwendung verwenden werden. Im nächsten Schritt fügen Sie mit der npm
-Befehlszeilenschnittstelle Abhängigkeiten zu dieser Datei hinzu.
OutputWrote to ~/hello-world/package.json:
{
"name": "hello-world",
"version": "1.0.0",
"description": "",
"main": index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Als Nächstes installieren Sie die erforderlichen npm
-Pakete mit folgendem Befehl:
- npm install --save-dev shipit-cli shipit-deploy shipit-shared
Verwenden Sie hier das Flag --save-dev
, da die Shipit-Pakete nur auf Ihrem lokalen Rechner benötigt werden. Sie sehen eine Ausgabe, die der folgenden ähnelt:
Output+ shipit-shared@4.4.2
+ shipit-cli@4.2.0
+ shipit-deploy@4.1.4
updated 4 packages and audited 21356 packages in 11.671s
found 62 low severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
Dadurch wurden auch die drei Pakete zu Ihrer package.json
-Datei als Entwicklungsabhängigkeiten hinzugefügt:
. . .
"devDependencies": {
"shipit-cli": "^4.2.0",
"shipit-deploy": "^4.1.4",
"shipit-shared": "^4.4.2"
},
. . .
Wenn Ihre lokale Umgebung konfiguriert ist, können Sie nun mit der Vorbereitung des Remote-App-Servers für Shipit-basierte Bereitstellungen fortfahren.
In diesem Schritt verwenden Sie ssh
, um sich mit Ihrem App-Server zu verbinden und Ihre Remote-Abhängigkeit rsync
zu installieren. Rsync ist ein Dienstprogramm zur effizienten Übertragung und Synchronisierung von Dateien zwischen lokalen und vernetzten Computern, indem die Änderungszeiten und Größen von Dateien verglichen werden.
Shipit verwendet rsync
zur Übertragung und Synchronisierung von Dateien zwischen Ihrem lokalen Computer und dem Remote-App-Server. Sie werden keine Befehle direkt an rsync
erteilen; Shipit übernimmt das für Sie.
Anmerkung: Mit So richten Sie eine Node.js-Anwendung für die Produktion unter CentOS 7 ein haben Sie die zwei Server App und Web erstellt. Diese Befehle sollten nur auf App ausgeführt werden.
Verbinden Sie Ihren Remote-App-Server über ssh
:
- ssh deployer@your_app_server_ip
Installieren Sie rsync
auf Ihrem Server, indem Sie den folgenden Befehl ausführen:
- sudo yum install rsync
Bestätigen Sie die Installation mit:
- rsync --version
In der Ausgabe dieses Befehls sehen Sie eine ähnliche Zeile:
Outputrsync version 3.1.2 protocol version 31
. . .
Sie können Ihre ssh
-Sitzung durch Eingabe von exit
beenden.
Wenn rsync
installiert und in der Befehlszeile verfügbar ist, können Sie mit den Bereitstellungsaufgaben und ihrer Beziehung zu den Ereignissen fortfahren.
Sowohl Ereignisse als auch Aufgaben sind Schlüsselkomponenten von Shipit-Bereitstellungen, und es ist wichtig zu verstehen, wie sie die Bereitstellung Ihrer Anwendung ergänzen. Die von Shipit ausgelösten Ereignisse stellen bestimmte Punkte im Lebenszyklus der Bereitstellung dar. Ihre Aufgaben werden als Reaktion auf diese Ereignisse ausgeführt, basierend auf der Reihenfolge des Shipit-Lebenszyklus.
Ein gängiges Beispiel, bei dem dieses Aufgaben-/Ereignissystem in einer Node.js-Anwendung nützlich ist, ist die Installation der Abhängigkeiten der Anwendung (node_modules
) auf dem Remote-Server. Später in diesem Schritt lassen Sie Shipit auf das Ereignis updated
(das nach der Übertragung der Anwendungsdateien ausgegeben wird) lauschen und eine Aufgabe ausführen, um die Abhängigkeiten der Anwendung (npm install
) auf dem Remote-Server zu installieren.
Zum Lauschen auf Ereignisse und Ausführen von Aufgaben benötigt Shipit eine Konfigurationsdatei, die Informationen über Ihren Remote-Server enthält (den App-Server) und die Ereignis-Listener und die von diesen Aufgaben auszuführenden Befehle registriert. Diese Datei befindet sich auf Ihrem lokalen Entwicklungsrechner im Verzeichnis Ihrer Node.js-Anwendung.
Um zu beginnen, erstellen Sie diese Datei, einschließlich Informationen über Ihren Remote-Server, die Ereignis-Listener, die Sie abonnieren möchten, und einige Definitionen Ihrer Aufgaben. Erstellen Sie shipitfile.js
in Ihrem Anwendungs-Stammverzeichnis auf Ihrem lokalen Rechner, indem Sie den folgenden Befehl ausführen:
- nano shipitfile.js
Nachdem Sie nun eine Datei erstellt haben, muss sie mit den anfänglichen Umgebungsinformationen, die Shipit benötigt, gefüllt werden. Dies ist in erster Linie der Standort Ihres Remote Git
-Repositorys und vor allem die öffentliche IP-Adresse und das SSH-Benutzerkonto Ihres App-Servers.
Fügen Sie diese Anfangskonfiguration hinzu und aktualisieren Sie die hervorgehobenen Zeilen, um sie an Ihre Umgebung anzupassen:
module.exports = shipit => {
require('shipit-deploy')(shipit);
require('shipit-shared')(shipit);
const appName = 'hello';
shipit.initConfig({
default: {
deployTo: '/home/sammy/your-domain',
repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',
keepReleases: 5,
shared: {
overwrite: true,
dirs: ['node_modules']
}
},
production: {
servers: 'sammy@YOUR_APP_SERVER_PUBLIC_IP'
}
});
const path = require('path');
const ecosystemFilePath = path.join(
shipit.config.deployTo,
'shared',
'ecosystem.config.js'
);
// Our listeners and tasks will go here
};
Die Aktualisierung der variables in Ihrer shipit.initConfig
-Methode stellt Shipit eine für Ihre Bereitstellung spezifische Konfiguration bereit. Diese stellen für Shipit Folgendes dar:
deployTo:
ist das Verzeichnis, in dem Shipit den Code Ihrer Anwendung auf dem Remote-Server bereitstellt. Hier verwenden Sie den Ordner /home/
für einen Benutzer ohne Rootberechtigung und mit sudo
-Berechtigungen (/home/sammy
), da er sicher ist und Probleme mit den Berechtigungen vermieden werden. Die Komponente /your-domain
ist eine Namenskonvention zur Unterscheidung des Ordners von anderen Ordnern im Home-Ordner des Benutzers.repositoryUrl:
ist die URL zu dem vollständigen Git-Repository. Shipit verwendet diese URL, um sicherzustellen, dass die Projektdateien vor der Bereitstellung synchronisiert sind.keepReleases:
ist die Anzahl der Versionen, die auf dem Remote-Server aufbewahrt werden sollen. Ein Release
ist ein mit einem Datumsstempel versehener Ordner, der die Dateien Ihrer Anwendung zum Zeitpunkt der Freigabe enthält. Diese können für das Rollback
einer Bereitstellung nützlich sein.shared:
ist eine mit keepReleases
korrespondierende Konfiguration, die die gemeinsame Nutzung von Verzeichnissen (shared
) zwischen Versionen ermöglicht. In diesem Fall haben wir einen einzigen Ordner node_modules
, der von allen Versionen gemeinsam genutzt wird.production:
stellt einen Remote-Server dar, auf dem Ihre Anwendung bereitgestellt wird. In diesem Fall haben Sie einen einzigen Server (App-Server), den Sie production
nennen, wobei die Konfiguration servers:
Ihrem SSH user
und der public ip address
entspricht. Der Name production
entspricht dem Shipit Bereitstellungsbefehl, der gegen Ende dieses Tutorials verwendet wird (npx shipit server name deploy
oder in Ihrem Fall npx shipit production deploy
).Weitere Informationen zu dem Objekt Shipit-Bereitstellungskonfiguration finden Sie im Shiptit Github-Repository.
Bevor Sie mit der Aktualisierung Ihrer shipitfile.js
fortfahren, lassen Sie uns das folgende Beispielcode-Snippet durchsehen, um die Shipit-Aufgaben zu verstehen:
Example event listenershipit.on('deploy', () => {
shipit.start('say-hello');
});
shipit.blTask('say-hello', async () => {
shipit.local('echo "hello from your local computer"')
});
Dies ist eine Beispielaufgabe, die die shipit.on
-Methode verwendet, um das Ereignis deploy
zu abonnieren. Diese Aufgabe wartet auf die Auslösung des Ereignisses deploy
durch den Shipit-Lebenszyklus, und wenn das Ereignis empfangen wird, führt die Aufgabe die Methode shipit.start
aus, die Shipit anweist, die say-hello
-Aufgabe zu starten
.
Die Methode shipit.on
nimmt zwei Parameter an, den Namen des Ereignisses, auf das zu lauschen ist, und die Rückruffunktion, die beim Empfang des Ereignisses ausgeführt werden soll.
Unter der Methodendeklaration shipit.on
wird die Aufgabe mit der Methode shipit.blTask
definiert. Dadurch wird eine neue Shipit-Aufgabe erstellt, die andere Aufgaben während ihrer Ausführung blockiert (es handelt sich um eine synchrone Aufgabe). Die Methode shipit.blTask
benötigt auch zwei Parameter, den Namen der Aufgabe, die sie definiert, und eine Rückruffunktion, die ausgeführt wird, wenn die Aufgabe durch shipit.start
ausgelöst wird.
Innerhalb der Rückruffunktion dieser Beispielaufgabe (say-hello
) führt die Methode shipit.local
einen Befehl auf dem lokalen Rechner aus. Der lokale Befehl gibt "hello from your local computer"
in die Terminalausgabe aus.
Wenn Sie einen Befehl auf dem Remote-Server ausführen wollten, würden Sie die Methode shipit.remote
verwenden. Die beiden Methoden, shipit.local
und shipit.remote
, stellen eine API zur Verfügung, um Befehle entweder lokal oder als Teil einer Bereitstellung per Fernzugriff auszugeben.
Aktualisieren Sie nun die Datei shipitfile.js
, um Ereignis-Listener einzubeziehen und den Shipit-Lebenszyklus mit shipit.on
zu abonnieren. Fügen Sie die Ereignis-Listener zu Ihrer shipitfile.js
hinzu, indem Sie sie nach dem Kommentar-Platzhalter aus der Anfangskonfiguration // Our tasks will go here
einfügen:
. . .
shipit.on('updated', () => {
shipit.start('npm-install', 'copy-config');
});
shipit.on('published', () => {
shipit.start('pm2-server');
});
Diese beiden Methoden lauschen auf die Ereignisse updated
und published
, die als Teil des Shipit-Bereitstellungslebenszyklus ausgesendet werden. Wenn das Ereignis empfangen wird, initiieren sie jeweils Aufgaben mit der Methode shipit.start
, ähnlich wie bei der Beispielaufgabe.
Nachdem Sie nun die Listener eingeplant haben, fügen Sie die entsprechende Aufgabe hinzu. Fügen Sie die folgende Aufgabe zu Ihrer shipitfile.js
hinzu, indem Sie sie nach den Ereignis-Listenern einfügen:
. . .
shipit.blTask('copy-config', async () => {
const fs = require('fs');
const ecosystem = `
module.exports = {
apps: [
{
name: '${appName}',
script: '${shipit.releasePath}/hello.js',
watch: true,
autorestart: true,
restart_delay: 1000,
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}
]
};`;
fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {
if (err) throw err;
console.log('File created successfully.');
});
await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath);
});
Sie deklarieren zunächst eine Aufgabe namens copy-config
. Diese Aufgabe erstellt eine lokale Datei namens ecosystem.config.js
und kopiert diese Datei dann auf Ihren Remote-App-Server. PM2
verwendet diese Datei, um Ihre Node.js-Anwendung zu verwalten. Sie stellt PM2
die erforderlichen Dateipfadinformationen zur Verfügung, um sicherzustellen, dass Ihre zuletzt bereitgestellten Dateien ausgeführt werden. Später im Build-Prozess erstellen Sie eine Aufgabe, die PM2
mit ecosystem.config.js
als Konfiguration ausführt.
Wenn Ihre Anwendung Umgebungsvariablen benötigt (wie z. B. einen Datenbank-Verbindungszeichenfolge), können Sie diese entweder lokal in env:
oder auf dem Remote-Server in env_production:
auf dieselbe Weise deklarieren, wie Sie die Variable NODE_ENV
in diesen Objekten festlegen.
Fügen Sie nach der Aufgabe copy-config
Ihrer shipitfile.js
-Datei die nächste Aufgabe hinzu:
. . .
shipit.blTask('npm-install', async () => {
shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
});
Als Nächstes deklarieren Sie eine Aufgabe namens npm-install
. Diese Aufgabe verwendet ein Remote-Bash-Terminal (über shipit.remote
), um die Abhängigkeiten der Anwendung (npm
-Pakete) zu installieren.
Fügen Sie nach der Aufgabe npm-install
Ihrer shipitfile.js
-Datei die letzte Aufgabe hinzu:
. . .
shipit.blTask('pm2-server', async () => {
await shipit.remote(`pm2 delete -s ${appName} || :`);
await shipit.remote(
`pm2 start ${ecosystemFilePath} --env production --watch true`
);
});
Abschließend deklarieren Sie eine Aufgabe namens pm2-server
. Diese Aufgabe verwendet ebenfalls ein Remote-Bash-Terminal, um PM2
zunächst durch den Befehl delete
an der Verwaltung Ihrer vorherigen Bereitstellung zu hindern und dann eine neue Instanz Ihres Node.js-Servers zu starten, die die Datei ecosystem.config.js
als Variable bereitstellt. Sie teilen PM2
auch mit, dass es Umgebungsvariablen aus dem Block production
Ihrer Anfangskonfiguration verwenden soll, und fordern PM2
auf, die Anwendung zu überwachen und bei einem Absturz neu zu starten.
Die vollständige Datei shipitfile.js
:
module.exports = shipit => {
require('shipit-deploy')(shipit);
require('shipit-shared')(shipit);
const appName = 'hello';
shipit.initConfig({
default: {
deployTo: '/home/deployer/example.com',
repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',
keepReleases: 5,
shared: {
overwrite: true,
dirs: ['node_modules']
}
},
production: {
servers: 'deployer@YOUR_APP_SERVER_PUBLIC_IP'
}
});
const path = require('path');
const ecosystemFilePath = path.join(
shipit.config.deployTo,
'shared',
'ecosystem.config.js'
);
// Our listeners and tasks will go here
shipit.on('updated', async () => {
shipit.start('npm-install', 'copy-config');
});
shipit.on('published', async () => {
shipit.start('pm2-server');
});
shipit.blTask('copy-config', async () => {
const fs = require('fs');
const ecosystem = `
module.exports = {
apps: [
{
name: '${appName}',
script: '${shipit.releasePath}/hello.js',
watch: true,
autorestart: true,
restart_delay: 1000,
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}
]
};`;
fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {
if (err) throw err;
console.log('File created successfully.');
});
await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath);
});
shipit.blTask('npm-install', async () => {
shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
});
shipit.blTask('pm2-server', async () => {
await shipit.remote(`pm2 delete -s ${appName} || :`);
await shipit.remote(
`pm2 start ${ecosystemFilePath} --env production --watch true`
);
});
};
Speichern und beenden Sie die Datei, wenn Sie fertig sind.
Wenn Ihre shipitfile.js
konfiguriert ist, die Ereignis-Listener und die zugehörigen Aufgaben abgeschlossen sind, können Sie mit der Bereitstellung auf dem App-Server fortfahren.
In diesem Schritt werden Sie Ihre Anwendung remote bereitstellen und testen, ob die Bereitstellung Ihre Anwendung für das Internet verfügbar gemacht hat.
Da Shipit die Projektdateien aus dem Remote-Git-Repository klont, müssen Sie Ihre lokalen Node.js-Anwendungsdateien von Ihrem lokalen Rechner zu Github übertragen. Navigieren Sie zum Anwendungsverzeichnis Ihres Node.js-Projekts (wo sich die Dateien hello.js
und shiptitfile.js
befinden) und führen Sie den folgenden Befehl aus:
- git status
Der Befehl git status
zeigt den Status des Arbeitsverzeichnisses und des Stagingbereichs an. Damit können Sie sehen, welche Änderungen bereitgestellt wurden, welche nicht, und welche Dateien nicht von Git verfolgt werden. Ihre Dateien werden nicht verfolgt und erscheinen in der Ausgabe rot:
OutputOn branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.js
package-lock.json
package.json
shipitfile.js
nothing added to commit but untracked files present (use "git add" to track)
Sie können diese Dateien mit dem folgenden Befehl zu Ihrem Repository hinzufügen:
- git add --all
Dieser Befehl erzeugt keine Ausgabe, obwohl die Dateien bei einer erneuten Ausführung von git status
grün und mit einem Hinweis darauf erscheinen würden, dass es Änderungen gibt, die übernommen werden müssen.
Sie können einen Commit erstellen, indem Sie den folgenden Befehl ausführen:
- git commit -m "Our first commit"
Die Ausgabe dieses Befehls liefert einige Git-spezifische Informationen über die Dateien.
Output[master c64ea03] Our first commit
4 files changed, 1948 insertions(+)
create mode 100644 hello.js
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 shipitfile.js
Jetzt müssen Sie nur noch den Commit mittels Push in das Remote-Repository übertragen, damit Shipit während der Bereitstellung Ihren App-Server klonen kann. Führen Sie den folgenden Befehl aus:
- git push origin master
Die Ausgabe enthält Informationen über die Synchronisation mit dem Remote-Repository:
OutputEnumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 15.27 KiB | 7.64 MiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:Asciant/hello-world.git
e274312..c64ea03 master -> master
Um Ihre Anwendung bereitzustellen, führen Sie den folgenden Befehl aus:
- npx shipit production deploy
Die Ausgabe dieses Befehls (die zu groß ist, um sie in seiner Gesamtheit anzuzeigen) liefert Einzelheiten über die ausgeführten Aufgaben und das Ergebnis der spezifischen Funktion. Die folgende Ausgabe für die Aufgabe pm2-server
zeigt, dass die Anwendung Node.js gestartet wurde:
OutputRunning 'deploy:init' task...
Finished 'deploy:init' after 432 μs
. . .
Running 'pm2-server' task...
Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com".
Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features
@centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting...
@centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances)
@centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐
@centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
@centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤
@centos-ap-app.asciant.com │ hello │ 0 │ 1.0.0 │ fork │ 4177 │ online │ 0 │ 0s │ 0% │ 4.5 MB │ deployer │ enabled │
@centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘
@centos-ap-app.asciant.com Use `pm2 show <id|name>` to get more details about an app
Finished 'pm2-server' after 5.27 s
Running 'deploy:clean' task...
Keeping "5" last releases, cleaning others
Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com".
Finished 'deploy:clean' after 1.81 s
Running 'deploy:finish' task...
Finished 'deploy:finish' after 222 μs
Finished 'deploy' [ deploy:init, deploy:fetch, deploy:update, deploy:publish, deploy:clean, deploy:finish ]
Um Ihre Anwendung aus der Perspektive eines Benutzers zu sehen, können Sie die URL Ihrer Webseite your-domain
in Ihren Browser eingeben, um auf Ihren Web-Server zuzugreifen. Dadurch wird die Node.js-Anwendung auf dem App-Server, auf dem Ihre Dateien bereitgestellt wurden, über Reverse-Proxy bereitgestellt.
Sie sehen die Begrüßung Hello World.
Anmerkung: Nach der ersten Bereitstellung wird Ihr Git-Repository eine neu erstellte Datei namens ecosystem.config.js
verfolgen. Da diese Datei bei jeder Bereitstellung neu erstellt wird und kompilierte Anwendungsgeheimnisse enthalten kann, sollte sie vor dem nächsten git
-Commit zur Datei .gitignore
im Anwendungs-Stammverzeichnis auf Ihrem lokalen Rechner hinzugefügt werden.
. . .
# ecosystem.config
ecosystem.config.js
Sie haben Ihre Node.js-Anwendung auf Ihrem App-Server bereitgestellt, der auf Ihre neue Bereitstellung verweist. Jetzt, wo alles läuft, können Sie zur Überwachung Ihrer Anwendungsprozesse übergehen.
PM2 ist ein ausgezeichnetes Werkzeug zur Verwaltung Ihrer Remote-Prozesse, bietet aber auch Funktionen zur Überwachung der Leistung dieser Anwendungsprozesse.
Stellen Sie mit diesem Befehl über SSH eine Verbindung zu Ihrem Remote-App-Server her:
- ssh deployer@your_app_server_ip
Um spezifische Informationen zu den von PM2 verwalteten Prozessen zu erhalten, führen Sie Folgendes aus:
- pm2 list
Sie sehen eine Ausgabe, die der nachfolgenden ähnelt:
Output┌─────────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬──────┬───────────┬──────────┬──────────┐
│ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├─────────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼──────┼───────────┼──────────┼──────────┤
│ hello │ 0 │ 0.0.1 │ fork │ 3212 │ online │ 0 │ 62m │ 0.3% │ 45.2 MB │ deployer │ enabled │
└─────────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴──────┴───────────┴──────────┴──────────┘
Sie sehen eine Zusammenfassung der Informationen, die PM2 gesammelt hat. Um detaillierte Informationen zu sehen, können Sie Folgendes ausführen:
- pm2 show hello
Die Ausgabe erweitert die durch den Befehl pm2 list
bereitgestellten zusammenfassenden Informationen. Sie liefert auch Informationen über eine Reihe von Zusatzbefehlen und gibt die Speicherorte der Protokolldateien an:
Output Describing process with id 0 - name hello
┌───────────────────┬─────────────────────────────────────────────────────────────┐
│ status │ online │
│ name │ hello │
│ version │ 1.0.0 │
│ restarts │ 0 │
│ uptime │ 82s │
│ script path │ /home/deployer/example.com/releases/20190531213027/hello.js │
│ script args │ N/A │
│ error log path │ /home/deployer/.pm2/logs/hello-error.log │
│ out log path │ /home/deployer/.pm2/logs/hello-out.log │
│ pid path │ /home/deployer/.pm2/pids/hello-0.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 0 │
│ exec cwd │ /home/deployer │
│ exec mode │ fork_mode │
│ node.js version │ 4.2.3 │
│ node env │ production │
│ watch & reload │ ✔ │
│ unstable restarts │ 0 │
│ created at │ 2019-05-31T21:30:48.334Z │
└───────────────────┴─────────────────────────────────────────────────────────────┘
Revision control metadata
┌──────────────────┬────────────────────────────────────────────────────┐
│ revision control │ git │
│ remote url │ N/A │
│ repository root │ /home/deployer/example.com/releases/20190531213027 │
│ last update │ 2019-05-31T21:30:48.559Z │
│ revision │ 62fba7c8c61c7769022484d0bfa46e756fac8099 │
│ comment │ Our first commit │
│ branch │ master │
└──────────────────┴────────────────────────────────────────────────────┘
Divergent env variables from local env
┌───────────────────────────┬───────────────────────────────────────┐
│ XDG_SESSION_ID │ 15 │
│ HOSTNAME │ N/A │
│ SELINUX_ROLE_REQUESTED │ │
│ TERM │ N/A │
│ HISTSIZE │ N/A │
│ SSH_CLIENT │ 44.222.77.111 58545 22 │
│ SELINUX_USE_CURRENT_RANGE │ │
│ SSH_TTY │ N/A │
│ LS_COLORS │ N/A │
│ MAIL │ /var/mail/deployer │
│ PATH │ /usr/local/bin:/usr/bin │
│ SELINUX_LEVEL_REQUESTED │ │
│ HISTCONTROL │ N/A │
│ SSH_CONNECTION │ 44.222.77.111 58545 209.97.167.252 22 │
└───────────────────────────┴───────────────────────────────────────┘
. . .
PM2 bietet auch ein In-Terminal-Überwachungstool, auf das wie folgt zugegriffen werden kann:
- pm2 monit
Die Ausgabe dieses Befehls ist ein interaktives Dashboard, in dem pm2
Prozessinformationen, Protokolle, Metriken und Metadaten in Echtzeit zur Verfügung stellt. Dieses Dashboard kann bei der Überwachung von Ressourcen und Fehlerprotokollen helfen:
Output┌─ Process list ────────────────┐┌─ Global Logs ─────────────────────────────────────────────────────────────┐
│[ 0] hello Mem: 22 MB ││ │
│ ││ │
│ ││ │
└───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘
┌─ Custom metrics (http://bit.l─┐┌─ Metadata ────────────────────────────────────────────────────────────────┐
│ Heap Size 10.73 ││ App Name hello │
│ Heap Usage 66.14 ││ Version N/A │
│ Used Heap Size 7.10 ││ Restarts 0 │
│ Active requests 0 ││ Uptime 55s │
│ Active handles 4 ││ Script path /home/asciant/hello.js │
│ Event Loop Latency 0.70 ││ Script args N/A │
│ Event Loop Latency p95 ││ Interpreter node │
│ ││ Interpreter args N/A │
└───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘
Wenn Sie wissen, wie Sie Ihre Prozesse mit PM2 überwachen können, können Sie fortfahren und lernen, wie Shipit Ihnen bei dem Rollback einer vorherigen funktionierenden Bereitstellung helfen kann.
Beenden Sie ihre ssh
-Sitzung auf Ihrem App-Server, indem Sie exit
ausführen.
Bei der Bereitstellung werden gelegentlich unvorhergesehene Fehler oder Probleme aufgedeckt, die zum Ausfall Ihrer Website führen. Die Entwickler und Betreuer von Shipit haben dies vorausgesehen und Ihnen die Möglichkeit gegeben, ein Rollback zu einer vorherigen (funktionierenden) Bereitstellung Ihrer Anwendung durchzuführen.
Um sicherzustellen, dass Ihre PM2
-Konfiguration erhalten bleibt, fügen Sie shipitfile.js
einen weiteren Ereignis-Listener für das Ereignis rollback
hinzu:
. . .
shipit.on('rollback', () => {
shipit.start('npm-install', 'copy-config');
});
Sie fügen dem Ereignis rollback
einen Listener hinzu, um Ihre Aufgaben npm-install
und copy-config
auszuführen. Dies ist erforderlich, da das Ereignis updated
im Gegensatz zum Ereignis published
beim Rollback einer Bereitstellung nicht durch den Shipit-Lebenszyklus ausgeführt wird. Das Hinzufügen dieses Ereignis-Listeners stellt sicher, dass Ihr PM2
-Prozessmanager selbst im Falle eines Rollbacks auf die letzte Bereitstellung verweist.
Dieser Prozess ähnelt der Bereitstellung, mit einer kleinen Befehlsänderung. Um ein Rollback auf eine frühere Bereitstellung zu versuchen, können Sie Folgendes ausführen:
- npx shipit production rollback
Wie der Befehl deploy
stellt rollback
Details zum Rollback-Prozess und zu den ausgeführten Aufgaben bereit:
OutputRunning 'rollback:init' task...
Get current release dirname.
Running "if [ -h /home/deployer/example.com/current ]; then readlink /home/deployer/example.com/current; fi" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com releases/20190531213719
Current release dirname : 20190531213719.
Getting dist releases.
Running "ls -r1 /home/deployer/example.com/releases" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com 20190531213719
@centos-ap-app.asciant.com 20190531213519
@centos-ap-app.asciant.com 20190531213027
Dist releases : ["20190531213719","20190531213519","20190531213027"].
Will rollback to 20190531213519.
Finished 'rollback:init' after 3.96 s
Running 'deploy:publish' task...
Publishing release "/home/deployer/example.com/releases/20190531213519"
Running "cd /home/deployer/example.com && if [ -d current ] && [ ! -L current ]; then echo "ERR: could not make symlink"; else ln -nfs releases/20190531213519 current_tmp && mv -fT current_tmp current; fi" on host "centos-ap-app.asciant.com".
Release published.
Finished 'deploy:publish' after 1.8 s
Running 'pm2-server' task...
Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com".
Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features
@centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting...
@centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances)
@centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐
@centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
@centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤
@centos-ap-app.asciant.com │ hello │ 0 │ 1.0.0 │ fork │ 4289 │ online │ 0 │ 0s │ 0% │ 4.5 MB │ deployer │ enabled │
@centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘
@centos-ap-app.asciant.com Use `pm2 show <id|name>` to get more details about an app
Finished 'pm2-server' after 5.55 s
Running 'deploy:clean' task...
Keeping "5" last releases, cleaning others
Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com".
Finished 'deploy:clean' after 1.82 s
Running 'rollback:finish' task...
Finished 'rollback:finish' after 615 μs
Finished 'rollback' [ rollback:init, deploy:publish, deploy:clean, rollback:finish ]
Über die Konfiguration keepReleases: 5
in shipitfile.js
haben Sie Shipit so konfiguriert, dass 5 Versionen behalten werden. Shipit verfolgt diese Versionen intern, um sicherzustellen, dass es in der Lage ist, bei Bedarf ein Rollback durchzuführen. Shipit bietet auch eine praktische Möglichkeit, die Releases zu identifizieren, indem es ein Verzeichnis erstellt, das als Zeitstempel benannt wird (JJJJMMTTHHmmss - Beispiel: /home/deployer/your-domain/releases/20190420210548
).
Wenn Sie den Rollback-Prozess weiter anpassen wollten, können Sie auf Ereignisse lauschen, die für den Rollback-Vorgang spezifisch sind. Diese Ereignisse können Sie dann zur Ausführung von Aufgaben verwenden, die Ihren Rollback-Prozess ergänzen. Sie können dazu auf die Ereignisliste in der Aufschlüsselung des Shipit-Lebenszyklus zurückgreifen und die Aufgaben/Listener innerhalb Ihrer shipitfile.js
konfigurieren.
Die Fähigkeit zum Rollback bedeutet, dass Sie Ihren Benutzern immer eine funktionierende Version Ihrer Anwendung zur Verfügung stellen können, selbst wenn eine Bereitstellung unerwartete Fehler/Probleme mit sich bringt.
In diesem Tutorial haben Sie einen Workflow konfiguriert, mit dem Sie eine hochgradig anpassbare Alternative zu „Platform as a Service“ erstellen können, und das alles von zwei Servern aus. Dieser Workflow ermöglicht eine kundenspezifische Bereitstellung und Konfiguration, die Prozessüberwachung mit PM2, die Möglichkeit zur Skalierung und dem Hinzufügen von Diensten oder zusätzlichen Servern oder Umgebungen zu der Bereitstellung, wenn dies erforderlich ist.
Wenn Sie daran interessiert sind, Ihre Node.js-Fähigkeiten weiterzuentwickeln, sehen Sie sich den Inhalt von DigitalOcean Node.js sowie die Serie So codieren Sie in Node.js an.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!