One place for hosting & domains

      Verwendung

      Ausführen verschiedener PHP-Versionen auf einem Server unter Verwendung von Apache und PHP-FPM unter Debian 10


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Der Apache-Webserver verwendet virtuelle Hosts zur Verwaltung mehrerer Domänen auf einer einzigen Instanz. In ähnlicher Weise verwendet PHP-FPM einen Daemon, um mehrere PHP-Versionen auf einer einzigen Instanz zu verwalten. Zusammen können Sie Apache und PHP-FPM verwenden, um mehrere PHP-Webanwendungen zu hosten, von denen jede eine andere Version von PHP verwendet, alle auf dem gleichen Server und alle zur gleichen Zeit. Dies ist nützlich, da verschiedene Anwendungen möglicherweise verschiedene Versionen von PHP erfordern, aber einige Server-Stacks, wie ein herkömmlich konfigurierter LAMP-Stack, nur einen verwalten können. Die Kombination von Apache mit PHP-FPM ist auch eine kosteneffizientere Lösung als das Hosting jeder Anwendung auf ihrer eigenen Instanz.

      PHP-FPM bietet auch Konfigurationsoptionen für stderr– und stdout-Protokollierung, Notfall-Neustarts und adaptives Prozess-Spawning, was bei stark ausgelasteten Sites nützlich ist. Tatsächlich ist der Einsatz von Apache mit PHP-FPM einer der besten Stacks für das Hosting von PHP-Anwendungen, insbesondere, wenn es um die Leistung geht.

      In diesem Tutorial richten Sie zwei PHP-Sites auf einer einzigen Instanz ein. Jede Site verwendet ihre eigene Domäne und jede Domäne stellt ihre eigene PHP-Version bereit. Die erste, site1.your_domain, stellt PHP 7.0 bereit. Die zweite, site2.your_domain, stellt PHP 7.2 bereit.

      Voraussetzungen

      Schritt 1 – Installieren von PHP Versionen 7.0 und 7.2 mit PHP-FPM

      Nachdem die Voraussetzungen erfüllt sind, installieren Sie nun PHP-Versionen 7.0 und 7.2 sowie PHP-FPM als auch mehrere zusätzliche Erweiterungen. Dazu müssen Sie jedoch zunächst das sury php-Repository zu Ihrem System hinzufügen.

      Installieren Sie zunächst mehrere erforderliche Pakete, einschließlich curl, wget und gnupg2:

      • sudo apt-get install curl wget gnupg2 ca-certificates lsb-release apt-transport-https -y

      Mit den obigen Paketen können Sie sicher auf das sury php-Repository zugreifen. sury php ist ein Drittanbieter-Repository oder PPA (Personal Package Archive). Es stellt PHP 7.4, 7.3, 7.2, 7.1 und 7.0 für das Debian-Betriebssystem bereit. Außerdem bietet es aktuellere Versionen von PHP als die offiziellen Debian 10-Repositorys und Sie können verschiedene Versionen von PHP im gleichen System installieren.

      Als Nächstes importieren Sie den Schlüssel des Pakets:

      • wget https://packages.sury.org/php/apt.gpg
      • sudo apt-key add apt.gpg

      Fügen Sie nun das Repository sury php Ihrem System hinzu:

      • echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php7.list

      Aktualisieren Sie das Repository:

      Installieren Sie als Nächstes php7.0, php7.0-fpm, php7.0-mysql, libapache2-mod-php7.0, und libapache2-mod-fcgid mit den folgenden Befehlen:

      • sudo apt-get install php7.0 php7.0-fpm php7.0-mysql libapache2-mod-php7.0 libapache2-mod-fcgid -y
      • php7.0 ist ein Metapaket zur Ausführung von PHP-Anwendungen.
      • php7.0-fpm bietet den Fast Process Manager-Interpreter, der als Daemon ausgeführt wird und Fast/CGI-Anfragen empfängt.
      • php7.0-mysql verbindet PHP mit der MySQL-Datenbank.
      • libapahce2-mod-php7.0 stellt das PHP-Modul für den Apache-Webserver bereit.
      • libapache2-mod-fcgid enthält eine mod_fcgid, die eine Reihe von CGI-Programminstanzen startet, um gleichzeitige Anfragen zu bearbeiten.

      Wiederholen Sie den Vorgang für PHP-Version 7.2. Installieren Sie php7.2, php7.2-fpm, php7.2-mysql und libapache2-mod-php7.2.

      • sudo apt-get install php7.2 php7.2-fpm php7.2-mysql libapache2-mod-php7.2 -y

      Starten Sie nach Installation beider PHP-Versionen den Dienst php7.0-fpm:

      • sudo systemctl start php7.0-fpm

      Überprüfen Sie als Nächstes den Status des php7.0-fpm-Dienstes:

      • sudo systemctl status php7.0-fpm

      Sie sehen die folgende Ausgabe:

      Output

      ● php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-04-04 08:51:47 UTC; 1min 17s ago Docs: man:php-fpm7.0(8) Main PID: 13016 (php-fpm7.0) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1149) Memory: 19.1M CGroup: /system.slice/php7.0-fpm.service ├─13016 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf) ├─13017 php-fpm: pool www └─13018 php-fpm: pool www Apr 04 08:51:47 debian10 systemd[1]: Starting The PHP 7.0 FastCGI Process Manager... Apr 04 08:51:47 debian10 systemd[1]: Started The PHP 7.0 FastCGI Process Manager.

      Wiederholen Sie diesen Vorgang nun zum Starten des php7.2-fpm-Dienstes:

      • sudo systemctl start php7.2-fpm

      Und überprüfen Sie dann den Status des php7.2-fpm-Dienstes:

      • sudo systemctl status php7.2-fpm

      Sie sehen die folgende Ausgabe:

      Output

      ● php7.2-fpm.service - The PHP 7.2 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php7.2-fpm.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-04-04 08:52:52 UTC; 1min 32s ago Docs: man:php-fpm7.2(8) Process: 22207 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.2/fpm/pool.d/www.conf 72 (code=exite Main PID: 22204 (php-fpm7.2) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1149) Memory: 12.0M CGroup: /system.slice/php7.2-fpm.service ├─22204 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf) ├─22205 php-fpm: pool www └─22206 php-fpm: pool www Apr 04 08:52:52 debian10 systemd[1]: Starting The PHP 7.2 FastCGI Process Manager... Apr 04 08:52:52 debian10 systemd[1]: Started The PHP 7.2 FastCGI Process Manager.

      Abschließend müssen Sie mehrere Module aktivieren, damit Ihr Apache2-Dienst mit mehreren PHP-Versionen arbeiten kann:

      • sudo a2enmod actions fcgid alias proxy_fcgi
      • actions wird für die Ausführung von CGI-Skripten verwendet, die auf Medientyp oder Anfragemethode basieren.

      • fcgid ist eine hochleistungsfähige Alternative zu mod_cgi, die eine ausreichende Anzahl von Instanzen des CGI-Programms zur Bearbeitung simultaner Anfragen startet.

      • alias stellt die Abbildung verschiedener Teile des Host-Dateisystems im Dokumentenbaum bereit und dient der URL-Umleitung.

      • proxy_fcgi ermöglicht Apache die Weiterleitung von Anfragen an PHP-FPM.

      Starten Sie nun den Apache-Dienst neu, um Ihre Änderungen zu übernehmen:

      • sudo systemctl restart apache2

      Zu diesem Zeitpunkt haben Sie zwei PHP-Versionen auf Ihrem Server installiert. Als Nächstes erstellen Sie eine Verzeichnisstruktur für jede Website, die Sie bereitstellen möchten.

      Schritt 2 — Erstellen von Verzeichnisstrukturen für beide Websites

      In diesem Abschnitt erstellen Sie für beide Websites ein Dokumentenverzeichnis und eine Indexseite.

      Erstellen Sie zunächst Dokument-Stammverzeichnisse sowohl für site1.your_domain als auch für site2.your_domain:

      • sudo mkdir /var/www/site1.your_domain
      • sudo mkdir /var/www/site2.your_domain

      Standardmäßig wird der Apache-Webserver als Benutzer www-data und als Gruppe www-data ausgeführt. Um sicherzustellen, dass Sie über die korrekte Eigentümerschaften und Berechtigungen für die Stammverzeichnisse Ihrer Website verfügen, führen Sie die folgenden Befehle aus:

      • sudo chown -R www-data:www-data /var/www/site1.your_domain
      • sudo chown -R www-data:www-data /var/www/site2.your_domain
      • sudo chmod -R 755 /var/www/site1.your_domain
      • sudo chmod -R 755 /var/www/site2.your_domain

      Erstellen Sie als Nächstes in jedem Stammverzeichnis Ihrer Website eine Datei info.php. Dadurch werden die PHP-Version jeder Website angezeigt. Beginnen Sie mit site1:

      • sudo nano /var/www/site1.your_domain/info.php

      Fügen Sie die folgende Zeile hinzu:

      /var/www/site1.your_domain/info.php

      <?php phpinfo(); ?>
      

      Speichern und schließen Sie die Datei. Kopieren Sie nun die von Ihnen erstellte Datei info.php nach site2:

      • sudo cp /var/www/site1.your_domain/info.php /var/www/site2.your_domain/info.php

      Ihr Webserver sollte nun über die Stammverzeichnisse der Dokumente verfügen, die jede Site benötigt, um Besuchern Daten zur Verfügung zu stellen. Als Nächstes konfigurieren Sie Ihren Apache-Webserver, um mit zwei verschiedenen PHP-Versionen zu arbeiten.

      Schritt 3 – Konfigurieren von Apache für beide Websites

      In diesem Abschnitt erstellen Sie zwei Konfigurationsdateien für virtuelle Hosts. Dadurch können Ihre beiden Websites gleichzeitig mit zwei verschiedenen PHP-Versionen arbeiten.

      Damit Apache diesen Inhalt bereitstellen kann, ist es erforderlich, eine virtuelle Host-Datei mit den richtigen Anweisungen zu erstellen. Anstatt die Standardkonfigurationsdatei unter /etc/apache2/sites-available/000-default.conf zu ändern, erstellen Sie zwei neue in dem Verzeichnis /etc/apache2/sites-available.

      Erstellen Sie zunächst eine neue Konfigurationsdatei für einen virtuellen Host für die Website site1.your_domain. Hier weisen Sie Apache an, Inhalte mit php7.0 zu rendern:

      • sudo nano /etc/apache2/sites-available/site1.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie sicher, dass der Website-Verzeichnispfad, der Servername und die PHP-Version mit Ihrer Einrichtung übereinstimmen:

      /etc/apache2/sites-available/site1.your_domain.conf

      
      <VirtualHost *:80>
           ServerAdmin admin@site1.your_domain
           ServerName site1.your_domain
           DocumentRoot /var/www/site1.your_domain
           DirectoryIndex info.php
      
           <Directory /var/www/site1.your_domain>
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              allow from all
           </Directory>
      
          <FilesMatch .php$>
            # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
            SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
          </FilesMatch>
      
           ErrorLog ${APACHE_LOG_DIR}/site1.your_domain_error.log
           CustomLog ${APACHE_LOG_DIR}/site1.your_domain_access.log combined
      </VirtualHost>
      

      In dieser Datei haben Sie die DocumentRoot auf Ihr neues Verzeichnis und ServerAdmin auf eine E-Mail aktualisiert, auf die der Administrator der Website your_domain zugreifen kann. Weiterhin haben Sue ServerName aktualisiert, der die Basisdomäne für diese Konfiguration des virtuellen Hosts festlegt, und Sie haben eine Anweisung SetHandler hinzugefügt, um PHP als fastCGI-Prozessserver auszuführen.

      Speichern und schließen Sie die Datei.

      Erstellen Sie als Nächstes eine neue Konfigurationsdatei des virtuellen Hosts für die Website site2.your_domain. Sie geben diese Subdomäne für die Bereitstellung von php7.2 an:

      • sudo nano /etc/apache2/sites-available/site2.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie auch hier sicher, dass der Website-Verzeichnispfad, der Servername und die PHP-Version mit Ihrer Einrichtung übereinstimmen:

      /etc/apache2/sites-available/site2.your_domain.conf

      <VirtualHost *:80>
           ServerAdmin admin@site2.your_domain
           ServerName site2.your_domain
           DocumentRoot /var/www/site2.your_domain
           DirectoryIndex info.php  
      
           <Directory /var/www/site2.your_domain>
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              allow from all
           </Directory>
      
          <FilesMatch .php$>
            # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
            SetHandler "proxy:unix:/run/php/php7.2-fpm.sock|fcgi://localhost"
          </FilesMatch>
      
           ErrorLog ${APACHE_LOG_DIR}/site2.your_domain_error.log
           CustomLog ${APACHE_LOG_DIR}/site2.your_domain_access.log combined
      </VirtualHost>
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei. Überprüfen Sie anschließend die Apache-Konfigurationsdatei auf etwaige Syntaxfehler:

      • sudo apachectl configtest

      Sie sehen die folgende Ausgabe:

      Output

      Syntax OK

      Aktivieren Sie dann beide Konfigurationsdateien des virtuellen Hosts:

      • sudo a2ensite site1.your_domain
      • sudo a2ensite site2.your_domain

      Deaktivieren Sie nun die Standardseite, da Sie sie nicht benötigen:

      • sudo a2dissite 000-default.conf

      Starten Sie schließlich den Apache-Dienst neu, um Ihre Änderungen zu übernehmen:

      • sudo systemctl restart apache2

      Nachdem Sie Apache nun konfiguriert haben, um jede Site zu bedienen, werden Sie sie testen, um sicherzustellen, dass die richtigen PHP-Versionen ausgeführt werden.

      Schritt 4 – Testen beider Websites

      Zu diesem Zeitpunkt haben Sie zwei Websites konfiguriert, um zwei verschiedene PHP-Versionen auszuführen. Testen Sie nun die Ergebnisse.

      Öffnen Sie Ihren Webbrowser und besuchen Sie beide Sites http://site1.your_domain und http://site2.your_domain. Sie sehen zwei Seiten, die wie folgt aussehen:

      PHP 7.0 InfoseitePHP 7.2 Infoseite

      Beachten Sie die Titel. Die erste Seite zeigt an, dass site1.your_domain PHP-Version 7.0 bereitstellt. Die zweite zeigt an, dass site2.your_domain PHP-Version 7.2 bereitstellt.

      Nachdem Sie nun Ihre Sites getestet haben, entfernen Sie die Dateien info.php. Da sie sensible Informationen über Ihren Server enthalten und für unberechtigte Benutzer zugänglich sind, stellen sie eine Sicherheitsbedrohung dar. Führen Sie zur Entfernung beider Dateien die folgenden Befehle aus:

      • sudo rm -rf /var/www/site1.your_domain/info.php
      • sudo rm -rf /var/www/site2.your_domain/info.php

      Jetzt verfügen Sie über einen einzelnen Debian 10-Server, der zwei Websites mit zwei verschiedenen PHP-Versionen handhabt. PHP-FPM ist jedoch nicht auf diese eine Anwendung beschränkt.

      Zusammenfassung

      Sie haben nun virtuelle Hosts und PHP-FPM kombiniert, um mehrere Websites und mehrere PHP-Versionen auf einem einzigen Server bereitzustellen. Die einzige praktische Beschränkung der Anzahl der PHP-Sites und PHP-Versionen, die Ihr Apache-Dienst verarbeiten kann, ist die Verarbeitungsleistung Ihrer Instanz.

      Von hier aus können Sie die fortgeschritteneren Funktionen von PHP-FPM erkunden, wie den adaptiven Spawning-Prozess oder wie sdtout und stderr protokolliert werden können. Alternativ können Sie jetzt auch Ihre Websites sichern. Zu diesem Zweck können Sie unserem Tutorial zum Sichern Ihrer Sites mit kostenlosen TLS/SSL-Zertifikaten von Let’s Encrypt folgen.



      Source link

      Erstellen einer Anwendung für ein inspirierendes Zitat unter Verwendung von AdonisJs und MySQL


      Der Autor wählte den Tech Education Fund, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      AdonisJs ist ein in einfachem JavaScript geschriebenes Node.js Web-Framework, das auf allen gängigen Betriebssystemen läuft. Es verwendet das beliebte Designmuster MVC (Model – View – Controller) und bietet ein stabiles Ökosystem für das Schreiben serverseitiger Webanwendungen. Das Framework bietet nahtlose Authentifizierung, SQL ORM (objekt-relationales Mapping), Migrationen und Datenbank-Seeding. AdonisJs weist eine ähnliche Architektur wie das PHP Webanwendungs-Framework Laravel auf, einschließlich der gleichen Ordnerstruktur und mehrere gemeinsam genutzter Einrichtungskonzepte.

      Standardmäßig verwendet AdonisJs die Edge Template Engine, die für eine intuitive Verwendung konzipiert ist. Genau wie Laravel wird AdonisJs mit einem ORM namens Lucid bereitgestellt, das als Schnittstelle für die Kommunikation zwischen den Modellen einer Anwendung und der Datenbank dient. Mit AdonisJs können Entwickler eine Full-Stack-Anwendung erstellen, bei der der Backend-Server für die Anwendung der Geschäftslogik, das Routing und das Rendering aller Seiten der Anwendung verantwortlich ist. Es ist auch möglich, eine Webdienst-API zu erstellen, um JSON-Antworten von einem Controller zurückzugeben; diese Webdienste können dann über Frontend-Frameworks wie Vue.js, React und Angular konsumiert werden.

      In diesem Tutorial erstellen Sie eine Anwendung mit AdonisJs unter Verwendung seiner CLI. Sie erstellen Routen, Controller, Modelle und Ansichten innerhalb Ihrer Anwendung und führen Formularvalidierungen durch. Das Beispiel in diesem Tutorial wird eine Anwendung für ein inspirierendes Zitat sein, bei der sich ein Benutzer registrieren und anmelden kann, um ein inspirierendes Zitat zu erstellen. Diese Demo-Anwendung bietet Ihnen die Möglichkeit zur Ausführung von CRUD (Create, Read, Update und Delete)-Operationen.

      Voraussetzungen

      Bevor Sie mit diesem Leitfaden beginnen, benötigen Sie Folgendes:

      Anmerkung: Dieses Tutorial verwendet für die Entwicklung einen macOS-Rechner. Wenn Sie ein anderes Betriebssystem verwenden, müssen Sie in den ersten Schritten möglicherweise sudo für npm-Befehle verwenden.

      Schritt 1 – Installieren der Adonis CLI

      In diesem Abschnitt werden Sie Adonis CLI und alle erforderlichen Pakete auf Ihrem lokalen Rechner installieren. Die CLI ermöglicht es Ihnen, ein neues AdonisJs-Projekt aufzubauen, sowie Boilerplates für Controller, Middlewares und Modelle in Ihrer Anwendung zu erstellen und zu generieren. Außerdem erstellen Sie Ihre Datenbank für das Projekt.

      Führen Sie den folgenden Befehl aus, um die AdonisJs CLI global auf Ihrem Rechner über npm zu installieren:

      Geben Sie nach Abschluss der Installation den folgenden Befehl im Terminal ein, um die Installation von AdonisJs zu bestätigen und die aktuelle Version anzuzeigen:

      Sie sehen eine Ausgabe, die die aktuelle Version von AdonisJs zeigt:

      Output

      4.1.0

      Mit der erfolgreichen Installation der AdonisJs CLI haben Sie nun Zugriff auf den Befehl adonis und können ihn zum Erstellen neuer Installationen eines AdonisJs-Projekts, zur Verwaltung Ihres Projekts und zum Erzeugen relevanter Dateien wie die Controller, Modelle usw. verwenden.

      Nun können Sie mit der Erstellung eines neuen AdonisJs-Projekts fortfahren, indem Sie den Befehl adonis wie hier gezeigt verwenden:

      • adonis new adonis-quotes-app

      Der vorhergehende Befehl erstellt eine Anwendung namens adonis-quotes-app​​​ in einem neuen Verzeichnis mit demselben Namen in Ihrem lokalen Projektverzeichnis mit der entsprechenden AdonisJs MVC-Struktur.

      Verschieben Sie sie in den neuen Anwendungsordner:

      Starten Sie dann Ihre Anwendung durch Ausführen von:

      Dadurch wird der Entwicklungsserver auf dem Standardport 3333 gestartet, wie in der Root-Datei .env für Ihre Anwendung angegeben. Navigieren Sie zu http://localhost:3333, um die Begrüßungsseite von AdonisJs anzuzeigen.

      Begrüßungsseite von AdonisJs

      Jetzt schließen Sie die Einrichtung Ihrer Datenbank ab. Hier installieren Sie den Treiber mysql, um sich über npm von Ihrer Node.js-Anwendung mit Ihrem MySQL-Server zu verbinden. Gehen Sie zunächst wieder zu Ihrem Terminal zurück, auf dem die Anwendung derzeit läuft, beenden Sie den Prozess mit STRG+C und führen Sie den folgenden Befehl aus:

      Nachdem Sie nun den MySQL Node.js-Treiber für diese Anwendung erfolgreich installiert haben, müssen Sie die Anwendungsdatenbank erstellen und die entsprechende Verbindung zu ihr aufbauen.

      Die neueste Version von MySQL, die Sie aus dem vorbereitendem Tutorial installiert haben, verwendet ein standardmäßiges Authentifizierungs-Plugin namens caching_ha2_password. Dieses wird derzeit von den Node.js-Treibern für MySQL nicht unterstützt. Um Probleme mit der Datenbankverbindung in Ihrer Anwendung zu vermeiden, müssen Sie einen neuen MySQL-Benutzer anlegen und das derzeit unterstützte Authentifizierungs-Plugin mysql_native_password verwenden.

      Um zu beginnen, greifen Sie mit dem Account root auf den MySQL-Client zu:

      Sie werden aufgefordert, das während der MySQL-Installation eingerichtete Passwort für den Account root einzugeben.

      Erstellen Sie als Nächstes den Benutzer und das Passwort unter Verwendung des Plugins mysql_native_password:

      • CREATE USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

      Sie sehen den folgenden Output:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Erstellen Sie nachfolgend eine Datenbank für die Anwendung mit:

      Sie sehen den folgenden Output:

      Output

      Query OK, 1 row affected (0.03 sec)

      Damit haben Sie die Datenbank für diese Anwendung erfolgreich erstellt.

      Aktivieren Sie jetzt den Zugriff auf die erstellte Datenbank für den neuen MySQL-Benutzer. Führen Sie den folgenden Befehl aus, um dem Benutzer alle Berechtigungen in der Datenbank zu erteilen:

      • GRANT ALL PRIVILEGES ON adonis.* TO 'sammy'@'localhost';

      Laden Sie die Berechtigungstabelle neu, indem Sie den folgenden Befehl ausführen, um die soeben vorgenommenen Änderungen zu übernehmen:

      Sie sehen den folgenden Output:

      Output

      Query OK, 0 rows affected (0.00 sec)

      Beenden Sie den MySQL-Client mit:

      Sie haben die AdonisJs CLI erfolgreich installiert, ein neues AdonisJs-Projekt erstellt und mysql über npm installiert.  Außerdem haben Sie die Datenbank für diese Anwendung erstellt und einen MySQL-Benutzer mit den entsprechenden Berechtigungen eingerichtet. Dies ist die Grundeinrichtung für Ihre Anwendung. Im nächsten Abschnitt beginnen Sie mit der Erstellung der erforderlichen Ansichten für Ihre Anwendung.

      Schritt 2 – Verwenden der Edge Templating Engine

      AdonisJs wird mit einer eigenen Template-Engine namens Edge bereitgestellt. Sie ermöglicht Ihnen die Erstellung einer wiederverwendbaren HTML-Vorlage und die Einführung von Front-End-Logik in Ihre Anwendung mit minimalem Code. Edge stellt JavaScript-Entwickler während der Entwicklung einer Anwendung die Werkzeuge zur Verfügung, um ein komponentenbasiertes Layout zu erstellen, Bedingungen zu schreiben, Iterationen zu verwenden und Anzeigeebenen zur Aufnahme der Logik zu erstellen. Alle Template-Dateien enden mit der Erweiterung .edge und werden im Verzeichnis resources/views gespeichert.

      Nachfolgend sind die Ansichten aufgeführt, die Ihre Anwendung für die ordnungsgemäße Funktionsweise benötigt:

      • Master Layout: Mit Edge können Sie eine Seite erstellen, die das CSS, gängige JavaScript-Dateien, jQuery und gängige Bestandteile der Benutzeroberfläche enthält, die in der gesamten Anwendung gleich bleiben, wie zum Beispiel die Navigationsleiste, das Logo, der Header usw. Sobald Sie die Seite Master Layout erstellt haben, übernehmen andere Ansichten (Seiten) in Ihrer Anwendung diese.
      • Index View: Diese Seite verwendet das Master Layout, um gängige Dateien zu erben und Inhalte für die Homepage der Anwendung darzustellen.
      • Login-Seite: Diese Seite verwendet ebenfalls das Master Layout und stellt das Formular mit den Eingabefeldern für Benutzername und Passwort für die Anmeldung der Benutzer dar.
      • Register-Seite: Hier sehen Benutzer ein Formular zur Registrierung und zur dauerhaften Speicherung der Informationen in der Datenbank.
      • Create Quote-Seite: Benutzer werden diese Seite zum Erstellen eines inspirierenden Zitats verwenden.
      • Edit Quote-Seite: Benutzer werden diese Seite zum Bearbeiten eines Zitats verwenden.
      • View Quote-Seite: Benutzer werden diese Seite zum Anzeigen eines bestimmten Zitats verwenden.

      Verwenden Sie zunächst den Befehl adonis, um die Seite Master Layout zu erstellen, indem Sie den folgenden Befehl ausführen:

      • adonis make:view layouts/master

      Sie werden eine Ausgabe ähnlich der folgenden sehen:

      Output

      ✔ create resources/views/layouts/master.edge

      Dieser Befehl erstellt automatisch eine Datei master.edge in Ihrem Ordner resources/views/layouts. Öffnen Sie die neue Datei:

      • nano resources/views/layouts/master.edge

      Fügen Sie den folgenden Code hinzu:

      /resources/views/layouts/master.edge

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>adonis-quotes-app</title>
          {{ style('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css') }}
          {{ style('style') }}
          {{ script('https://code.jquery.com/jquery-3.3.1.slim.min.js') }}
      </head>
      <body>
          <div class="container-fliud">
              @include('navbar')
              @!section('content')
          </div>
          {{ script('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js') }}
      
      </body>
      </html>
      

      In dieser Datei schließen Sie die CDN-Dateien für Bootstrap CSS, Bootstrap JavaScript und jQuery ein. Sie fügen einen globalen CSS-Dateinamen style.css hinzu und schließen innerhalb der div eine Partiale-Datei namens navbar ein. Um Fragmente des HTML-Codes, die Sie auf mehreren Seiten Ihrer Anwendung benötigen, wie nav oder footer, wiederzuverwenden, können Sie Partiale einfügen. Dabei handelt es sich um kleinere Dateien, die den sich wiederholenden Code enthalten, sodass der Code für diese Elemente schneller an einer Stelle und nicht bei jedem Auftreten aktualisiert werden kann. Die navbar enthält Markierungen für die Schaltflächen Login und Register, ein Logo und einen Home-Link.

      Auf diese Weise können alle nachfolgenden für diese Anwendung erstellten Seiten das Master-Layout erweitern und die navbar rendern, ohne dass der Inhalt neu geschrieben werden muss. Sie erstellen diese Datei navbar später im Tutorial.

      Abschließend definieren Sie einen Abschnitt-Tag @! section(), um Inhalte anderer Seiten einzuschließen und sie vom Master-Layout rendern zu lassen. Damit dies wie erwartet funktioniert, müssen alle neuen Seiten, die das Master-Layout erweitern, auch einen Abschnitt-Tag mit demselben Namen (d. h. @section('content')) definieren.

      Speichern und schließen Sie die Datei, sobald Sie mit der Bearbeitung fertig sind.

      Als Nächstes verwenden Sie den Befehl adonis, um die Navigationsleiste zu erstellen:

      Sie sehen einen Output, der so ähnlich wie der nachfolgende aussieht:

      Output

      ✔ create resources/views/navbar.edge

      Öffnen Sie die neu erstellte Datei:

      • nano resources/views/navbar.edge

      Fügen Sie dann den folgenden Code hinzu:

      /resources/views/navbar.edge

      <nav class="navbar navbar-expand-lg navbar-dark text-white">
          <a class="navbar-brand" >LOGO</a>
          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
              <span class="navbar-toggler-icon"></span>
          </button>
      
          <div class="collapse navbar-collapse" id="navbarNav">
              <ul class="navbar-nav">
                  <li class="nav-item active ">
                      <a class="btn text-white" href="https://www.digitalocean.com/">Home</a>
                  </li>
              </ul>
          </div>
          <div class="navbar-right" id="navbarNav">
              @loggedIn
                  <ul class="navbar-nav">
                          <li>
                              <div class="text-right">
                                   <a href="{{route('create.quote')}}" class="btn btn-outline-primary">Create Quote</a>
                              </div>
                          </li>
      
                      <li class="nav-item dropdown">
                          <a class="nav-link dropdown-toggle" href="https://www.digitalocean.com/#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                             {{ auth.user.username}}
                          </a>
                          <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                              <form method="POST" action="{{route('logout')}}">
                                  {{ csrfField() }}
                                    <button  type="submit" class="dropdown-item" href="">logout</button>
                              </form>
                          </div>
                      </li>
                  </ul>
              @else
                  <ul class="navbar-nav">
                      <li class="nav-item active pr-2">
                          <a href="{{route('login.create')}}" class="btn btn-outline-danger">
                            login
                          </a>
                      </li>
                      <li class="nav-item active pr-2">
                          <a href="{{route('register.create')}}" class="btn btn-outline-primary">
                              Register
                          </a>
                      </li>
                  </ul>
              @endloggedIn
          </div>
      </nav>
      

      Zusätzlich zur Definition der Links zu der Homepage und einer Schaltfläche zum Registrieren und Anmelden fügen Sie ein Tag @loggedIn hinzu. Damit können Sie eine bedingte Anweisung um den authentifizierten Benutzer herum schreiben und bei Bedarf entsprechende Inhalte anzeigen. Für einen authentifizierten Benutzer zeigt die Anwendung den Benutzernamen und eine Schaltfläche zum Erstellen eines neuen Zitats an. Wenn ein Benutzer nicht angemeldet ist, zeigt Ihre Anwendung eine Schaltfläche für die Anmeldung oder die Registrierung an. Diese Seite wird als Partiale auf jeder Seite eingefügt, so wie es zuvor im Master-Layout für diese Anwendung enthalten war.

      Speichern und schließen Sie die Datei.

      Nun erstellen Sie die Indexseite, die Sie für die Homepage der Anwendung verwenden. Sie wird die Liste aller inspirierenden Zitate, die die Benutzer schreiben, rendern und anzeigen:

      Sie werden eine Ausgabe sehen, die der folgenden ähnelt:

      Output

      ✔ create resources/views/index.edge

      Die hier erstellte Datei wird sich in resources/views/index.edge befinden. Öffnen Sie die Datei:

      • nano resources/views/index.edge

      Fügen Sie dann den folgenden Code hinzu:

      /resources/views/index.edge

      @layout('layouts/master')
      @section('content')
      
      <div class="container">
          <div class="text-center">
              @if(flashMessage('successmessage'))
                  <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
              @endif
          </div>
          <div class="row">
              @each(quote in quotes)
                  <div class="col-md-4 mb-4 quote-wrapper">
                      <a href="https://www.digitalocean.com/view-quote/{{quote.id}}" class="w-100">
                          <div class="card shadow-lg bg-dark text-white">
                              <div class="card-body">
                                  <blockquote class="blockquote mb-0">
                                      <p>{{quote.body}}</p>
                                      <footer class="blockquote-footer">
                                          <cite title="Source Title"> {{quote.username}}</cite>
                                      </footer>
                                  </blockquote>
                                  @if(auth.user.id == quote.user_id)
                                    <div>
                                      <a  href="http://www.digitalocean.com/edit-quote/{{quote.id}}" class="btn btn-primary">edit</a>
                                      <a href="http://www.digitalocean.com/delete-quote/{{quote.id}}" class="btn btn-danger">delete</a>
                                    </div>
                                  @endif
                              </div>
                          </div>
                      </a>
                  </div>
              @else
               <div class="col-md-12 empty-quote text-center">
                      <p>No inspirational quote has been created</p>
               </div>
              @endeach
          </div>
      </div>
      @endsection
      

      Hier geben Sie an, dass diese Ansicht das Layout master durch Erweiterung verwenden wird. Diese Seite hat nun Zugriff auf alle Bibliotheken, Stylesheets und die navbar, die im Layout master enthalten sind. Als Nächstes iterieren Sie über ein Array von quotes (Zitaten) unter Verwendung des integrierten Tags @each. Das Array quotes wird von dem QuoteController, den Sie später in diesem Tutorial erstellen werden, an diese Ansicht übergeben. Wenn keine Zitate vorhanden sind, wird eine entsprechende Meldung angezeigt.

      Speichern und schließen Sie diese Datei.

      Um die Anmeldeseite zu erstellen, führen Sie nun den folgenden Befehl aus:

      • adonis make:view auth/login

      Sie werden eine Ausgabe sehen, die der folgenden ähnelt:

      Output

      ✔ create resources/views/auth/login.edge

      Dadurch wird automatisch ein Ordner auth innerhalb von resources/views erstellt und darin ebenfalls eine Datei login.edge angelegt. Öffnen Sie die Datei login.edge:

      • nano resources/views/auth/login.edge

      Fügen Sie den folgenden Inhalt hinzu:

      /resources/views/auth/login.edge

      @layout('layouts/master')
      @section('content')
        <div class="container">
          <div class="row">
            <div class="col-md-4 shadow bg-white mt-5 rounded offset-md-4">
              <form method="POST" action="{{route('login.store')}}">
                {{ csrfField() }}
                  <div>
                    @if(flashMessage('successmessage'))
                      <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
                    @endif
                  </div>
                  <div class="form-group">
                    <label for="email">Email address</label>
                    <input type="email" class="form-control" id="email" name="email" value="{{old('email','')}}"  placeholder="Enter email">
                    {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
                  </div>
                  <div class="form-group">
                    <label for="pasword">Password</label>
                    <input type="password" class="form-control" id="password" name="password" value="{{old('password','')}}" placeholder="Password">
                    {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
                  </div>
      
                  <div class="text-center">
                    <button type="submit" class="btn btn-primary">Submit</button>
                  </div>
              </form>
            </div>
          </div>
        </div>
      @endsection
      

      Diese Datei enthält ein Formular, das Eingabeelemente enthält,mit denen Sie den Benutzernamen und das Passwort eines registrierten Benutzers erfassen, bevor dieser sich erfolgreich authentifizieren und mit der Erstellung von Zitaten beginnen kann. Ein weiteres wichtiges Element, das Sie auf dieser Seite beachten sollten, ist das {{ csrfField() }}​​​. Es handelt sich dabei um eine globale Variable, die AdonisJs verwendet, um das CSRF-Zugriffstoken zu übergeben, wenn eine POST-, PUT– und DELETE-Anfrage aus Ihrer Anwendung gesendet wird.

      Dies wurde eingerichtet, um Ihre Anwendung vor Cross-Site Request Forgery (CSRF)-Angriffen zu schützen. Es funktioniert, indem es für jeden Benutzer, der Ihre Website besucht, ein eindeutiges CSRF-Geheimnis erzeugt. Sobald Ihre Benutzer eine HTTP-Anfrage vom Frontend aus senden, wird ein entsprechendes Token für dieses Geheimnis generiert und mit der Anfrage weitergegeben. Auf diese Weise kann die für diese Anfrage innerhalb von AdonisJs erstellte Middleware überprüfen, ob sowohl das Token als auch das CSRF-Geheimnis gültig sind und dem aktuell authentifizierten Benutzer gehören.

      Speichern und schließen Sie die Datei, sobald Sie fertig sind.

      Als Nächstes erstellen Sie die Registrierungsseite mit diesem Befehl:

      • adonis make:view auth/register

      Sie werden eine ähnliche Ausgabe wie diese sehen:

      Output

      ✔ create resources/views/auth/register.edge

      Suchen und öffnen Sie die neu erstellte Datei in resources/views/auth/register.edge:

      • nano resources/views/auth/register.edge

      Fügen Sie folgenden Code hinzu:

      resources/views/auth/register.edge

      @layout('layouts/master')
      @section('content')
        <div class="container ">
          <div class="row">
              <div class="col-md-4  bg-white p-3 mt-5 shadow no-border rounded offset-md-4">
                <form method="POST" action="{{route('register.store')}}">
                  {{ csrfField() }}
                    <div class="form-group">
                      <label for="name">Fullname</label>
                      <input type="text" class="form-control" id="name" name="name"  value="{{old('name','')}}" placeholder="Enter Fullname">
                      {{ elIf('<span class=text-danger>$self</span>', getErrorFor('name'), hasErrorFor('name')) }}
                    </div>
                    <div class="form-group">
                      <label for="email">Email address</label>
                      <input type="email" class="form-control" id="email"  name="email" value="{{old('email','')}}" placeholder="Enter email">
                      {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
                    </div>
                    <div class="form-group">
                      <label for="pasword">Password</label>
                      <input type="password" class="form-control" id="password" name="password" placeholder="Password">
                      {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
                    </div>
                    <div class="text-center">
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </div>
                </form>
              </div>
          </div>
        </div>
      @endsection
      

      Ähnlich wie die Anmeldeseite enthält diese Datei ein HTML-Formular mit Eingabefeldern zur Erfassung von Name, E-Mail und Passwort eines Benutzers während des Registrierungsvorgangs. Ebenfalls enthalten ist das {{ csrfField() }}, da es für jede Post-Anfrage für eine AdonisJs-Anwendung erforderlich ist.

      Speichern und schließen Sie die Datei.

      Nun erstellen Sie eine neue Datei, um ein inspirierendes Zitat zu erstellen, indem Sie den folgenden Befehl vom Terminal aus ausführen:

      • adonis make:view quotes/create-quote

      Sie sehen eine Ausgabe wie:

      Output

      ✔ create resources/views/quotes/create-quote.edge

      Öffnen Sie resources/views/quotes/create-quote.edge:

      • nano resources/views/quotes/create-quote.edge

      Und fügen Sie den folgenden Inhalt hinzu:

      /resources/views/quotes/create-quote.edge

      @layout('layouts/master')
      @section('content')
      <div class="container">
          <div class="row">
              <div class="col-md-3"></div>
              <div class="col-md-6 shadow bg-white mt-5 rounded p-3">
                  <div class="float-right">
                      <a href="https://www.digitalocean.com/" class="btn btn-outline-dark ">back</a>
                  </div>
                      <br>
      
                  <div class="clear-fix"></div>
                      <form method="POST" action="{{route('store.quote')}}">
                          {{ csrfField() }}
                          <div class="form-group">
                              <label for="quote">Create Quote</label>
                              <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="Write an inspirational quote"></textarea>
                          </div>
      
                          <div class="text-center">
                              <button type="submit" class="btn btn-primary">Submit</button>
                          </div>
                      </form>
                  </div>
              </div>
              <div class="col-md-3"></div>
          </div>
      </div>
      @endsection
      

      Diese Seite erweitert das Master-Layout und enthält ein HTML-Formular mit einem Textbereichselement, das es dem Benutzer ermöglicht, Text über mehrere Zeilen einzugeben, bevor er über die entsprechende Route veröffentlicht und gehandhabt wird.

      Speichern und schließen Sie die Datei, sobald Sie fertig sind.

      Erstellen Sie als Nächstes eine Seite zur Bearbeitung eines bestimmten Zitats. Führen Sie den folgenden Befehl vom Terminal aus:

      • adonis make:view quotes/edit-quote

      Sie sehen den folgenden Output:

      Output

      ✔ create resources/views/quotes/edit-quote.edge

      Öffnen Sie die Datei mit:

      • nano resources/views/quotes/edit-quote.edge

      Fügen Sie den folgenden Inhalt zu resources/views/quotes/edit-quote hinzu:

      /resources/views/quotes/edit-quote.edge

      @layout('layouts/master')
      @section('content')
      <div class="container">
          <div class="row">
              <div class="col-md-6 shadow bg-white rounded p-3 offset-md-3">
                  <div class="float-right">
                      <a href="https://www.digitalocean.com/" class="btn btn-outline-dark ">back</a>
                  </div>
                  <br>
      
                  <div class="clear-fix"></div>
                  <form method="POST" action="/update-quote/{{quote.id}}">
                      {{ csrfField() }}
                      <div class="form-group">
                          <label for="pasword">Edit Quote</label>
                          <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="write the inspirational quote">{{quote.body}}</textarea>
                      </div>
                      <div class="text-center">
                          <button type="submit" class="btn btn-primary">Update</button>
                      </div>
      
                  </form>
              </div>
          </div>
      </div>
      @endsection
      

      Diese Seite enthält ähnliche Inhalte wie die Datei create-quote.edge – der Unterschied besteht darin, dass sie die Details eines bestimmten Zitats enthält, die zu bearbeiten sind, <form method="POST" action="/update-quote/{{quote.id}}">.

      Speichern und schließen Sie die Datei.

      Erstellen Sie abschließend eine Seite, um ein einzelnes inspirierendes Zitat anzuzeigen:

      • adonis make:view quotes/quote

      Sie sehen eine Ausgabe, die dieser ähnelt:

      Output

      ✔ create resources/views/quotes/quote.edge

      Öffnen Sie die Datei mit:

      • nano resources/views/quotes/quote.edge

      Fügen Sie folgenden Code hinzu:

      /resources/views/quotes/quote.edge

      @layout('layouts/master')
      @section('content')
      <div class="container">
          <div class="row">
              <div class="col-md-6 offset-md-3">
                  <div class="card shadow-lg bg-dark text-white">
                      <div class="card-body">
                          <div class="float-right">
                              <a href="https://www.digitalocean.com/" class="btn btn-outline-primary ">back</a>
                          </div>
                              <br>
                          <div class="clear-fix"></div>
                          <blockquote class="blockquote mb-0">
                              <p>{{quote.body}}</p>
                              <footer class="blockquote-footer">
                                  <cite title="Source Title">{{quote.username}}</cite>
                              </footer>
                          </blockquote>
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      

      Diese Seite gibt die Details eines bestimmten Zitats wieder, einschließlich des Zitatkörpers quote.body, und des Autors, der es erstellt hat, quote.username.

      Wenn Sie mit der Datei fertig sind, speichern und schließen Sie sie.

      Sie haben alle erforderlichen Seiten für Ihre Anwendung mit Hilfe der Edge Templating Engine erstellt. Als Nächstes konfigurieren und stellen Sie eine Verbindung mit der Datenbank Ihrer Anwendung her.

      Schritt 3 – Erstellen eines Datenbankschemas

      Wenn Sie Ihre Anwendung jetzt bereitstellen, wird ein Fehler ausgegeben, da Sie die Anwendung noch mit einer Datenbank verbinden müssen. In diesem Abschnitt richten Sie eine Verbindung mit der Datenbank ein und verwenden dann den Befehl adonis zur Erzeugung einer Migrationsdatei, die zur Erstellung der Tabellen für die Datenbank verwendet wird.

      AdonisJs enthält ein ORM namens Lucid ORM, das eine aktive Datensatz-Implementierung für die Arbeit mit Ihrer Datenbank bereitstellt. Damit entfällt das mühsame Schreiben von SQL-Abfragen, die Daten in Echtzeit aus der Datenbank abrufen. Dies ist besonders hilfreich bei der Arbeit an einer komplexen Anwendung, die viele Abfragen erfordert. So können Sie beispielsweise alle Zitate aus Ihrer Anwendung abrufen, indem Sie eingeben:

      const quotes = await Quote.all()
      

      Um mit der entsprechenden Konfiguration für Ihre Anwendungsdatenbank fortzufahren, stellen Sie sicher, dass Sie sich immer noch im Stammverzeichnis Ihrer Anwendung befinden und erstellen Sie eine .env-Datei:

      Öffnen Sie die neu erstellte Datei und fügen Sie den folgenden Inhalt hinzu:

      .env

      HOST=127.0.0.1
      PORT=3333
      NODE_ENV=development
      APP_URL=http://${HOST}:${PORT}
      CACHE_VIEWS=false
      APP_KEY=bTVOEgUvmTCfkvgrK8gEBC3Qxt1xSYr0
      DB_CONNECTION=mysql
      DB_HOST=127.0.0.1
      DB_PORT=3306
      DB_USER=sammy
      DB_PASSWORD=password
      DB_DATABASE=adonis
      SESSION_DRIVER=cookie
      HASH_DRIVER=bcrypt
      

      Standardmäßig ist die Datenbankverbindung für eine AdonisJs-Anwendung SQLite, die Sie hier auf MySQL aktualisieren werden. Des Weiteren geben Sie den PORT für die Anwendung, die Anwendungsumgebung und Berechtigungsnachweise für die Datenbank an. Stellen Sie sicher, dass Sie die Platzhalter DB_USER, DB_PASSWORD und DB_DATABASE mit Ihren Berechtigungsnachweisen ersetzen.

      Als Nächstes erstellen Sie das Modell und eine Migrationsdatei für Quote unter Verwendung der Adonis CLI. Führen Sie dazu den folgenden Befehl aus:

      • adonis make:model Quote --migration

      Sie sehen eine Ausgabe, die der folgenden ähnelt:

      Output

      ✔ create app/Models/Quote.js ✔ create database/migrations/1568209992854_quote_schema.js

      Dieser Befehl erstellt ein Modell für Quote im Ordner app/Models und eine Schemadatei in dem Ordner database/migrations. Der neu erstellten Schemadatei wird der aktuelle Zeitstempel vorangestellt. Öffnen Sie die Schemadatei mit:

      • nano database/migrations/1568209992854_quote_schema.js

      Aktualisieren Sie den Inhalt mit dem folgenden Code:

      database/migrations/…quote_schema.js

      'use strict'
      /** @type {import('@adonisjs/lucid/src/Schema')} */
      const Schema = use('Schema')
      class QuoteSchema extends Schema {
        up () {
          this.create('quotes', (table) => {
            table.increments()
            table.integer('user_id').notNullable()
            table.string('username', 80).notNullable()
            table.string('body').notNullable()
            table.timestamps()
          })
        }
        down () {
          this.drop('quotes')
        }
      }
      module.exports = QuoteSchema
      

      Eine Schemadatei in AdonisJs erfordert zwei verschiedene Methoden:

      • up: Wird verwendet, um eine neue Tabelle zu erstellen oder eine bestehende Tabelle zu ändern.
      • down: Wird verwendet, um die bei der Methode up vorgenommene Änderung rückgängig zu machen.

      Zusätzlich zu den Feldern timestamps() und increments() aktualisieren Sie den Inhalt der Schemadatei mit den Feldattributen user_id, username und dem body eines zu erstellenden Zitats. Die Felder user_id und username verweisen auf die Details des Benutzers, der ein bestimmtes Zitat erstellt. Dies definiert eine 1:n-Beziehung und bedeutet, dass ein Benutzer eine unendliche Anzahl von Zitaten besitzen kann, während ein einzelnes Zitat nur einem Benutzer gehören kann.

      Speichern und schließen Sie die Datei.

      AdonisJs wird standardmäßig mit Modell User und der zugehörigen Migrationsdatei installiert. Dies erfordert nur eine kleine Änderung, um die Beziehung zwischen dem Modell User und Quote herzustellen.

      Öffnen Sie das Modell User in app/Models/User.js:

      Fügen Sie diese Methode unmittelbar nach der Methode tokens() hinzu:

      app/Models/User.js

      ...
      class User extends Model {
        ...
        tokens () {
          return this.hasMany('App/Models/Token')
        }
      
        quote () {
          return this.hasMany('App/Models/Quote')
        }
      }
      
      module.exports = User
      

      Dadurch wird eine 1:n-Beziehung mit der Tabelle Quote unter Verwendung von user_id als Fremdschlüssel festgelegt.

      Speichern und schließen Sie die Datei.

      Um diesen Abschnitt abzuschließen, verwenden Sie den folgenden Befehl zur Ausführung von Migrationen, wodurch die Methode up() aller Migrationsdateien ausgeführt wird:

      Sie werden eine Ausgabe sehen, die der folgenden ähnelt:

      Output

      migrate: 1503248427885_user.js migrate: 1503248427886_token.js migrate: 1568209992854_quote_schema.js Database migrated successfully in 3.42 s

      Sie haben eine Verbindung mit Ihrer Datenbank konfiguriert und gesichert. Des Weiteren haben Sie ein Modell Quote und die dazugehörige Schemadatei erstellt und eine 1:n-Beziehung zwischen User und Quote hergestellt. Als Nächstes generieren Sie die Routen und Controller zur Bearbeitung von HTTP-Anfragen und die Geschäftslogik zum Erstellen, Bearbeiten und Löschen eines inspirierenden Zitats.

      Schritt 4 – Erstellen von Controllern und Einrichten von Routen

      In diesem Abschnitt beginnen Sie mit der Erstellung von Controllern, die die gesamte Logik für die Anwendung verarbeiten und diese später an eine bestimmte Route anhängen, damit die Benutzer über eine URL darauf zugreifen können.

      Zu Beginn werden Sie mit der Adonis CLI einen neuen HTTP-Request-Controller erstellen, der alle Authentifizierungsprozesse für Ihre Anwendung verarbeiten kann, indem Sie den folgenden Befehl ausführen:

      • adonis make:controller Auth --type http

      Dieser Befehl erstellt eine Datei AuthController.js und speichert sie innerhalb des Ordners app/Controllers/Http. Sie verwenden das Flag --type, um anzugeben, dass dieser Controller ein HTTP-Controller sein soll.

      Sie werden eine Ausgabe sehen, die der folgenden ähnelt:

      Output

      ✔ create app/Controllers/Http/AuthController.js

      Öffnen Sie als Nächstes die neu erstellte Controller-Datei:

      • nano app/Controllers/Http/AuthController.js

      Aktualisieren Sie sie mit dem folgenden Inhalt:

      app/Controllers/Http/AuthController.js

      'use strict'
      const User = use('App/Models/User')
      class AuthController {
      
          loginView({ view }) {
              return view.render('auth.login')
          }
          registrationView({ view }) {
              return view.render('auth.register')
          }
      
          async postLogin({ request, auth, response}) {
              await auth.attempt(request.input('email'), request.input('password'))
              return response.route('index')
          }
      
          async postRegister({ request, session, response }) {
              const user = await User.create({
                  username: request.input('name'),
                  email: request.input('email'),
                  password: request.input('password')
              })
              session.flash({ successmessage: 'User have been created successfully'})
              return response.route('login.create');
          }
      
          async logout ({ auth, response }) {
              await auth.logout()
              return response.route("https://www.digitalocean.com/")
          }
      }
      module.exports = AuthController
      

      In dieser Datei importieren Sie das Modell User und erstellen dann zwei Methoden namens loginView() und registerView(), um die Anmelde- bzw. Registrierungsseite zu rendern. Abschließend erstellen Sie die folgenden asynchronen Methoden:

      • postLogin(): Mit dieser Methode erhalten Sie den Wert von email und password, die mit Hilfe der in AdonisJs eingebauten Methode request gepostet wurden, und validieren dann diesen Benutzer anhand der Details in der Datenbank. Wenn ein solcher Benutzer in der Datenbank existiert und den korrekten Berechtigungsnachweis eingegeben hat, wird er zurück auf die Homepage umgeleitet und authentifiziert, bevor er ein neues Zitat erstellen kann. Andernfalls wird eine Meldung angezeigt, die auf den falschen Berechtigungsnachweis hinweist.
      • postRegister(): Dies erhält den Wert von username, email und password für einen Benutzer, um ein Konto für diesen Benutzer in der Datenbank zu erstellen. Eine Nachricht mit der Angabe, dass dieser Benutzer erfolgreich erstellt wurde, wird an die Sitzung weitergeleitet, und der Benutzer wird auf die Anmeldeseite umgeleitet, um authentifiziert zu werden und mit der Erstellung eines Zitats zu beginnen.
      • logout(): Diese Methode verarbeitet die Logout-Funktionalität und leitet den Benutzer zurück auf die Homepage.

      Speichern und schließen Sie die Datei.

      Nachdem Sie nun den Controller für die Registrierung und Authentifizierung von Benutzern eingerichtet haben, fahren Sie mit der Erstellung eines HTTP-Request-Controllers für die Verwaltung aller Operationen in Bezug auf Zitate fort.

      Führen Sie, zurück im Terminal, den folgenden Befehl aus, um den QuoteController zu erstellen:

      • adonis make:controller Quote --type http --resource

      Die Verwendung des Flags --resource erstellt einen Controller mit vordefinierten kreativen Methoden zur Durchführung von CRUD (Create, Read, Update und Delete)-Operationen.

      Sie sehen:

      Output

      ✔ create app/Controllers/Http/QuoteController.js

      Finden Sie diese Datei innerhalb von app/Controllers/Http/QuoteControllers.js:

      • nano app/Controllers/Http/QuoteController.js

      Aktualisieren Sie sie mit dem folgenden Inhalt:

      app/Controllers/Http/QuoteController.js

      'use strict'
      const Quote = use('App/Models/Quote')
      
      class QuoteController {
      
        async index ({ view }) {
          const quote = await Quote.all()
          return view.render('index', {
            quotes: quote.toJSON()
          })
        }
      
        async create ({ view }) {
          return view.render('quotes.create-quote')
        }
      
        async store ({ request,auth,session, response }) {
          const quote = await Quote.create({
            user_id: auth.user.id,
            username: auth.user.username,
            body: request.input('body')
          })
          session.flash({ 'successmessage': 'Quote has been created'})
          return response.redirect("https://www.digitalocean.com/")
        }
      
        async show ({ params, view }) {
          const quote = await Quote.find(params.id)
          return view.render('quotes.view-quote', {
            quote: quote.toJSON()
          })
        }
      
        async edit ({ params, view }) {
          const quote = await Quote.find(params.id)
          return view.render('quotes.edit-quote', {
            quote: quote.toJSON()
          })
        }
      
        async update ({ params, request, response, session }) {
          const quote = await Quote.find(params.id)
          quote.body = request.input('body')
          await quote.save()
          session.flash({'successmessage': 'Quote has been updated'})
          return response.redirect("https://www.digitalocean.com/")
        }
      
        async destroy ({ params, response, session }) {
          const quote = await Quote.find(params.id)
          await quote.delete()
          session.flash({'successmessage': 'Quote has been deleted'})
          return response.redirect("https://www.digitalocean.com/")
        }
      }
      module.exports = QuoteController
      

      In diesem Controller haben Sie das Modell Quote importiert und die folgenden Methoden aktualisiert, die automatisch mit AdonisJs CLI erstellt wurden:

      • index(): Um alle Zitate aus der Datenbank zu holen und sie auf der Homepage der Anwendung darzustellen.
      • create(): Um eine Seite zum Erstellen von Zitaten darzustellen.
      • store(): Um ein neu erstelltes Zitat dauerhaft in der Datenbank zu speichern und eine entsprechende Antwort zurückzugeben.
      • show(): Um die id eines bestimmten Zitats zu erhalten, es aus der Datenbank abzurufen und auf der Seite zur Bearbeitung von Zitaten anzuzeigen.
      • edit(): Um Details eines bestimmten Zitats aus der Datenbank abzurufen und zur Bearbeitung darzustellen.
      • update(): Um jede Aktualisierung eines Zitats zu verarbeiten und den Benutzer zurück auf die Homepage zu leiten.
      • destroy(): Um ein bestimmtes Zitat zu löschen und vollständig aus der Datenbank zu entfernen.

      Speichern und schließen Sie die Datei.

      Nachdem Sie alle erforderlichen Controller für diese Anwendung erstellt haben, können Sie nun die Routen so einrichten, dass die Benutzer problemlos mit Ihrer Anwendung interagieren können. Navigieren Sie zu Beginn zu der Datei start/routes.js:

      Ersetzen Sie den Inhalt mit dem folgenden:

      start/routes.js

      'use strict'
      const Route = use('Route')
      
      Route.get("https://www.digitalocean.com/",'QuoteController.index').as('index')
      Route.get('/register','AuthController.registrationView').as('register.create')
      Route.post('/register-store','AuthController.postRegister').as('register.store').validator('Register')
      Route.get('/login','AuthController.loginView').as('login.create')
      Route.post('/login-store','AuthController.postLogin').as('login.store')
      Route.get('/view-quote/:id','QuoteController.show').as('view.quote')
      
      Route.group(() => {
          Route.get('/create-quote','QuoteController.create').as('create.quote')
          Route.post('/store-quote','QuoteController.store').as('store.quote')
          Route.get('/edit-quote/:id','QuoteController.edit').as('edit.quote')
          Route.post('/update-quote/:id','QuoteController.update').as('update.quote')
          Route.get('/delete-quote/:id','QuoteController.destroy').as('delete.quote')
          Route.post('/logout','AuthController.logout').as('logout')
      }).middleware(['auth'])
      

      Hier definieren Sie den Pfad für jede Route in Ihrer Anwendung, geben die HTTP-Verben für jede Aktion an und binden die Route an eine bestimmte Methode in jedem Controller. Außerdem benennen Sie jede dieser Routen so, wie sie in den Controllern und Ansichten referenziert wurden.

      Um sicherzustellen, dass nur authentifizierte Benutzer auf alle Zitatrouten zugreifen können, ordnen Sie eine Gruppe namens Middleware zu. Schließlich hängen Sie eine Validierer-Methode an die Route register.store an, um die Benutzereingaben zu validieren.

      Speichern und schließen Sie die Datei.

      Sie haben Ihre Controller erstellt und die Routen für Ihre Anwendung eingerichtet. Als Nächstes erstellen Sie die in diesem Schritt definierte Validierer-Methode.

      Schritt 5 – Validieren der Benutzereingabe

      Standardmäßig verfügt AdonisJs nicht über integrierte Validierer. Daher müssen Sie den Validierer für Ihre Anwendung manuell installieren und registrieren.

      Führen Sie den folgenden Befehl aus, um ihn zu installieren:

      Öffnen Sie die folgende Datei, um den Anbieter des Validieres (Validator Provider) zu registrieren:

      Registrieren Sie dann den Anbieter des Validieres, indem Sie ihn an die Liste der Anbieter anhängen, wie nachfolgend gezeigt:

      start/app.js

      ...
      const providers = [
         ...
         '@adonisjs/cors/providers/CorsProvider',
         '@adonisjs/shield/providers/ShieldProvider',
         '@adonisjs/session/providers/SessionProvider',
         '@adonisjs/auth/providers/AuthProvider',
         '@adonisjs/validator/providers/ValidatorProvider'
      ]
      

      Nachdem Sie den Anbieter des Validieres innerhalb Ihrer Anwendung installiert und registriert haben, erstellen Sie nun mit dem folgenden Befehl einen benutzerdefinierten Validierer, um die Eingabe des Benutzers während der Registrierung zu validieren:

      • adonis make:validator Register

      Dadurch wird eine Datei Register.js im Verzeichnis App/Validators erstellt. Öffnen Sie die Datei mit:

      • nano app/Validators/Register.js

      Fügen Sie den folgenden Code zur Datei hinzu:

      app/Validators/Register.js

      'use strict'
      class Register {
        get rules () {
          return {
            name:'required',
            email:'required|email|unique:users',
            password:'required|min:8'
          }
        }
      
        get messages(){
          return{
            'name.required':'Full name is required',
            'email.required':'email is required',
            'email.unique':'email already exists',
            'password.required':'password is required',
            'password.min':'password should be at least 8 characters'
          }
        }
      }
      module.exports = Register
      

      In Ihrer Anwendung definieren Sie Regeln für bestimmte Felder. Wenn Validierungen zu einem beliebigen Zeitpunkt fehlschlagen, setzt der Validierer den Fehler automatisch als Flash-Meldung und der Benutzer wird zurück zum Formular geleitet.

      Speichern und schließen Sie die Datei, sobald Sie die Bearbeitung abgeschlossen haben.

      Um Ihrer Anwendung ein Design hinzuzufügen, öffnen Sie schließlich die folgende Datei:

      Ersetzen Sie die Inhalte mit dem folgenden:

      /public/style.css

      @import url('https://fonts.googleapis.com/css?family=Montserrat:300');
      
      html, body {
        height: 100%;
        width: 100%;
      }
      
      body {
        font-family: 'Montserrat', sans-serif;
        font-weight: 300;
        background-image: url("/splash.png");
        background-color: #220052;
      }
      
      * {
        margin: 0;
        padding: 0;
      }
      
      a {
        color: inherit;
        text-decoration: underline;
      }
      
      p {
        margin: 0.83rem 0;
      }
      
      .quote-wrapper {
        margin-top: 20px;
      }
      
      .quote-wrapper a {
        text-decoration: none;
      }
      
      .quote-wrapper a:hover {
        color: #ffffff;
      }
      
      .empty-quote {
        color: #ffffff;
      }
      
      form {
        padding: 20px;
      }
      

      In dieser Datei aktualisieren Sie das CSS-Design Ihrer Anwendung in der Datei style.css.

      Sie haben einen Anbieter eines Validieres installiert und registriert, um die Eingabe von Benutzern während des Registrierungsvorgangs zu überprüfen. Des Weiteren haben Sie den Inhalt Ihres Stylesheets aktualisiert, um der Anwendung mehr Design hinzuzufügen. Im letzten Schritt testen Sie Ihre Anwendung.

      Schritt 6 – Bereitstellen der Anwendung

      In diesem Schritt stellen Sie Ihre Anwendung bereit und erstellen einen Benutzer und ein Passwort zum Testen der Authentifizierung. Außerdem fügen Sie Ihrer Anwendung ein Zitate hinzu und zeigen es auf der Homepage an.

      Um Ihre Anwendung zu testen, starten Sie den Entwicklungsserver mit dem folgenden Befehl aus dem Stammverzeichnis Ihrer Anwendung:

      Dadurch wird die Anwendung auf dem innerhalb der Stammdatei .env definierten Port, 3333, gestartet. Navigieren Sie in Ihrem Browser zu http://localhost:3333.

      Homepage der Zitat-Anwendung

      Die Homepage ist zur Zeit leer, da Sie keine Zitate erstellt haben. Klicken Sie auf die Schaltfläche Register.

      Anmeldeseite

      Geben Sie Ihre Informationen ein und klicken Sie auf die Schaltfläche Submit, um den Registrierungsvorgang abzuschließen. Sie werden auf die Anmeldeseite umgeleitet. Geben Sie Ihre E-Mail-Adresse und Ihr Passwort für die Authentifizierung ein.

      Anmeldeseite

      Nachdem Sie authentifiziert sind, klicken Sie auf die Schaltfläche Create Quote.

      Seite „Zitat erstellen“

      Geben Sie ein Zitat ein und navigieren Sie zu der Seite View all, um Ihr Zitat anzuzeigen.

      Seite „Alle Zitate anzeigen“

      Sie haben Ihre Anwendung getestet, indem Sie einen Benutzer erstellt und authentifiziert und anschließend ein Zitat verfasst haben.

      Zusammenfassung

      In diesem Tutorial haben Sie eine Webanwendung mit AdonisJs erstellt. Sie haben die Anwendung unter Verwendung der AdonisJs CLI eingerichtet und die CLI zum Erstellen anderer relevanter Dateien wie Controller, Modelle und Ansichten verwendet.

      Sie können Webanwendungen mit diesem Framework unabhängig von Ihrer Größe und Komplexität erstellen. Sie können den Quellcode für dieses Projekt hier auf GitHub herunterladen. Um weitere Funktionen zu erkunden, können Sie auch die offizielle Dokumentation besuchen.

      Wenn Sie einige unserer anderen JavaScript-Framework-Tutorials erkunden möchten, sehen Sie sich Folgendes an:



      Source link

      Erstellen eines Hashicorp Vault Server unter Verwendung von Packer und Terraform auf DigitalOcean


      Der Autor wählte den Free and Open Source Fund, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Vault von Hashicorp ist ein Open Source Tool, um Zugangsdaten und sensible Daten in dynamischen Cloud-Umgebungen sicher zu speichern. Es bietet eine starke Datenverschlüsselung, identitätsbasierten Zugriff unter Verwendung von benutzerdefinierten Richtlinien, geheimes Leasen und Widerrufen sowie ein ausführliches Auditprotokoll, das fortlaufend aufgezeichnet wird. Vault bietet zudem eine HTTP-API und ist damit die ideale Wahl für die Speicherung von Anmeldeinformationen in verstreuten serviceorientierten Implementierungen wie Kubernetes.

      Packer und Terraform, ebenfalls von Hashicorp entwickelt, können zusammen verwendet werden, um Bilder von Vault zu kreieren und bereitzustellen. Innerhalb dieses Workflows können Entwickler Packer verwenden, um unveränderliche Bilder für verschiedene Plattformen aus einer einzelnen Konfigurationsdatei zu erstellen, die angibt, was das Bild enthalten soll. Terraform stellt dann so viele angepasste Exemplare der erstellten Bilder bereit, wie benötigt werden.

      In diesem Tutorial erstellen Sie mit Packer einen unveränderlichen Snapshot des Systems mit installiertem Vault und orchestrieren dessen Bereitstellung mit Terraform. Zum Schluss verfügen Sie über ein automatisiertes System zur Bereitstellung von Vault. So können Sie sich anstatt auf den zugrunde liegenden Installations- und Bereitstellungsprozess auf die Arbeit mit Vault selbst konzentrieren.

      Voraussetzungen

      • Auf Ihrem lokalen Rechner installierter Packer. Lesen Sie für Anweisungen die Offizielle Dokumentation.
      • Auf Ihrem lokalen Rechner installiertes Terraform. Lesen Sie die Offizielle Dokumentation für eine Anleitung.
      • Einen persönlichen Zugangs-Token (API-Schlüssel) mit Lese- und Schreibberechtigungen für Ihr DigitalOcean-Konto. Um einen solchen zu erstellen, besuchen Sie Erstellen eines persönlichen Zugangs-Tokens bei den Dokumenten.
      • Einen SSH-Schlüssel, den Sie zur Authentifizierung mit den bereitgestellten Vault Droplets verwenden, die auf Ihrem lokalen Rechner verfügbar sind und Ihrem DigitalOcean-Konto hinzugefügt werden. Sie benötigen auch dessen Fingerabdruck, den Sie von der Sicherheitsseite Ihres Kontos nach dem Erstellen kopieren können. Besuchen Sie die DigitalOcean Dokumentation für detaillierte Anweisungen oder das Tutorial Einrichten von SSH-Schlüsseln.

      Schritt 1 — Erstellen einer Packer-Vorlage

      In diesem Schritt schreiben Sie eine Packer-Konfigurationsdatei, die sogenannte Vorlage, die Packer anweist, wie ein Bild mit vorinstalliertem Vault erstellt werden kann. Sie schreiben die Konfiguration im Format JSON, einem gängigen, visuell lesbaren Dateiformat.

      Für die Zwecke dieses Tutorials speichern Sie alle Dateien unter ~/vault-orchestration. Erstellen Sie das Verzeichnis, indem Sie den folgenden Befehl ausführen:

      • mkdir ~/vault-orchestration

      Navigieren Sie dorthin:

      Sie speichern die Konfigurationsdateien für Packer und Terraform separat in verschiedenen Unterverzeichnissen. Erstellen Sie diese mit dem folgenden Befehl:

      Da Sie zuerst mit Packer arbeiten, navigieren Sie in dessen Verzeichnis:

      Verwenden von Vorlagenvariablen

      Die Speicherung von privaten Daten und Zugangsdaten für Applikationen in einer separaten Variablendatei ist der ideale Weg, diese aus Ihrer Vorlage herauszuhalten. Beim Erstellen des Bildes ersetzt Packer die angegebenen Variablen mit ihren Werten. Die Hartkodierung von geheimen Datenwerten in Ihre Vorlage ist ein Sicherheitsrisiko, insbesondere wenn sie mit Teammitgliedern geteilt oder auf öffentlichen Websites wie GitHub veröffentlicht werden soll.

      Sie speichern diese im Unterverzeichnis packer, in einer Datei namens variables.json​​​​​​. Erstellen Sie sie mit Ihrem bevorzugten Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/variables.json

      {
          "do_token": "your_do_api_key",
          "base_system_image": "ubuntu-18-04-x64",
          "region": "nyc3",
          "size": "s-1vcpu-1gb"
      }
      

      Die Variablendatei besteht aus einem JSON-Wörterbuch, das die Variablennamen ihren Werten zuordnet. Sie verwenden diese Variablen in der Vorlage, die Sie erstellen. Wenn Sie möchten, können Sie die Werte Basisbild, Region und Droplet-Größe entsprechend den Entwicklerdokumenten bearbeiten.

      Denken Sie daran, your_do_api_key durch Ihren API-Schlüssel zu ersetzen, den Sie als Teil der Voraussetzungen erstellt haben. Speichern und schließen Sie dann die Datei.

      Erstellen von Buildern und Provisionern

      Mit der fertigen Variablendatei erstellen Sie nun die Packer-Vorlage selbst.

      Sie speichern die Packer-Vorlage für Vault in einer Datei namens template.json. Erstellen Sie sie mit Ihrem Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/template.json

      {
           "builders": [{
               "type": "digitalocean",
               "api_token": "{{user `do_token`}}",
               "image": "{{user `base_system_image`}}",
               "region": "{{user `region`}}",
               "size": "{{user `size`}}",
               "ssh_username": "root"
           }],
           "provisioners": [{
               "type": "shell",
               "inline": [
                   "sleep 30",
                   "sudo apt-get update",
                   "sudo apt-get install unzip -y",
                   "curl -L https://releases.hashicorp.com/vault/1.3.2/vault_1.3.2_linux_amd64.zip -o vault.zip",
                   "unzip vault.zip",
                   "sudo chown root:root vault",
                   "mv vault /usr/local/bin/",
                   "rm -f vault.zip"
               ]
          }]
      }
      

      In der Vorlage definieren Sie Arrays von Buildern und Provisionern. Builder weisen Packer an, wie das Systembild (je nach Typ) zu erstellen ist und wo es gespeichert werden soll, während Provisioner eine Reihe von Aktionen enthalten, die Packer auf dem System durchführen muss, bevor es in ein unveränderliches Bild umgewandelt wird, wie z. B. die Installation oder Konfiguration von Software. Ohne Provisioner würden Sie zum Schluss ein unangetastetes Bild des Basissystems erhalten. Sowohl Builder als auch Provisioner stellen Parameter zur weiteren Anpassung des Workflows zur Verfügung.

      Sie definieren zuerst einen einzelnen Builder des Typs digitalocean, d. h. dass Packer beim Befehl zur Erstellung eines Bildes die bereitgestellten Parameter verwendet, um mit dem bereitgestellten API-Schlüssel ein temporäres Droplet der definierten Größe zu erstellen, mit dem angegebenen Basissystembild und der angegebenen Region. Das Format zum Abrufen einer Variablen ist {{user 'variable_name'}}, wobei der hervorgehobene Teil der Name ist.

      Wenn das provisorische Droplet bereitgestellt ist, stellt der Provisioner eine Verbindung über SSH mit dem angegebenen Benutzernamen her und führt nacheinander alle definierten Provisioner aus, bevor ein DigitalOcean Snapshot aus dem Droplet erstellt und es gelöscht wird.

      Es handelt sich um eine Shell, die die angegebenen Befehle auf dem Ziel ausführt. Die Befehle können entweder inline als Array von Zeichenfolgen angegeben oder in getrennten Skriptdateien definiert werden, wenn das Einfügen in die Vorlage aufgrund der Größe zu umständlich wird. Die Befehle in der Vorlage warten 30 Sekunden, bis das System hochgefahren ist. Anschließend wird Vault 1.3.2 heruntergeladen und entpackt. Konsultieren Sie die Offizielle Vault Downloadseite und ersetzen Sie den Link in den Befehlen durch eine neuere Version für Linux, wenn verfügbar.

      Wenn Sie fertig sind, speichern und schließen Sie die Datei.

      Um die Gültigkeit Ihrer Vorlage zu überprüfen, führen Sie den folgenden Befehl aus:

      • packer validate -var-file=variables.json template.json

      Packer akzeptiert einen Pfad zur Variablendatei über das Argument -var-file.

      Sie sehen die folgende Ausgabe:

      Output

      Template validated successfully.

      Sollten Sie eine Fehlermeldung erhalten, gibt Packer genau an, wo dieser aufgetreten ist, sodass Sie diesen korrigieren können.

      Nun haben Sie eine funktionierende Vorlage, die ein Bild mit installiertem Vault erzeugt, wobei Ihr API-Schlüssel und andere Parameter in einer separaten Datei definiert sind. Jetzt können Sie Packer aufrufen und den Snapshot erstellen.

      Schritt 2 — Erstellen des Snapshot

      In diesem Schritt erstellen Sie einen DigitalOcean Snapshot aus Ihrer Vorlage mit dem Packerbefehl build.

      Um Ihren Snapshot zu erstellen, führen Sie den folgenden Befehl aus:

      • packer build -var-file=variables.json template.json

      Die Ausführung des Befehls nimmt etwas Zeit in Anspruch. Sie sehen eine Menge Ausgabe, die so aussehen wird:

      Output

      digitalocean: output will be in this color. ==> digitalocean: Creating temporary ssh key for droplet... ==> digitalocean: Creating droplet... ==> digitalocean: Waiting for droplet to become active... ==> digitalocean: Using ssh communicator to connect: ... ==> digitalocean: Waiting for SSH to become available... ==> digitalocean: Connected to SSH! ==> digitalocean: Provisioning with shell script: /tmp/packer-shell035430322 ... ==> digitalocean: % Total % Received % Xferd Average Speed Time Time Time Current ==> digitalocean: Dload Upload Total Spent Left Speed digitalocean: Archive: vault.zip ==> digitalocean: 100 45.5M 100 45.5M 0 0 154M 0 --:--:-- --:--:-- --:--:-- 153M digitalocean: inflating: vault ==> digitalocean: Gracefully shutting down droplet... ==> digitalocean: Creating snapshot: packer-1581537927 ==> digitalocean: Waiting for snapshot to complete... ==> digitalocean: Destroying droplet... ==> digitalocean: Deleting temporary ssh key... Build 'digitalocean' finished. ==> Builds finished. The artifacts of successful builds are: --> digitalocean: A snapshot was created: 'packer-1581537927' (ID: 58230938) in regions '...'

      Packer protokolliert alle Schritte, die es beim Erstellen Ihrer Vorlage vorgenommen hat. Die letzte Zeile enthält den Namen des Snapshots (wie packer-1581537927) und seine rot markierte ID in Klammern. Notieren Sie die ID Ihres Snapshots, da Sie diese im nächsten Schritt benötigen.

      Falls der Build-Prozess durch Fehler in der API fehlschlägt, warten Sie einige Minuten und versuchen Sie es dann erneut.

      Sie haben nun einen DigitalOcean Snapshot entsprechend Ihrer Vorlage erstellt. Auf dem Snapshot ist Vault vorinstalliert und Sie können nun Droplets mit ihm als Systembild bereitstellen. Im nächsten Schritt schreiben Sie die Terraform-Konfiguration zur Automatisierung solcher Bereitstellungen.

      Schritt 3 — Schreiben der Terraform-Konfiguration

      In diesem Schritt schreiben Sie die Terraform-Konfiguration zur Automatisierung der Droplet-Bereitstellungen des Snapshots, der den gerade mit Packer erstellten Vault enthält.

      Bevor Sie die eigentliche Terraform-Konfiguration zur Bereitstellung von Vault aus dem zuvor erstellten Snapshot schreiben, müssen Sie hierzu zunächst den DigitalOcean-Provider konfigurieren. Navigieren Sie zum Terraform-Unterverzeichnis, indem Sie Folgendes ausführen:

      • cd ~/vault-orchestration/terraform

      Erstellen Sie dann eine Datei namens do-provider.tf, in der Sie den Provider speichern:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/do-provider.tf

      variable "do_token" {
      }
      
      variable "ssh_fingerprint" {
      }
      
      variable "instance_count" {
        default = "1"
      }
      
      variable "do_snapshot_id" {
      }
      
      variable "do_name" {
        default = "vault"
      }
      
      variable "do_region" {
      }
      
      variable "do_size" {
      }
      
      variable "do_private_networking" {
        default = true
      }
      
      provider "digitalocean" {
        token = var.do_token
      }
      

      Diese Datei gibt Parametervariablen an und verleiht dem digitalocean-Provider einen API-Schlüssel. Sie verwenden diese Variablen später in Ihrer Terraform-Vorlage, aber Sie müssen zuerst deren Werte festlegen. Zu diesem Zweck unterstützt Terraform die Angabe der variablen Werte in einer Variablendefinitionsdatei, ähnlich wie bei Packer. Der Dateiname muss entweder in .tfvars oder .tfvars.json enden. Sie übergeben diese Datei später an Terraform mit dem Argument -var-file.

      Speichern und schließen Sie die Datei.

      Erstellen Sie eine Variablendefinitionsdatei mit dem Namen definitions.tfvars mithilfe Ihres Texteditors:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/definitions.tf

      do_token         = "your_do_api_key"
      ssh_fingerprint  = "your_ssh_key_fingerprint"
      do_snapshot_id   = your_do_snapshot_id
      do_name          = "vault"
      do_region        = "nyc3"
      do_size          = "s-1vcpu-1gb"
      instance_count   = 1
      

      Ersetzen Sie your_do_api_key, your_ssh_key_fingerprint und your_do_snapshot_id jeweils mit dem API-Schlüssel Ihres Kontos, dem Fingerabdruck Ihres SSH-Schlüssels und der aus dem vorherigen Schritt erhaltenen Snapshot-ID. Die Parameter do_region und do_size müssen die gleichen Werte wie in der Packer-Variablendatei haben. Wenn Sie mehrere Exemplare gleichzeitig bereitstellen möchten, stellen Sie instance_count auf den gewünschten Wert.

      Danach speichern und schließen Sie die Datei.

      Weitere Informationen über den DigitalOcean Terraform Provider finden Sie in den Offiziellen Dokumenten.

      Sie speichern die Vault Snapshot-Bereitstellungskonfiguration in einer Datei namens deployment.tf, unter dem Verzeichnis terraform. Erstellen Sie sie mit Ihrem Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/deployment.tf

      resource "digitalocean_droplet" "vault" {
        count              = var.instance_count
        image              = var.do_snapshot_id
        name               = var.do_name
        region             = var.do_region
        size               = var.do_size
        private_networking = var.do_private_networking
        ssh_keys = [
          var.ssh_fingerprint
        ]
      }
      
      output "instance_ip_addr" {
        value = {
          for instance in digitalocean_droplet.vault:
          instance.id => instance.ipv4_address
        }
        description = "The IP addresses of the deployed instances, paired with their IDs."
      }
      

      Hier definieren Sie eine einzelne Ressource des Typs digitalocean_droplet namens vault. Danach legen Sie seine Parameter entsprechend den Variablenwerten fest und fügen einen SSH-Schlüssel (mit seinem Fingerabdruck) von Ihrem DigitalOcean-Konto zur Droplet-Ressource hinzu. Zum Schluss erfolgt das output der IP-Adressen aller neu erstellten Exemplare an die Konsole.

      Speichern und schließen Sie die Datei.

      Bevor Sie die Bereitstellungskonfiguration einsetzen, müssen Sie das Verzeichnis als Terraform-Projekt initialisieren:

      Sie sehen die folgende Ausgabe:

      Output

      Initializing the backend... Initializing provider plugins... The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, it is recommended to add version = "..." constraints to the corresponding provider blocks in configuration, with the constraint strings suggested below. * provider.digitalocean: version = "~> 1.14" Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.

      Bei der Initialisierung eines Verzeichnisses als Projekt liest Terraform die verfügbaren Konfigurationsdateien ein und lädt die als notwendig erachteten Plugins herunter, wie in der Ausgabe protokolliert.

      Sie verfügen jetzt über die Terraform-Konfiguration, um Ihren Vault Snapshot bereitzustellen. Sie können diese nun validieren und in einem Droplet bereitstellen.

      Schritt 4 — Bereitstellen von Vault mit Terraform

      In diesem Abschnitt verifizieren Sie die Terraform-Konfiguration mit dem Befehl validate. Nach erfolgreicher Verifizierung wenden Sie sie mit apply an und stellen als Ergebnis ein Droplet bereit.

      Führen Sie den folgenden Befehl aus, um die Gültigkeit Ihrer Konfiguration zu testen:

      Sie sehen die folgende Ausgabe:

      Output

      Success! The configuration is valid.

      Führen Sie als Nächstes den Befehl plan aus, um zu sehen, wie Terraform sich verhält, um die Infrastruktur entsprechend Ihrer Konfiguration bereitzustellen:

      • terraform plan -var-file="definitions.tfvars"

      Terraform akzeptiert eine Variablendefinitionsdatei mit dem Parameter -var-file.

      Die Ausgabe wird ähnlich sein wie diese:

      Output

      Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.vault[0] will be created + resource "digitalocean_droplet" "vault" { ... } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.

      Das grüne + am Anfang der Zeile resource "digitalocean_droplet" "vault" bedeutet, dass Terraform ein neues Droplet mit dem Namen vault erstellt, wobei es folgende Parameter verwendet. Das ist korrekt und nun können Sie den Plan mit terraform apply ausführen:

      • terraform apply -var-file="definitions.tfvars"

      Geben Sie bei Nachfrage yes ein. Nach einigen Minuten ist die Bereitstellung durch das Droplet abgeschlossen und Sie sehen eine Ausgabe ähnlich wie diese:

      Output

      An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + digitalocean_droplet.vault-droplet ... Plan: 1 to add, 0 to change, 0 to destroy. ... digitalocean_droplet.vault-droplet: Creating... ... Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: instance_ip_addr = { "181254240" = "your_new_server_ip" }

      In der Ausgabe protokolliert Terraform die ausgeführten Aktionen (in diesem Fall zur Erstellung eines Droplets) und zeigt am Ende seine öffentliche IP-Adresse an. Diese nutzen Sie, um sich im nächsten Schritt mit Ihrem neuen Droplet zu verbinden.

      Sie haben ein neues Droplet aus dem Snapshot mit Vault erstellt und können es nun verifizieren.

      Schritt 5 — Verifizieren Ihres bereitgestellten Droplets

      In diesem Schritt greifen Sie mit SSH auf Ihr neues Droplet zu und verifizieren, dass Vault korrekt installiert wurde.

      Wenn Sie mit Windows arbeiten, können Sie Software wie Kitty oder Putty verwenden, um sich mit dem Droplet über einen SSH-Schlüssel zu verbinden.

      Auf Linux- und macOS-Rechnern können Sie den bereits verfügbaren Befehl ssh verwenden, um eine Verbindung herzustellen:

      Geben Sie bei Nachfrage yes ein. Nach der Anmeldung starten Sie Vault, indem Sie Folgendes ausführen:

      Sie sehen seine “Hilfe”-Ausgabe, die folgendermaßen aussieht:

      Output

      Usage: vault <command> [args] Common commands: read Read data and retrieves secrets write Write data, configuration, and secrets delete Delete secrets and configuration list List data or secrets login Authenticate locally agent Start a Vault agent server Start a Vault server status Print seal and HA status unwrap Unwrap a wrapped secret Other commands: audit Interact with audit devices auth Interact with auth methods debug Runs the debug command kv Interact with Vault's Key-Value storage lease Interact with leases namespace Interact with namespaces operator Perform operator-specific tasks path-help Retrieve API help for paths plugin Interact with Vault plugins and catalog policy Interact with policies print Prints runtime configurations secrets Interact with secrets engines ssh Initiate an SSH session token Interact with tokens

      Sie können die Verbindung durch Eingabe von exit beenden.

      Sie haben nun verifiziert, dass Ihr neu bereitgestelltes Droplet aus dem von Ihnen erstellten Snapshot kreiert wurde, und dass Vault korrekt installiert ist.

      Zusammenfassung

      Sie verfügen jetzt über ein automatisiertes System zur Bereitstellung von Hashicorp Vault auf DigitalOcean Droplets mit Unterstützung von Terraform und Packer. Sie können nun so viele Vault-Server bereitstellen, wie Sie benötigen. Um Vault zu verwenden, müssen Sie es initialisieren und weiter konfigurieren. Anweisungen hierzu finden Sie in den Offiziellen Dokumenten.

      Weitere Tutorials zur Verwendung von Terraform finden Sie auf der Terraform Content Page.



      Source link