Zenon  Pruschke

Zenon Pruschke

1660760760

So installieren Sie WordPress mit Docker Compose und Nginx

Dieses Tutorial zeigt, wie Sie mit Docker Compose eine WordPress-Installation mit einem Nginx-Webserver erstellen. Erstellen Sie eine Multi-Container-WordPress-Installation

Einführung

WordPress ist ein kostenloses und Open-Source-Content-Management-System (CMS), das auf einer MySQL - Datenbank mit PHP -Verarbeitung basiert. Dank der erweiterbaren Plugin-Architektur und des Templating-Systems kann der größte Teil der Verwaltung über die Weboberfläche erfolgen. Aus diesem Grund ist WordPress eine beliebte Wahl beim Erstellen verschiedener Arten von Websites, von Blogs über Produktseiten bis hin zu E-Commerce-Websites.

Das Ausführen von WordPress beinhaltet normalerweise die Installation eines LAMP- (Linux, Apache, MySQL und PHP) oder LEMP-Stacks (Linux, Nginx, MySQL und PHP), was zeitaufwändig sein kann. Durch die Verwendung von Tools wie Docker und Docker Compose können Sie jedoch den Prozess der Einrichtung Ihres bevorzugten Stacks und der Installation von WordPress optimieren. Anstatt einzelne Komponenten von Hand zu installieren, können Sie Images verwenden , die Dinge wie Bibliotheken, Konfigurationsdateien und Umgebungsvariablen standardisieren. Führen Sie diese Images dann in Containern aus, isolierten Prozessen, die auf einem gemeinsam genutzten Betriebssystem ausgeführt werden. Darüber hinaus können Sie mithilfe von Compose mehrere Container koordinieren, z. B. eine Anwendung und eine Datenbank, um miteinander zu kommunizieren.

In diesem Tutorial erstellen Sie eine Multi-Container-WordPress-Installation. Ihre Container enthalten eine MySQL-Datenbank, einen Nginx-Webserver und WordPress selbst. Sie sichern Ihre Installation auch, indem Sie TLS/SSL-Zertifikate mit Let's Encrypt für die Domäne erhalten, die Sie mit Ihrer Website verknüpfen möchten. Schließlich richten Sie einen cronJob ein, um Ihre Zertifikate zu erneuern, damit Ihre Domain sicher bleibt.

Sobald Sie alles eingerichtet haben, können Sie mit dem ersten Schritt beginnen.

Schritt 1 – Definieren der Webserverkonfiguration

Bevor Sie Container ausführen, müssen Sie zunächst die Konfiguration für Ihren Nginx-Webserver definieren. Ihre Konfigurationsdatei enthält einige WordPress-spezifische Standortblöcke sowie einen Standortblock, um Let’s Encrypt-Verifizierungsanfragen zur automatisierten Zertifikatserneuerung an den Certbot-Client weiterzuleiten.

Erstellen Sie zunächst ein Projektverzeichnis für Ihr WordPress-Setup. In diesem Beispiel heißt es wordpress. Sie können dieses Verzeichnis anders benennen, wenn Sie möchten:

mkdir wordpress

Navigieren Sie dann zum Verzeichnis:

cd wordpress

Erstellen Sie als Nächstes ein Verzeichnis für die Konfigurationsdatei:

mkdir nginx-conf

Öffnen Sie die Datei mit nanooder Ihrem bevorzugten Editor:

nano nginx-conf/nginx.conf

Fügen Sie in dieser Datei einen Serverblock mit Anweisungen für Ihren Servernamen und das Dokumentstammverzeichnis sowie Standortblöcke hinzu, um die Anfrage des Certbot-Clients nach Zertifikaten, PHP-Verarbeitung und statischen Asset-Anfragen weiterzuleiten.

Fügen Sie den folgenden Code in die Datei ein. Stellen Sie sicher, dass your_domainSie durch Ihren eigenen Domainnamen ersetzen:

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

Unser Serverblock enthält die folgenden Informationen:

Richtlinien:

  • listen: Dies weist Nginx an, auf Port zu lauschen 80, wodurch Sie das Webroot-Plugin von Certbot für Ihre Zertifikatsanforderungen verwenden können. Beachten Sie, dass Sie den Port noch nicht443 einschließen – Sie werden Ihre Konfiguration aktualisieren, um SSL einzuschließen, sobald Sie Ihre Zertifikate erfolgreich erhalten haben.
  • server_name: Dies definiert Ihren Servernamen und den Serverblock, der für Anfragen an Ihren Server verwendet werden soll. your_domainAchten Sie darauf, diese Zeile durch Ihren eigenen Domainnamen zu ersetzen .
  • index: Diese Direktive definiert die Dateien, die als Indizes verwendet werden, wenn Anfragen an Ihren Server verarbeitet werden. Sie haben hier die Standardprioritätsreihenfolge geändert und sich index.phpnach vorne bewegt index.html, damit Nginx aufgerufene Dateien nach index.phpMöglichkeit priorisiert.
  • root: Diese Direktive benennt das Root- Verzeichnis für Anfragen an Ihren Server. Dieses Verzeichnis /var/www/htmlwird zur Build-Zeit durch Anweisungen in Ihrer WordPress-Dockerfile als Mount-Punkt erstellt . Diese Dockerfile-Anweisungen stellen auch sicher, dass die Dateien aus der WordPress-Version auf diesem Volume gemountet werden.

Standortblöcke:

  • location ~ /.well-known/acme-challenge: Dieser Standortblock verarbeitet Anfragen an das .well-knownVerzeichnis, in dem Certbot eine temporäre Datei ablegt, um zu überprüfen, ob das DNS für Ihre Domäne zu Ihrem Server aufgelöst wird. Mit dieser Konfiguration können Sie das Webroot-Plugin von Certbot verwenden, um Zertifikate für Ihre Domain zu erhalten.
  • location /: In diesem Location-Block wird eine try_filesDirektive verwendet, um nach Dateien zu suchen, die mit einzelnen URI-Anforderungen übereinstimmen. Anstatt jedoch standardmäßig einen 404 Not Found -Status zurückzugeben, übergibst du die Kontrolle an die WordPress- index.phpDatei mit den Anfrageargumenten.
  • location ~ \.php$: Dieser Standortblock übernimmt die PHP-Verarbeitung und leitet diese Anfragen an Ihren wordpressContainer weiter. Da Ihr WordPress-Docker-Image auf dem php:fpmimage basiert, fügen Sie in diesem Block auch Konfigurationsoptionen ein, die für das FastCGI-Protokoll spezifisch sind. Nginx benötigt einen unabhängigen PHP-Prozessor für PHP-Anfragen. In diesem Fall werden diese Anforderungen von dem php-fpmProzessor verarbeitet, der im php:fpmImage enthalten ist. Darüber hinaus enthält dieser Standortblock FastCGI-spezifische Anweisungen, Variablen und Optionen, die Anforderungen an die in Ihrem wordpressContainer ausgeführte WordPress-Anwendung weiterleiten, den bevorzugten Index für den geparsten Anforderungs-URI festlegen und URI-Anforderungen analysieren.
  • location ~ /\.ht: Dieser Block verarbeitet .htaccessDateien, da Nginx sie nicht bereitstellt. Die deny_allDirektive stellt sicher, dass .htaccessDateien niemals Benutzern bereitgestellt werden.
  • location = /favicon.ico, location = /robots.txt: Diese Blöcke stellen sicher, dass Anfragen an /favicon.icound /robots.txtnicht protokolliert werden.
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: Dieser Block deaktiviert die Protokollierung für statische Asset-Anforderungen und stellt sicher, dass diese Assets in hohem Maße zwischengespeichert werden können, da ihre Bereitstellung normalerweise teuer ist.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind. Wenn Sie verwendet nanohaben, tun Sie dies, indem Sie CTRL+X, Y, dann drücken ENTER.

Wenn Ihre Nginx-Konfiguration vorhanden ist, können Sie mit dem Erstellen von Umgebungsvariablen fortfahren, die zur Laufzeit an Ihre Anwendungs- und Datenbankcontainer übergeben werden.

Schritt 2 – Definieren von Umgebungsvariablen

Ihre Datenbank- und WordPress-Anwendungscontainer benötigen zur Laufzeit Zugriff auf bestimmte Umgebungsvariablen, damit Ihre Anwendungsdaten bestehen bleiben und für Ihre Anwendung zugänglich sind. Diese Variablen enthalten sowohl vertrauliche als auch nicht vertrauliche Informationen: vertrauliche Werte für Ihr MySQL -Root- Passwort und den Benutzer und das Passwort der Anwendungsdatenbank sowie nicht vertrauliche Informationen für den Namen und Host Ihrer Anwendungsdatenbank.

Anstatt all diese Werte in Ihrer Docker Compose-Datei festzulegen – der Hauptdatei, die Informationen darüber enthält, wie Ihre Container ausgeführt werden – legen Sie die sensiblen Werte in einer .envDatei fest und schränken ihre Verbreitung ein. Dadurch wird verhindert, dass diese Werte in Ihre Projekt-Repositorys kopiert und öffentlich zugänglich gemacht werden.

Öffnen Sie in Ihrem Hauptprojektverzeichnis ~/wordpresseine Datei namens .env:

nano .env

Die vertraulichen Werte, die Sie in dieser Datei festlegen, umfassen ein Passwort für den MySQL -Root- Benutzer sowie einen Benutzernamen und ein Passwort, die WordPress für den Zugriff auf die Datenbank verwendet.

Fügen Sie der Datei die folgenden Variablennamen und -werte hinzu. Denken Sie daran, hier Ihre eigenen Werte für jede Variable anzugeben:

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

Enthalten sind ein Passwort für das Root- Administrationskonto sowie Ihr bevorzugter Benutzername und Ihr bevorzugtes Passwort für Ihre Anwendungsdatenbank.

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

Da Ihre .envDatei vertrauliche Informationen enthält, möchten Sie sicherstellen, dass sie in Ihren Projekten .gitignoreund .dockerignoreDateien enthalten ist. Dies teilt Git und Docker mit, welche Dateien nicht in Ihre Git-Repositories bzw. Docker-Images kopiert werden sollen.

Wenn Sie vorhaben, mit Git zur Versionskontrolle zu arbeiten, initialisieren Sie Ihr aktuelles Arbeitsverzeichnis als Repository mit git init:

git init

Erstellen und öffnen Sie dann eine .gitignoreDatei:

nano .gitignore

.envZur Datei hinzufügen :

.env

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

.envEbenso ist es eine gute Vorsichtsmaßnahme, eine Datei hinzuzufügen .dockerignore, damit sie nicht in Ihren Containern landet, wenn Sie dieses Verzeichnis als Build-Kontext verwenden.

Öffne die Datei:

nano .dockerignore

.envZur Datei hinzufügen :

.env

Darunter können Sie optional Dateien und Verzeichnisse hinzufügen, die mit der Entwicklung Ihrer Anwendung verbunden sind:

.env
.git
docker-compose.yml
.dockerignore

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

Mit Ihren sensiblen Informationen können Sie nun damit fortfahren, Ihre Dienste in einer docker-compose.ymlDatei zu definieren.

Schritt 3 – Definieren von Diensten mit Docker Compose

Ihre docker-compose.ymlDatei enthält die Dienstdefinitionen für Ihr Setup. Ein Dienst in Compose ist ein laufender Container, und Dienstdefinitionen geben Informationen darüber an, wie jeder Container ausgeführt wird.

Mit Compose können Sie verschiedene Dienste zum Ausführen von Multi-Container-Anwendungen definieren, da Compose es Ihnen ermöglicht, diese Dienste mit gemeinsam genutzten Netzwerken und Volumes zu verknüpfen. Dies ist für Ihr aktuelles Setup hilfreich, da Sie verschiedene Container für Ihre Datenbank, WordPress-Anwendung und Ihren Webserver erstellen. Sie werden auch einen Container erstellen, um den Certbot-Client auszuführen , um Zertifikate für Ihren Webserver zu erhalten.

Erstellen und öffnen Sie zunächst die docker-compose.ymlDatei:

nano docker-compose.yml

Fügen Sie den folgenden Code hinzu, um Ihre Compose-Dateiversion und Ihren dbDatenbankdienst zu definieren:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

Die dbDienstdefinition enthält die folgenden Optionen:

  • image: Dies teilt Compose mit, welches Image abgerufen werden soll, um den Container zu erstellen. Sie heften das mysql:8.0Bild hier an, um zukünftige Konflikte zu vermeiden, wenn das mysql:latestBild weiterhin aktualisiert wird. Weitere Informationen zum Anheften von Versionen und zum Vermeiden von Abhängigkeitskonflikten finden Sie in der Docker-Dokumentation zu Best Practices für Dockerfile .
  • container_name: Dies gibt einen Namen für den Container an.
  • restart: Dies definiert die Container-Neustartrichtlinie. Der Standardwert ist no, aber Sie haben den Container so eingestellt, dass er neu gestartet wird, sofern er nicht manuell gestoppt wird.
  • env_file: Diese Option teilt Compose mit, dass Sie Umgebungsvariablen aus einer Datei namens hinzufügen möchten .env, die sich in Ihrem Build-Kontext befindet. In diesem Fall ist der Build-Kontext Ihr aktuelles Verzeichnis.
  • environment: Mit dieser Option können Sie zusätzliche Umgebungsvariablen hinzufügen, die über die in Ihrer .envDatei definierten hinausgehen. Sie werden die MYSQL_DATABASEVariable gleich setzen wordpress, um einen Namen für Ihre Anwendungsdatenbank anzugeben. Da es sich um nicht vertrauliche Informationen handelt, können Sie sie direkt in die docker-compose.ymlDatei aufnehmen.
  • volumes: Hier mounten Sie ein benanntes Volume mit dem Namen dbdatades /var/lib/mysqlVerzeichnisses im Container. Dies ist das Standarddatenverzeichnis für MySQL auf den meisten Distributionen.
  • command: Diese Option gibt einen Befehl zum Überschreiben der standardmäßigen CMD-Anweisung für das Bild an. In diesem speziellen Fall fügen Sie dem Standardbefehl des Docker-Images eine Option hinzu mysqld, die den MySQL-Server auf dem Container startet. Diese Option --default-authentication-plugin=mysql_native_passwordsetzt die --default-authentication-pluginSystemvariable auf und gibt an mysql_native_password, welcher Authentifizierungsmechanismus neue Authentifizierungsanforderungen an den Server steuern soll. Da PHP und damit Ihr WordPress-Image den neueren Authentifizierungsstandard von MySQL nicht unterstützen , müssen Sie diese Anpassung vornehmen, um den Benutzer Ihrer Anwendungsdatenbank zu authentifizieren.
  • networks: Dies gibt an, dass Ihr Anwendungsdienst dem app-networkNetzwerk beitritt, das Sie am Ende der Datei definieren.

Fügen Sie als Nächstes unter Ihrer dbDienstdefinition die Definition für Ihren wordpressAnwendungsdienst hinzu:

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

In dieser Dienstdefinition benennen Sie Ihren Container und definieren eine Neustartrichtlinie, wie Sie es beim dbDienst getan haben. Sie fügen auch einige Optionen hinzu, die für diesen Container spezifisch sind:

  • depends_on: Diese Option stellt sicher, dass Ihre Container in der Reihenfolge ihrer Abhängigkeit gestartet werden, wobei der wordpressContainer nach dem Container beginnt db. Ihre WordPress-Anwendung ist auf die Existenz Ihrer Anwendungsdatenbank und Ihres Benutzers angewiesen, sodass das Ausdrücken dieser Abhängigkeitsreihenfolge Ihrer Anwendung ermöglicht, ordnungsgemäß zu starten.
  • image: Für dieses Setup verwenden Sie das 5.1.1-fpm-alpineWordPress-Image . Wie in Schritt 1 besprochen , stellt die Verwendung dieses Images sicher, dass Ihre Anwendung über den php-fpmProzessor verfügt, den Nginx für die PHP-Verarbeitung benötigt. Dies ist auch ein alpinevom Alpine Linux-Projekt abgeleitetes Bild, das dazu beitragen wird, die Gesamtbildgröße gering zu halten. Weitere Informationen zu den Vor- und Nachteilen der Verwendung von alpineBildern und dazu, ob dies für Ihre Anwendung sinnvoll ist oder nicht, finden Sie in der vollständigen Diskussion im Abschnitt „Bildvarianten“ auf der Bildseite von Docker Hub WordPress .
  • env_file: Auch hier geben Sie an, dass Sie Werte aus Ihrer Datei abrufen möchten .env, da Sie hier Ihren Anwendungsdatenbankbenutzer und Ihr Kennwort definiert haben.
  • environment: Hier verwenden Sie die Werte, die Sie in Ihrer .envDatei definiert haben, weisen sie jedoch den Variablennamen zu, die das WordPress-Image erwartet: WORDPRESS_DB_USERund WORDPRESS_DB_PASSWORD. Sie definieren auch eine WORDPRESS_DB_HOST, bei der es sich um den MySQL-Server handelt, der auf dem dbContainer ausgeführt wird, auf den über den Standardport von MySQL zugegriffen werden kann 3306. Ihr WORDPRESS_DB_NAMEwird derselbe Wert sein, den Sie in der MySQL-Dienstdefinition für Ihre MYSQL_DATABASE: angegeben haben wordpress.
  • volumes: Sie mounten ein benanntes Volume wordpressmit dem Namen des /var/www/htmlMountpoints , der vom WordPress-Image erstellt wurde . Wenn Sie ein benanntes Volume auf diese Weise verwenden, können Sie Ihren Anwendungscode mit anderen Containern teilen.
  • networks: Sie fügen den wordpressContainer auch dem app-networkNetzwerk hinzu.

Fügen Sie als Nächstes unter der wordpressAnwendungsdienstdefinition die folgende Definition für Ihren webserverNginx-Dienst hinzu:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

Hier benennen Sie Ihren Container und machen ihn wordpressin der Startreihenfolge vom Container abhängig. Sie verwenden auch ein alpineImage – das 1.15.12-alpineNginx-Image .

Diese Dienstdefinition enthält auch die folgenden Optionen:

  • ports: Dadurch wird der Port verfügbar gemacht 80, um die Konfigurationsoptionen zu aktivieren, die Sie in Ihrer nginx.confDatei in Schritt 1 definiert haben .
  • volumes: Hier definieren Sie eine Kombination aus benannten Volumes und Bind-Mounts :
    • wordpress:/var/www/html: Dadurch wird Ihr WordPress-Anwendungscode in das /var/www/htmlVerzeichnis eingebunden, das Verzeichnis, das Sie als rootin Ihrem Nginx-Serverblock festgelegt haben.
    • ./nginx-conf:/etc/nginx/conf.d: Dadurch wird das Nginx-Konfigurationsverzeichnis auf dem Host an das entsprechende Verzeichnis auf dem Container gebunden, wodurch sichergestellt wird, dass alle Änderungen, die Sie an Dateien auf dem Host vornehmen, im Container widergespiegelt werden.
    • certbot-etc:/etc/letsencrypt: Dadurch werden die relevanten Let's Encrypt-Zertifikate und -Schlüssel für Ihre Domain in das entsprechende Verzeichnis des Containers gemountet.

Sie haben diesen Container auch zum app-networkNetzwerk hinzugefügt.

Fügen Sie schließlich unter Ihrer webserverDefinition Ihre letzte Dienstdefinition für den certbotDienst hinzu. Achten Sie darauf, die hier aufgeführten E-Mail-Adressen und Domänennamen durch Ihre eigenen Informationen zu ersetzen:

certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

Diese Definition weist Compose an, das certbot/certbotImage von Docker Hub abzurufen. Es verwendet auch benannte Volumes, um Ressourcen mit dem Nginx-Container zu teilen, einschließlich der Domänenzertifikate und -eingaben certbot-etcsowie des Anwendungscodes in wordpress.

Auch hier haben Sie früher depends_onangegeben, dass der certbotContainer gestartet werden soll, sobald der webserverDienst ausgeführt wird.

Sie haben auch eine commandOption eingefügt, die einen Unterbefehl angibt, der mit dem Standardbefehl des Containers certbotausgeführt werden soll. Der certonlyUnterbefehl erhält ein Zertifikat mit den folgenden Optionen:

  • --webroot: Dies weist Certbot an, das Webroot-Plugin zu verwenden, um Dateien zur Authentifizierung im Webroot-Ordner abzulegen. Dieses Plugin hängt von der HTTP-01-Validierungsmethode ab , die eine HTTP-Anforderung verwendet, um zu beweisen, dass Certbot auf Ressourcen von einem Server zugreifen kann, der auf einen bestimmten Domänennamen antwortet.
  • --webroot-path: Dies gibt den Pfad des Webroot-Verzeichnisses an.
  • --email: Ihre bevorzugte E-Mail-Adresse für die Registrierung und Wiederherstellung.
  • --agree-tos: Dies gibt an, dass Sie der Abonnentenvereinbarung von ACME zustimmen .
  • --no-eff-email: Dies teilt Certbot mit, dass Sie Ihre E-Mail nicht mit der Electronic Frontier Foundation (EFF) teilen möchten . Sie können dies gerne weglassen, wenn Sie dies bevorzugen.
  • --staging: Dies teilt Certbot mit, dass Sie die Staging-Umgebung von Let's Encrypt verwenden möchten, um Testzertifikate zu erhalten. Mit dieser Option können Sie Ihre Konfigurationsoptionen testen und mögliche Domain-Anforderungsbeschränkungen vermeiden. Weitere Informationen zu diesen Limits finden Sie in der Dokumentation zu Ratenlimits von Let's Encrypt .
  • -d: Hiermit können Sie Domänennamen angeben, die Sie auf Ihre Anfrage anwenden möchten. In diesem Fall haben Sie your_domainund eingeschlossen www.your_domain. Achten Sie darauf, diese durch Ihre eigene Domain zu ersetzen.

Fügen Sie unterhalb der certbotService-Definition Ihre Netzwerk- und Volume-Definitionen hinzu:

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

Ihr Schlüssel der obersten Ebene volumesdefiniert die Lautstärken certbot-etc, wordpressund dbdata. Wenn Docker Volumes erstellt, wird der Inhalt des Volumes in einem Verzeichnis auf dem Host-Dateisystem gespeichert /var/lib/docker/volumes/, das von Docker verwaltet wird. Der Inhalt jedes Volumes wird dann aus diesem Verzeichnis in jeden Container gemountet, der das Volume verwendet. Auf diese Weise ist es möglich, Code und Daten zwischen Containern auszutauschen.

Das benutzerdefinierte Bridge-Netzwerk app-networkermöglicht die Kommunikation zwischen Ihren Containern, da sie sich auf demselben Docker-Daemon-Host befinden. Dies optimiert den Datenverkehr und die Kommunikation innerhalb der Anwendung, da alle Ports zwischen Containern im selben Bridge-Netzwerk geöffnet werden, ohne dass Ports der Außenwelt zugänglich gemacht werden. Daher können Ihre db, wordpress, und webserverContainer miteinander kommunizieren, und Sie müssen nur den Port 80für den Front-End-Zugriff auf die Anwendung verfügbar machen.

Das Folgende ist die docker-compose.ymlDatei in ihrer Gesamtheit:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

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

Wenn Ihre Dienstdefinitionen vorhanden sind, können Sie die Container starten und Ihre Zertifikatsanforderungen testen.

Schritt 4 – Erhalt von SSL-Zertifikaten und Anmeldeinformationen

Starten Sie Ihre Container mit dem docker-compose upBefehl, der Ihre Container in der von Ihnen angegebenen Reihenfolge erstellt und ausführt. Durch Hinzufügen des -dFlags führt der Befehl die Container db, wordpress, und webserverim Hintergrund aus:

docker-compose up -d

Die folgende Ausgabe bestätigt, dass Ihre Dienste erstellt wurden:

Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

Überprüfen docker-compose psSie mit den Status Ihrer Dienste:

docker-compose ps

Sobald dies abgeschlossen ist, werden Ihre db, wordpress, und webserver-Dienste angezeigt Upund der certbotContainer wird mit einer 0Statusmeldung beendet:

Output
  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp  

Alles andere als Upin der StateSpalte für die Dienste db, wordpress, oder webserveroder ein anderer Exit-Status als 0für den certbotContainer bedeutet, dass Sie möglicherweise die Dienstprotokolle mit dem docker-compose logsfolgenden Befehl überprüfen müssen:

docker-compose logs service_name

Sie können jetzt überprüfen, ob Ihre Zertifikate im webserverContainer gemountet wurden mit docker-compose exec:

docker-compose exec webserver ls -la /etc/letsencrypt/live

Sobald Ihre Zertifikatsanforderungen erfolgreich sind, lautet die Ausgabe:

Output
total 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain

Da Sie nun wissen, dass Ihre Anfrage erfolgreich sein wird, können Sie die Dienstdefinition bearbeiten , um das Flag certbotzu entfernen .--staging

Öffnen docker-compose.yml:

nano docker-compose.yml

Suchen Sie den Abschnitt der Datei mit der Dienstdefinition certbotund ersetzen Sie das --stagingFlag in der commandOption durch das --force-renewalFlag, das Certbot mitteilt, dass Sie ein neues Zertifikat mit denselben Domänen wie ein vorhandenes Zertifikat anfordern möchten. Das Folgende ist die certbotDienstdefinition mit dem aktualisierten Flag:

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

Sie können jetzt ausführen docker-compose up, um den Container neu zu erstellen certbot. Sie werden auch die --no-depsOption hinzufügen, um Compose mitzuteilen, dass es das Starten des webserverDienstes überspringen kann, da es bereits läuft:

docker-compose up --force-recreate --no-deps certbot

Die folgende Ausgabe zeigt an, dass Ihre Zertifikatsanforderung erfolgreich war:

Output
Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for your_domain
certbot      | http-01 challenge for www.your_domain
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0

Wenn Ihre Zertifikate vorhanden sind, können Sie mit der Änderung Ihrer Nginx-Konfiguration fortfahren, um SSL einzuschließen.

Schritt 5 – Ändern der Webserverkonfiguration und Dienstdefinition

Das Aktivieren von SSL in Ihrer Nginx-Konfiguration umfasst das Hinzufügen einer HTTP-Umleitung zu HTTPS, das Angeben Ihres SSL-Zertifikats und der Schlüsselspeicherorte sowie das Hinzufügen von Sicherheitsparametern und Headern.

Da Sie den Dienst neu erstellen webserverwerden, um diese Ergänzungen aufzunehmen, können Sie ihn jetzt stoppen:

docker-compose stop webserver

Bevor Sie die Konfigurationsdatei ändern, rufen Sie den empfohlenen Nginx-Sicherheitsparameter von Certbot ab, indem Sie Folgendes verwenden curl:

curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

Dieser Befehl speichert diese Parameter in einer Datei namens options-ssl-nginx.conf, die sich im nginx-confVerzeichnis befindet.

Entfernen Sie als Nächstes die zuvor erstellte Nginx-Konfigurationsdatei:

rm nginx-conf/nginx.conf

Erstellen und öffnen Sie eine andere Version der Datei:

nano nginx-conf/nginx.conf

Fügen Sie der Datei den folgenden Code hinzu, um HTTP zu HTTPS umzuleiten und SSL-Anmeldeinformationen, Protokolle und Sicherheitsheader hinzuzufügen. your_domainDenken Sie daran, durch Ihre eigene Domain zu ersetzen :

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

Der HTTP-Serverblock gibt das Webroot für Certbot-Erneuerungsanfragen an das .well-known/acme-challengeVerzeichnis an. Es enthält auch eine Rewrite-Direktive , die HTTP-Anforderungen an das Stammverzeichnis an HTTPS weiterleitet.

Der HTTPS-Serverblock aktiviert sslund http2. Um mehr darüber zu erfahren, wie HTTP/2 HTTP-Protokolle iteriert und welche Vorteile es für die Leistung von Websites haben kann, lesen Sie bitte die Einführung zu How To Set Up Nginx with HTTP/2 Support on Ubuntu 18.04 .

Dieser Block enthält auch Ihr SSL-Zertifikat und Schlüsselspeicherorte sowie die empfohlenen Certbot-Sicherheitsparameter, die Sie in gespeichert haben nginx-conf/options-ssl-nginx.conf.

Darüber hinaus sind einige Sicherheits-Header enthalten, die es Ihnen ermöglichen, A - Bewertungen für Dinge wie die Server-Testseiten von SSL Labs und Security Headers zu erhalten. Zu diesen Headern gehören X-Frame-Options, X-Content-Type-Options, Referrer Policy, Content-Security-Policyund X-XSS-Protection. Der HTTPStrict Transport Security (HSTS)-Header ist auskommentiert – aktivieren Sie dies nur, wenn Sie die Auswirkungen verstehen und seine „Preload“-Funktionalität bewertet haben .

Ihre rootund index-Anweisungen befinden sich ebenfalls in diesem Block, ebenso wie die restlichen WordPress-spezifischen Standortblöcke, die in Schritt 1 besprochen wurden .

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

Bevor Sie den webserverDienst neu erstellen, müssen Sie 443Ihrer Dienstdefinition eine Portzuordnung hinzufügen webserver.

Öffnen Sie Ihre docker-compose.ymlDatei:

nano docker-compose.yml

Fügen Sie in der webserverDienstdefinition die folgende Portzuordnung hinzu:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

Hier ist die vollständige docker-compose.ymlDatei nach den Änderungen:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

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

Erstellen Sie den webserverDienst neu:

docker-compose up -d --force-recreate --no-deps webserver

Überprüfen Sie Ihre Dienstleistungen mit docker-compose ps:

docker-compose ps

Die Ausgabe sollte anzeigen, dass Ihre Dienste db, wordpress, und webserverausgeführt werden:

Output
  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp    

Wenn Ihre Container ausgeführt werden, können Sie Ihre WordPress-Installation über die Weboberfläche abschließen.

Schritt 6 – Abschließen der Installation über die Webschnittstelle

Schließen Sie bei laufenden Containern die Installation über die WordPress-Weboberfläche ab.

Navigieren Sie in Ihrem Webbrowser zur Domain Ihres Servers. your_domainDenken Sie daran, durch Ihren eigenen Domainnamen zu ersetzen :

https://your_domain

Wählen Sie die Sprache aus, die Sie verwenden möchten:

WordPress-Sprachauswahl

Nachdem Sie auf Weiter geklickt haben, landen Sie auf der Haupteinrichtungsseite, wo Sie einen Namen für Ihre Website und einen Benutzernamen auswählen müssen. Es ist eine gute Idee, hier einen einprägsamen Benutzernamen (statt „admin“) und ein sicheres Passwort zu wählen. Sie können das Passwort verwenden, das WordPress automatisch generiert, oder ein eigenes erstellen.

Schließlich müssen Sie Ihre E-Mail-Adresse eingeben und entscheiden, ob Sie Suchmaschinen davon abhalten möchten, Ihre Website zu indizieren:

WordPress Haupteinrichtungsseite

Wenn Sie unten auf der Seite auf WordPress installieren klicken, gelangen Sie zu einer Anmeldeaufforderung:

WordPress-Anmeldebildschirm

Sobald Sie angemeldet sind, haben Sie Zugriff auf das WordPress-Administrations-Dashboard:

WordPress Hauptverwaltungs-Dashboard

Wenn Ihre WordPress-Installation abgeschlossen ist, können Sie Schritte unternehmen, um sicherzustellen, dass Ihre SSL-Zertifikate automatisch erneuert werden.

Schritt 7 – Erneuern von Zertifikaten

Let's Encrypt Zertifikate sind 90 Tage gültig. Sie können einen automatischen Verlängerungsprozess einrichten, um sicherzustellen, dass sie nicht verfallen. Eine Möglichkeit, dies zu tun, besteht darin, einen Job mit dem cronPlanungsdienstprogramm zu erstellen. Im folgenden Beispiel erstellen Sie einen cronJob, um regelmäßig ein Skript auszuführen, das Ihre Zertifikate erneuert und Ihre Nginx-Konfiguration neu lädt.

Öffnen Sie zuerst ein Skript mit dem Namen ssl_renew.sh:

nano ssl_renew.sh

Fügen Sie dem Skript den folgenden Code hinzu, um Ihre Zertifikate zu erneuern und Ihre Webserverkonfiguration neu zu laden. Denken Sie daran, den Beispiel-Benutzernamen hier durch Ihren eigenen Nicht -Root- Benutzernamen zu ersetzen:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

Dieses Skript weist zuerst die docker-composeBinärdatei einer Variablen namens zu COMPOSEund gibt die --no-ansiOption an, die docker-composeBefehle ohne ANSI-Steuerzeichen ausführt . Es macht dann dasselbe mit der dockerBinärdatei. Schließlich wechselt es in das ~/wordpressProjektverzeichnis und führt die folgenden docker-composeBefehle aus:

  • docker-compose run: Dadurch wird ein certbotContainer gestartet und der commandin Ihrer Dienstdefinition bereitgestellte überschrieben certbot. Anstatt den certonlyUnterbefehl zu verwenden, wird der renewUnterbefehl verwendet, der Zertifikate erneuert, die kurz vor dem Ablauf stehen. Ebenfalls enthalten ist die --dry-runOption, Ihr Skript zu testen.
  • docker-compose kill: Dies sendet ein SIGHUPSignal an den webserverContainer, um die Nginx-Konfiguration neu zu laden.

Es wird dann ausgeführt docker system prune, um alle nicht verwendeten Container und Bilder zu entfernen.

Schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind. Machen Sie es mit dem folgenden Befehl ausführbar:

chmod +x ssl_renew.sh

Öffnen Sie als Nächstes Ihre Stammdatei crontab , um das Erneuerungsskript in einem bestimmten Intervall auszuführen:

sudo crontab -e 

Wenn Sie diese Datei zum ersten Mal bearbeiten, werden Sie aufgefordert, einen Editor auszuwählen:

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

Fügen Sie ganz unten in dieser Datei die folgende Zeile hinzu:

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

Dadurch wird das Auftragsintervall auf alle fünf Minuten eingestellt, sodass Sie testen können, ob Ihre Verlängerungsanforderung wie beabsichtigt funktioniert hat oder nicht. Eine Protokolldatei, cron.log, wird erstellt, um relevante Ausgaben des Jobs aufzuzeichnen.

Prüfen Sie cron.lognach fünf Minuten, ob die Erneuerungsanfrage erfolgreich war:

tail -f /var/log/cron.log

Die folgende Ausgabe bestätigt eine erfolgreiche Verlängerung:

Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Beenden Sie es, indem CTRL+CSie in Ihr Terminal eintreten.

crontabSie können die Datei ändern , um ein tägliches Intervall festzulegen. Um das Skript beispielsweise jeden Tag mittags auszuführen, würden Sie die letzte Zeile der Datei wie folgt ändern:

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

--dry-runSie sollten die Option auch aus Ihrem ssl_renew.shSkript entfernen :

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

Ihr cronJob stellt sicher, dass Ihre Let's Encrypt-Zertifikate nicht verfallen, indem Sie sie erneuern, wenn sie berechtigt sind. Sie können die Protokollrotation auch mit dem Dienstprogramm Logrotate einrichten , um Ihre Protokolldateien zu rotieren und zu komprimieren.

Fazit

In diesem Tutorial haben Sie Docker Compose verwendet, um eine WordPress-Installation mit einem Nginx-Webserver zu erstellen. Als Teil dieses Workflows haben Sie TLS/SSL-Zertifikate für die Domain erhalten, die Sie mit Ihrer WordPress-Site verknüpfen möchten. Außerdem haben Sie einen cronJob erstellt, um diese Zertifikate bei Bedarf zu erneuern.

Quelle des Originalartikels unter https://www.digitalocean.com

#wordpress #docker 

What is GEEK

Buddha Community

So installieren Sie WordPress mit Docker Compose und Nginx
Zenon  Pruschke

Zenon Pruschke

1660760760

So installieren Sie WordPress mit Docker Compose und Nginx

Dieses Tutorial zeigt, wie Sie mit Docker Compose eine WordPress-Installation mit einem Nginx-Webserver erstellen. Erstellen Sie eine Multi-Container-WordPress-Installation

Einführung

WordPress ist ein kostenloses und Open-Source-Content-Management-System (CMS), das auf einer MySQL - Datenbank mit PHP -Verarbeitung basiert. Dank der erweiterbaren Plugin-Architektur und des Templating-Systems kann der größte Teil der Verwaltung über die Weboberfläche erfolgen. Aus diesem Grund ist WordPress eine beliebte Wahl beim Erstellen verschiedener Arten von Websites, von Blogs über Produktseiten bis hin zu E-Commerce-Websites.

Das Ausführen von WordPress beinhaltet normalerweise die Installation eines LAMP- (Linux, Apache, MySQL und PHP) oder LEMP-Stacks (Linux, Nginx, MySQL und PHP), was zeitaufwändig sein kann. Durch die Verwendung von Tools wie Docker und Docker Compose können Sie jedoch den Prozess der Einrichtung Ihres bevorzugten Stacks und der Installation von WordPress optimieren. Anstatt einzelne Komponenten von Hand zu installieren, können Sie Images verwenden , die Dinge wie Bibliotheken, Konfigurationsdateien und Umgebungsvariablen standardisieren. Führen Sie diese Images dann in Containern aus, isolierten Prozessen, die auf einem gemeinsam genutzten Betriebssystem ausgeführt werden. Darüber hinaus können Sie mithilfe von Compose mehrere Container koordinieren, z. B. eine Anwendung und eine Datenbank, um miteinander zu kommunizieren.

In diesem Tutorial erstellen Sie eine Multi-Container-WordPress-Installation. Ihre Container enthalten eine MySQL-Datenbank, einen Nginx-Webserver und WordPress selbst. Sie sichern Ihre Installation auch, indem Sie TLS/SSL-Zertifikate mit Let's Encrypt für die Domäne erhalten, die Sie mit Ihrer Website verknüpfen möchten. Schließlich richten Sie einen cronJob ein, um Ihre Zertifikate zu erneuern, damit Ihre Domain sicher bleibt.

Sobald Sie alles eingerichtet haben, können Sie mit dem ersten Schritt beginnen.

Schritt 1 – Definieren der Webserverkonfiguration

Bevor Sie Container ausführen, müssen Sie zunächst die Konfiguration für Ihren Nginx-Webserver definieren. Ihre Konfigurationsdatei enthält einige WordPress-spezifische Standortblöcke sowie einen Standortblock, um Let’s Encrypt-Verifizierungsanfragen zur automatisierten Zertifikatserneuerung an den Certbot-Client weiterzuleiten.

Erstellen Sie zunächst ein Projektverzeichnis für Ihr WordPress-Setup. In diesem Beispiel heißt es wordpress. Sie können dieses Verzeichnis anders benennen, wenn Sie möchten:

mkdir wordpress

Navigieren Sie dann zum Verzeichnis:

cd wordpress

Erstellen Sie als Nächstes ein Verzeichnis für die Konfigurationsdatei:

mkdir nginx-conf

Öffnen Sie die Datei mit nanooder Ihrem bevorzugten Editor:

nano nginx-conf/nginx.conf

Fügen Sie in dieser Datei einen Serverblock mit Anweisungen für Ihren Servernamen und das Dokumentstammverzeichnis sowie Standortblöcke hinzu, um die Anfrage des Certbot-Clients nach Zertifikaten, PHP-Verarbeitung und statischen Asset-Anfragen weiterzuleiten.

Fügen Sie den folgenden Code in die Datei ein. Stellen Sie sicher, dass your_domainSie durch Ihren eigenen Domainnamen ersetzen:

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

Unser Serverblock enthält die folgenden Informationen:

Richtlinien:

  • listen: Dies weist Nginx an, auf Port zu lauschen 80, wodurch Sie das Webroot-Plugin von Certbot für Ihre Zertifikatsanforderungen verwenden können. Beachten Sie, dass Sie den Port noch nicht443 einschließen – Sie werden Ihre Konfiguration aktualisieren, um SSL einzuschließen, sobald Sie Ihre Zertifikate erfolgreich erhalten haben.
  • server_name: Dies definiert Ihren Servernamen und den Serverblock, der für Anfragen an Ihren Server verwendet werden soll. your_domainAchten Sie darauf, diese Zeile durch Ihren eigenen Domainnamen zu ersetzen .
  • index: Diese Direktive definiert die Dateien, die als Indizes verwendet werden, wenn Anfragen an Ihren Server verarbeitet werden. Sie haben hier die Standardprioritätsreihenfolge geändert und sich index.phpnach vorne bewegt index.html, damit Nginx aufgerufene Dateien nach index.phpMöglichkeit priorisiert.
  • root: Diese Direktive benennt das Root- Verzeichnis für Anfragen an Ihren Server. Dieses Verzeichnis /var/www/htmlwird zur Build-Zeit durch Anweisungen in Ihrer WordPress-Dockerfile als Mount-Punkt erstellt . Diese Dockerfile-Anweisungen stellen auch sicher, dass die Dateien aus der WordPress-Version auf diesem Volume gemountet werden.

Standortblöcke:

  • location ~ /.well-known/acme-challenge: Dieser Standortblock verarbeitet Anfragen an das .well-knownVerzeichnis, in dem Certbot eine temporäre Datei ablegt, um zu überprüfen, ob das DNS für Ihre Domäne zu Ihrem Server aufgelöst wird. Mit dieser Konfiguration können Sie das Webroot-Plugin von Certbot verwenden, um Zertifikate für Ihre Domain zu erhalten.
  • location /: In diesem Location-Block wird eine try_filesDirektive verwendet, um nach Dateien zu suchen, die mit einzelnen URI-Anforderungen übereinstimmen. Anstatt jedoch standardmäßig einen 404 Not Found -Status zurückzugeben, übergibst du die Kontrolle an die WordPress- index.phpDatei mit den Anfrageargumenten.
  • location ~ \.php$: Dieser Standortblock übernimmt die PHP-Verarbeitung und leitet diese Anfragen an Ihren wordpressContainer weiter. Da Ihr WordPress-Docker-Image auf dem php:fpmimage basiert, fügen Sie in diesem Block auch Konfigurationsoptionen ein, die für das FastCGI-Protokoll spezifisch sind. Nginx benötigt einen unabhängigen PHP-Prozessor für PHP-Anfragen. In diesem Fall werden diese Anforderungen von dem php-fpmProzessor verarbeitet, der im php:fpmImage enthalten ist. Darüber hinaus enthält dieser Standortblock FastCGI-spezifische Anweisungen, Variablen und Optionen, die Anforderungen an die in Ihrem wordpressContainer ausgeführte WordPress-Anwendung weiterleiten, den bevorzugten Index für den geparsten Anforderungs-URI festlegen und URI-Anforderungen analysieren.
  • location ~ /\.ht: Dieser Block verarbeitet .htaccessDateien, da Nginx sie nicht bereitstellt. Die deny_allDirektive stellt sicher, dass .htaccessDateien niemals Benutzern bereitgestellt werden.
  • location = /favicon.ico, location = /robots.txt: Diese Blöcke stellen sicher, dass Anfragen an /favicon.icound /robots.txtnicht protokolliert werden.
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: Dieser Block deaktiviert die Protokollierung für statische Asset-Anforderungen und stellt sicher, dass diese Assets in hohem Maße zwischengespeichert werden können, da ihre Bereitstellung normalerweise teuer ist.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind. Wenn Sie verwendet nanohaben, tun Sie dies, indem Sie CTRL+X, Y, dann drücken ENTER.

Wenn Ihre Nginx-Konfiguration vorhanden ist, können Sie mit dem Erstellen von Umgebungsvariablen fortfahren, die zur Laufzeit an Ihre Anwendungs- und Datenbankcontainer übergeben werden.

Schritt 2 – Definieren von Umgebungsvariablen

Ihre Datenbank- und WordPress-Anwendungscontainer benötigen zur Laufzeit Zugriff auf bestimmte Umgebungsvariablen, damit Ihre Anwendungsdaten bestehen bleiben und für Ihre Anwendung zugänglich sind. Diese Variablen enthalten sowohl vertrauliche als auch nicht vertrauliche Informationen: vertrauliche Werte für Ihr MySQL -Root- Passwort und den Benutzer und das Passwort der Anwendungsdatenbank sowie nicht vertrauliche Informationen für den Namen und Host Ihrer Anwendungsdatenbank.

Anstatt all diese Werte in Ihrer Docker Compose-Datei festzulegen – der Hauptdatei, die Informationen darüber enthält, wie Ihre Container ausgeführt werden – legen Sie die sensiblen Werte in einer .envDatei fest und schränken ihre Verbreitung ein. Dadurch wird verhindert, dass diese Werte in Ihre Projekt-Repositorys kopiert und öffentlich zugänglich gemacht werden.

Öffnen Sie in Ihrem Hauptprojektverzeichnis ~/wordpresseine Datei namens .env:

nano .env

Die vertraulichen Werte, die Sie in dieser Datei festlegen, umfassen ein Passwort für den MySQL -Root- Benutzer sowie einen Benutzernamen und ein Passwort, die WordPress für den Zugriff auf die Datenbank verwendet.

Fügen Sie der Datei die folgenden Variablennamen und -werte hinzu. Denken Sie daran, hier Ihre eigenen Werte für jede Variable anzugeben:

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

Enthalten sind ein Passwort für das Root- Administrationskonto sowie Ihr bevorzugter Benutzername und Ihr bevorzugtes Passwort für Ihre Anwendungsdatenbank.

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

Da Ihre .envDatei vertrauliche Informationen enthält, möchten Sie sicherstellen, dass sie in Ihren Projekten .gitignoreund .dockerignoreDateien enthalten ist. Dies teilt Git und Docker mit, welche Dateien nicht in Ihre Git-Repositories bzw. Docker-Images kopiert werden sollen.

Wenn Sie vorhaben, mit Git zur Versionskontrolle zu arbeiten, initialisieren Sie Ihr aktuelles Arbeitsverzeichnis als Repository mit git init:

git init

Erstellen und öffnen Sie dann eine .gitignoreDatei:

nano .gitignore

.envZur Datei hinzufügen :

.env

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

.envEbenso ist es eine gute Vorsichtsmaßnahme, eine Datei hinzuzufügen .dockerignore, damit sie nicht in Ihren Containern landet, wenn Sie dieses Verzeichnis als Build-Kontext verwenden.

Öffne die Datei:

nano .dockerignore

.envZur Datei hinzufügen :

.env

Darunter können Sie optional Dateien und Verzeichnisse hinzufügen, die mit der Entwicklung Ihrer Anwendung verbunden sind:

.env
.git
docker-compose.yml
.dockerignore

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

Mit Ihren sensiblen Informationen können Sie nun damit fortfahren, Ihre Dienste in einer docker-compose.ymlDatei zu definieren.

Schritt 3 – Definieren von Diensten mit Docker Compose

Ihre docker-compose.ymlDatei enthält die Dienstdefinitionen für Ihr Setup. Ein Dienst in Compose ist ein laufender Container, und Dienstdefinitionen geben Informationen darüber an, wie jeder Container ausgeführt wird.

Mit Compose können Sie verschiedene Dienste zum Ausführen von Multi-Container-Anwendungen definieren, da Compose es Ihnen ermöglicht, diese Dienste mit gemeinsam genutzten Netzwerken und Volumes zu verknüpfen. Dies ist für Ihr aktuelles Setup hilfreich, da Sie verschiedene Container für Ihre Datenbank, WordPress-Anwendung und Ihren Webserver erstellen. Sie werden auch einen Container erstellen, um den Certbot-Client auszuführen , um Zertifikate für Ihren Webserver zu erhalten.

Erstellen und öffnen Sie zunächst die docker-compose.ymlDatei:

nano docker-compose.yml

Fügen Sie den folgenden Code hinzu, um Ihre Compose-Dateiversion und Ihren dbDatenbankdienst zu definieren:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

Die dbDienstdefinition enthält die folgenden Optionen:

  • image: Dies teilt Compose mit, welches Image abgerufen werden soll, um den Container zu erstellen. Sie heften das mysql:8.0Bild hier an, um zukünftige Konflikte zu vermeiden, wenn das mysql:latestBild weiterhin aktualisiert wird. Weitere Informationen zum Anheften von Versionen und zum Vermeiden von Abhängigkeitskonflikten finden Sie in der Docker-Dokumentation zu Best Practices für Dockerfile .
  • container_name: Dies gibt einen Namen für den Container an.
  • restart: Dies definiert die Container-Neustartrichtlinie. Der Standardwert ist no, aber Sie haben den Container so eingestellt, dass er neu gestartet wird, sofern er nicht manuell gestoppt wird.
  • env_file: Diese Option teilt Compose mit, dass Sie Umgebungsvariablen aus einer Datei namens hinzufügen möchten .env, die sich in Ihrem Build-Kontext befindet. In diesem Fall ist der Build-Kontext Ihr aktuelles Verzeichnis.
  • environment: Mit dieser Option können Sie zusätzliche Umgebungsvariablen hinzufügen, die über die in Ihrer .envDatei definierten hinausgehen. Sie werden die MYSQL_DATABASEVariable gleich setzen wordpress, um einen Namen für Ihre Anwendungsdatenbank anzugeben. Da es sich um nicht vertrauliche Informationen handelt, können Sie sie direkt in die docker-compose.ymlDatei aufnehmen.
  • volumes: Hier mounten Sie ein benanntes Volume mit dem Namen dbdatades /var/lib/mysqlVerzeichnisses im Container. Dies ist das Standarddatenverzeichnis für MySQL auf den meisten Distributionen.
  • command: Diese Option gibt einen Befehl zum Überschreiben der standardmäßigen CMD-Anweisung für das Bild an. In diesem speziellen Fall fügen Sie dem Standardbefehl des Docker-Images eine Option hinzu mysqld, die den MySQL-Server auf dem Container startet. Diese Option --default-authentication-plugin=mysql_native_passwordsetzt die --default-authentication-pluginSystemvariable auf und gibt an mysql_native_password, welcher Authentifizierungsmechanismus neue Authentifizierungsanforderungen an den Server steuern soll. Da PHP und damit Ihr WordPress-Image den neueren Authentifizierungsstandard von MySQL nicht unterstützen , müssen Sie diese Anpassung vornehmen, um den Benutzer Ihrer Anwendungsdatenbank zu authentifizieren.
  • networks: Dies gibt an, dass Ihr Anwendungsdienst dem app-networkNetzwerk beitritt, das Sie am Ende der Datei definieren.

Fügen Sie als Nächstes unter Ihrer dbDienstdefinition die Definition für Ihren wordpressAnwendungsdienst hinzu:

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

In dieser Dienstdefinition benennen Sie Ihren Container und definieren eine Neustartrichtlinie, wie Sie es beim dbDienst getan haben. Sie fügen auch einige Optionen hinzu, die für diesen Container spezifisch sind:

  • depends_on: Diese Option stellt sicher, dass Ihre Container in der Reihenfolge ihrer Abhängigkeit gestartet werden, wobei der wordpressContainer nach dem Container beginnt db. Ihre WordPress-Anwendung ist auf die Existenz Ihrer Anwendungsdatenbank und Ihres Benutzers angewiesen, sodass das Ausdrücken dieser Abhängigkeitsreihenfolge Ihrer Anwendung ermöglicht, ordnungsgemäß zu starten.
  • image: Für dieses Setup verwenden Sie das 5.1.1-fpm-alpineWordPress-Image . Wie in Schritt 1 besprochen , stellt die Verwendung dieses Images sicher, dass Ihre Anwendung über den php-fpmProzessor verfügt, den Nginx für die PHP-Verarbeitung benötigt. Dies ist auch ein alpinevom Alpine Linux-Projekt abgeleitetes Bild, das dazu beitragen wird, die Gesamtbildgröße gering zu halten. Weitere Informationen zu den Vor- und Nachteilen der Verwendung von alpineBildern und dazu, ob dies für Ihre Anwendung sinnvoll ist oder nicht, finden Sie in der vollständigen Diskussion im Abschnitt „Bildvarianten“ auf der Bildseite von Docker Hub WordPress .
  • env_file: Auch hier geben Sie an, dass Sie Werte aus Ihrer Datei abrufen möchten .env, da Sie hier Ihren Anwendungsdatenbankbenutzer und Ihr Kennwort definiert haben.
  • environment: Hier verwenden Sie die Werte, die Sie in Ihrer .envDatei definiert haben, weisen sie jedoch den Variablennamen zu, die das WordPress-Image erwartet: WORDPRESS_DB_USERund WORDPRESS_DB_PASSWORD. Sie definieren auch eine WORDPRESS_DB_HOST, bei der es sich um den MySQL-Server handelt, der auf dem dbContainer ausgeführt wird, auf den über den Standardport von MySQL zugegriffen werden kann 3306. Ihr WORDPRESS_DB_NAMEwird derselbe Wert sein, den Sie in der MySQL-Dienstdefinition für Ihre MYSQL_DATABASE: angegeben haben wordpress.
  • volumes: Sie mounten ein benanntes Volume wordpressmit dem Namen des /var/www/htmlMountpoints , der vom WordPress-Image erstellt wurde . Wenn Sie ein benanntes Volume auf diese Weise verwenden, können Sie Ihren Anwendungscode mit anderen Containern teilen.
  • networks: Sie fügen den wordpressContainer auch dem app-networkNetzwerk hinzu.

Fügen Sie als Nächstes unter der wordpressAnwendungsdienstdefinition die folgende Definition für Ihren webserverNginx-Dienst hinzu:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

Hier benennen Sie Ihren Container und machen ihn wordpressin der Startreihenfolge vom Container abhängig. Sie verwenden auch ein alpineImage – das 1.15.12-alpineNginx-Image .

Diese Dienstdefinition enthält auch die folgenden Optionen:

  • ports: Dadurch wird der Port verfügbar gemacht 80, um die Konfigurationsoptionen zu aktivieren, die Sie in Ihrer nginx.confDatei in Schritt 1 definiert haben .
  • volumes: Hier definieren Sie eine Kombination aus benannten Volumes und Bind-Mounts :
    • wordpress:/var/www/html: Dadurch wird Ihr WordPress-Anwendungscode in das /var/www/htmlVerzeichnis eingebunden, das Verzeichnis, das Sie als rootin Ihrem Nginx-Serverblock festgelegt haben.
    • ./nginx-conf:/etc/nginx/conf.d: Dadurch wird das Nginx-Konfigurationsverzeichnis auf dem Host an das entsprechende Verzeichnis auf dem Container gebunden, wodurch sichergestellt wird, dass alle Änderungen, die Sie an Dateien auf dem Host vornehmen, im Container widergespiegelt werden.
    • certbot-etc:/etc/letsencrypt: Dadurch werden die relevanten Let's Encrypt-Zertifikate und -Schlüssel für Ihre Domain in das entsprechende Verzeichnis des Containers gemountet.

Sie haben diesen Container auch zum app-networkNetzwerk hinzugefügt.

Fügen Sie schließlich unter Ihrer webserverDefinition Ihre letzte Dienstdefinition für den certbotDienst hinzu. Achten Sie darauf, die hier aufgeführten E-Mail-Adressen und Domänennamen durch Ihre eigenen Informationen zu ersetzen:

certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

Diese Definition weist Compose an, das certbot/certbotImage von Docker Hub abzurufen. Es verwendet auch benannte Volumes, um Ressourcen mit dem Nginx-Container zu teilen, einschließlich der Domänenzertifikate und -eingaben certbot-etcsowie des Anwendungscodes in wordpress.

Auch hier haben Sie früher depends_onangegeben, dass der certbotContainer gestartet werden soll, sobald der webserverDienst ausgeführt wird.

Sie haben auch eine commandOption eingefügt, die einen Unterbefehl angibt, der mit dem Standardbefehl des Containers certbotausgeführt werden soll. Der certonlyUnterbefehl erhält ein Zertifikat mit den folgenden Optionen:

  • --webroot: Dies weist Certbot an, das Webroot-Plugin zu verwenden, um Dateien zur Authentifizierung im Webroot-Ordner abzulegen. Dieses Plugin hängt von der HTTP-01-Validierungsmethode ab , die eine HTTP-Anforderung verwendet, um zu beweisen, dass Certbot auf Ressourcen von einem Server zugreifen kann, der auf einen bestimmten Domänennamen antwortet.
  • --webroot-path: Dies gibt den Pfad des Webroot-Verzeichnisses an.
  • --email: Ihre bevorzugte E-Mail-Adresse für die Registrierung und Wiederherstellung.
  • --agree-tos: Dies gibt an, dass Sie der Abonnentenvereinbarung von ACME zustimmen .
  • --no-eff-email: Dies teilt Certbot mit, dass Sie Ihre E-Mail nicht mit der Electronic Frontier Foundation (EFF) teilen möchten . Sie können dies gerne weglassen, wenn Sie dies bevorzugen.
  • --staging: Dies teilt Certbot mit, dass Sie die Staging-Umgebung von Let's Encrypt verwenden möchten, um Testzertifikate zu erhalten. Mit dieser Option können Sie Ihre Konfigurationsoptionen testen und mögliche Domain-Anforderungsbeschränkungen vermeiden. Weitere Informationen zu diesen Limits finden Sie in der Dokumentation zu Ratenlimits von Let's Encrypt .
  • -d: Hiermit können Sie Domänennamen angeben, die Sie auf Ihre Anfrage anwenden möchten. In diesem Fall haben Sie your_domainund eingeschlossen www.your_domain. Achten Sie darauf, diese durch Ihre eigene Domain zu ersetzen.

Fügen Sie unterhalb der certbotService-Definition Ihre Netzwerk- und Volume-Definitionen hinzu:

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

Ihr Schlüssel der obersten Ebene volumesdefiniert die Lautstärken certbot-etc, wordpressund dbdata. Wenn Docker Volumes erstellt, wird der Inhalt des Volumes in einem Verzeichnis auf dem Host-Dateisystem gespeichert /var/lib/docker/volumes/, das von Docker verwaltet wird. Der Inhalt jedes Volumes wird dann aus diesem Verzeichnis in jeden Container gemountet, der das Volume verwendet. Auf diese Weise ist es möglich, Code und Daten zwischen Containern auszutauschen.

Das benutzerdefinierte Bridge-Netzwerk app-networkermöglicht die Kommunikation zwischen Ihren Containern, da sie sich auf demselben Docker-Daemon-Host befinden. Dies optimiert den Datenverkehr und die Kommunikation innerhalb der Anwendung, da alle Ports zwischen Containern im selben Bridge-Netzwerk geöffnet werden, ohne dass Ports der Außenwelt zugänglich gemacht werden. Daher können Ihre db, wordpress, und webserverContainer miteinander kommunizieren, und Sie müssen nur den Port 80für den Front-End-Zugriff auf die Anwendung verfügbar machen.

Das Folgende ist die docker-compose.ymlDatei in ihrer Gesamtheit:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

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

Wenn Ihre Dienstdefinitionen vorhanden sind, können Sie die Container starten und Ihre Zertifikatsanforderungen testen.

Schritt 4 – Erhalt von SSL-Zertifikaten und Anmeldeinformationen

Starten Sie Ihre Container mit dem docker-compose upBefehl, der Ihre Container in der von Ihnen angegebenen Reihenfolge erstellt und ausführt. Durch Hinzufügen des -dFlags führt der Befehl die Container db, wordpress, und webserverim Hintergrund aus:

docker-compose up -d

Die folgende Ausgabe bestätigt, dass Ihre Dienste erstellt wurden:

Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

Überprüfen docker-compose psSie mit den Status Ihrer Dienste:

docker-compose ps

Sobald dies abgeschlossen ist, werden Ihre db, wordpress, und webserver-Dienste angezeigt Upund der certbotContainer wird mit einer 0Statusmeldung beendet:

Output
  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp  

Alles andere als Upin der StateSpalte für die Dienste db, wordpress, oder webserveroder ein anderer Exit-Status als 0für den certbotContainer bedeutet, dass Sie möglicherweise die Dienstprotokolle mit dem docker-compose logsfolgenden Befehl überprüfen müssen:

docker-compose logs service_name

Sie können jetzt überprüfen, ob Ihre Zertifikate im webserverContainer gemountet wurden mit docker-compose exec:

docker-compose exec webserver ls -la /etc/letsencrypt/live

Sobald Ihre Zertifikatsanforderungen erfolgreich sind, lautet die Ausgabe:

Output
total 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain

Da Sie nun wissen, dass Ihre Anfrage erfolgreich sein wird, können Sie die Dienstdefinition bearbeiten , um das Flag certbotzu entfernen .--staging

Öffnen docker-compose.yml:

nano docker-compose.yml

Suchen Sie den Abschnitt der Datei mit der Dienstdefinition certbotund ersetzen Sie das --stagingFlag in der commandOption durch das --force-renewalFlag, das Certbot mitteilt, dass Sie ein neues Zertifikat mit denselben Domänen wie ein vorhandenes Zertifikat anfordern möchten. Das Folgende ist die certbotDienstdefinition mit dem aktualisierten Flag:

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

Sie können jetzt ausführen docker-compose up, um den Container neu zu erstellen certbot. Sie werden auch die --no-depsOption hinzufügen, um Compose mitzuteilen, dass es das Starten des webserverDienstes überspringen kann, da es bereits läuft:

docker-compose up --force-recreate --no-deps certbot

Die folgende Ausgabe zeigt an, dass Ihre Zertifikatsanforderung erfolgreich war:

Output
Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for your_domain
certbot      | http-01 challenge for www.your_domain
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0

Wenn Ihre Zertifikate vorhanden sind, können Sie mit der Änderung Ihrer Nginx-Konfiguration fortfahren, um SSL einzuschließen.

Schritt 5 – Ändern der Webserverkonfiguration und Dienstdefinition

Das Aktivieren von SSL in Ihrer Nginx-Konfiguration umfasst das Hinzufügen einer HTTP-Umleitung zu HTTPS, das Angeben Ihres SSL-Zertifikats und der Schlüsselspeicherorte sowie das Hinzufügen von Sicherheitsparametern und Headern.

Da Sie den Dienst neu erstellen webserverwerden, um diese Ergänzungen aufzunehmen, können Sie ihn jetzt stoppen:

docker-compose stop webserver

Bevor Sie die Konfigurationsdatei ändern, rufen Sie den empfohlenen Nginx-Sicherheitsparameter von Certbot ab, indem Sie Folgendes verwenden curl:

curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

Dieser Befehl speichert diese Parameter in einer Datei namens options-ssl-nginx.conf, die sich im nginx-confVerzeichnis befindet.

Entfernen Sie als Nächstes die zuvor erstellte Nginx-Konfigurationsdatei:

rm nginx-conf/nginx.conf

Erstellen und öffnen Sie eine andere Version der Datei:

nano nginx-conf/nginx.conf

Fügen Sie der Datei den folgenden Code hinzu, um HTTP zu HTTPS umzuleiten und SSL-Anmeldeinformationen, Protokolle und Sicherheitsheader hinzuzufügen. your_domainDenken Sie daran, durch Ihre eigene Domain zu ersetzen :

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

Der HTTP-Serverblock gibt das Webroot für Certbot-Erneuerungsanfragen an das .well-known/acme-challengeVerzeichnis an. Es enthält auch eine Rewrite-Direktive , die HTTP-Anforderungen an das Stammverzeichnis an HTTPS weiterleitet.

Der HTTPS-Serverblock aktiviert sslund http2. Um mehr darüber zu erfahren, wie HTTP/2 HTTP-Protokolle iteriert und welche Vorteile es für die Leistung von Websites haben kann, lesen Sie bitte die Einführung zu How To Set Up Nginx with HTTP/2 Support on Ubuntu 18.04 .

Dieser Block enthält auch Ihr SSL-Zertifikat und Schlüsselspeicherorte sowie die empfohlenen Certbot-Sicherheitsparameter, die Sie in gespeichert haben nginx-conf/options-ssl-nginx.conf.

Darüber hinaus sind einige Sicherheits-Header enthalten, die es Ihnen ermöglichen, A - Bewertungen für Dinge wie die Server-Testseiten von SSL Labs und Security Headers zu erhalten. Zu diesen Headern gehören X-Frame-Options, X-Content-Type-Options, Referrer Policy, Content-Security-Policyund X-XSS-Protection. Der HTTPStrict Transport Security (HSTS)-Header ist auskommentiert – aktivieren Sie dies nur, wenn Sie die Auswirkungen verstehen und seine „Preload“-Funktionalität bewertet haben .

Ihre rootund index-Anweisungen befinden sich ebenfalls in diesem Block, ebenso wie die restlichen WordPress-spezifischen Standortblöcke, die in Schritt 1 besprochen wurden .

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

Bevor Sie den webserverDienst neu erstellen, müssen Sie 443Ihrer Dienstdefinition eine Portzuordnung hinzufügen webserver.

Öffnen Sie Ihre docker-compose.ymlDatei:

nano docker-compose.yml

Fügen Sie in der webserverDienstdefinition die folgende Portzuordnung hinzu:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

Hier ist die vollständige docker-compose.ymlDatei nach den Änderungen:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

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

Erstellen Sie den webserverDienst neu:

docker-compose up -d --force-recreate --no-deps webserver

Überprüfen Sie Ihre Dienstleistungen mit docker-compose ps:

docker-compose ps

Die Ausgabe sollte anzeigen, dass Ihre Dienste db, wordpress, und webserverausgeführt werden:

Output
  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp    

Wenn Ihre Container ausgeführt werden, können Sie Ihre WordPress-Installation über die Weboberfläche abschließen.

Schritt 6 – Abschließen der Installation über die Webschnittstelle

Schließen Sie bei laufenden Containern die Installation über die WordPress-Weboberfläche ab.

Navigieren Sie in Ihrem Webbrowser zur Domain Ihres Servers. your_domainDenken Sie daran, durch Ihren eigenen Domainnamen zu ersetzen :

https://your_domain

Wählen Sie die Sprache aus, die Sie verwenden möchten:

WordPress-Sprachauswahl

Nachdem Sie auf Weiter geklickt haben, landen Sie auf der Haupteinrichtungsseite, wo Sie einen Namen für Ihre Website und einen Benutzernamen auswählen müssen. Es ist eine gute Idee, hier einen einprägsamen Benutzernamen (statt „admin“) und ein sicheres Passwort zu wählen. Sie können das Passwort verwenden, das WordPress automatisch generiert, oder ein eigenes erstellen.

Schließlich müssen Sie Ihre E-Mail-Adresse eingeben und entscheiden, ob Sie Suchmaschinen davon abhalten möchten, Ihre Website zu indizieren:

WordPress Haupteinrichtungsseite

Wenn Sie unten auf der Seite auf WordPress installieren klicken, gelangen Sie zu einer Anmeldeaufforderung:

WordPress-Anmeldebildschirm

Sobald Sie angemeldet sind, haben Sie Zugriff auf das WordPress-Administrations-Dashboard:

WordPress Hauptverwaltungs-Dashboard

Wenn Ihre WordPress-Installation abgeschlossen ist, können Sie Schritte unternehmen, um sicherzustellen, dass Ihre SSL-Zertifikate automatisch erneuert werden.

Schritt 7 – Erneuern von Zertifikaten

Let's Encrypt Zertifikate sind 90 Tage gültig. Sie können einen automatischen Verlängerungsprozess einrichten, um sicherzustellen, dass sie nicht verfallen. Eine Möglichkeit, dies zu tun, besteht darin, einen Job mit dem cronPlanungsdienstprogramm zu erstellen. Im folgenden Beispiel erstellen Sie einen cronJob, um regelmäßig ein Skript auszuführen, das Ihre Zertifikate erneuert und Ihre Nginx-Konfiguration neu lädt.

Öffnen Sie zuerst ein Skript mit dem Namen ssl_renew.sh:

nano ssl_renew.sh

Fügen Sie dem Skript den folgenden Code hinzu, um Ihre Zertifikate zu erneuern und Ihre Webserverkonfiguration neu zu laden. Denken Sie daran, den Beispiel-Benutzernamen hier durch Ihren eigenen Nicht -Root- Benutzernamen zu ersetzen:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

Dieses Skript weist zuerst die docker-composeBinärdatei einer Variablen namens zu COMPOSEund gibt die --no-ansiOption an, die docker-composeBefehle ohne ANSI-Steuerzeichen ausführt . Es macht dann dasselbe mit der dockerBinärdatei. Schließlich wechselt es in das ~/wordpressProjektverzeichnis und führt die folgenden docker-composeBefehle aus:

  • docker-compose run: Dadurch wird ein certbotContainer gestartet und der commandin Ihrer Dienstdefinition bereitgestellte überschrieben certbot. Anstatt den certonlyUnterbefehl zu verwenden, wird der renewUnterbefehl verwendet, der Zertifikate erneuert, die kurz vor dem Ablauf stehen. Ebenfalls enthalten ist die --dry-runOption, Ihr Skript zu testen.
  • docker-compose kill: Dies sendet ein SIGHUPSignal an den webserverContainer, um die Nginx-Konfiguration neu zu laden.

Es wird dann ausgeführt docker system prune, um alle nicht verwendeten Container und Bilder zu entfernen.

Schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind. Machen Sie es mit dem folgenden Befehl ausführbar:

chmod +x ssl_renew.sh

Öffnen Sie als Nächstes Ihre Stammdatei crontab , um das Erneuerungsskript in einem bestimmten Intervall auszuführen:

sudo crontab -e 

Wenn Sie diese Datei zum ersten Mal bearbeiten, werden Sie aufgefordert, einen Editor auszuwählen:

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

Fügen Sie ganz unten in dieser Datei die folgende Zeile hinzu:

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

Dadurch wird das Auftragsintervall auf alle fünf Minuten eingestellt, sodass Sie testen können, ob Ihre Verlängerungsanforderung wie beabsichtigt funktioniert hat oder nicht. Eine Protokolldatei, cron.log, wird erstellt, um relevante Ausgaben des Jobs aufzuzeichnen.

Prüfen Sie cron.lognach fünf Minuten, ob die Erneuerungsanfrage erfolgreich war:

tail -f /var/log/cron.log

Die folgende Ausgabe bestätigt eine erfolgreiche Verlängerung:

Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Beenden Sie es, indem CTRL+CSie in Ihr Terminal eintreten.

crontabSie können die Datei ändern , um ein tägliches Intervall festzulegen. Um das Skript beispielsweise jeden Tag mittags auszuführen, würden Sie die letzte Zeile der Datei wie folgt ändern:

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

--dry-runSie sollten die Option auch aus Ihrem ssl_renew.shSkript entfernen :

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

Ihr cronJob stellt sicher, dass Ihre Let's Encrypt-Zertifikate nicht verfallen, indem Sie sie erneuern, wenn sie berechtigt sind. Sie können die Protokollrotation auch mit dem Dienstprogramm Logrotate einrichten , um Ihre Protokolldateien zu rotieren und zu komprimieren.

Fazit

In diesem Tutorial haben Sie Docker Compose verwendet, um eine WordPress-Installation mit einem Nginx-Webserver zu erstellen. Als Teil dieses Workflows haben Sie TLS/SSL-Zertifikate für die Domain erhalten, die Sie mit Ihrer WordPress-Site verknüpfen möchten. Außerdem haben Sie einen cronJob erstellt, um diese Zertifikate bei Bedarf zu erneuern.

Quelle des Originalartikels unter https://www.digitalocean.com

#wordpress #docker 

Beata Zubek

1572946450

WordPress in Docker. Part 1: Dockerization

This entry-level guide will tell you why and how to Dockerize your WordPress projects.

#wordpress #docker #dockerization #dockerize #ci/cd

Docker Compose: How to Install WordPress on Docker using MySQL Backend

We can create a container and run it using Dockerfile. We can even run multiple container in separate ports using two Dockefiles in multiple terminals.

But when you want to create more than one container for your application, you have to create several Docker files. This adds on the load of maintaining them and is also quite time-consuming.

This blog is continuation with my previous blogwhere i showed** How to Install WordPress on Docker using MySQL Backend**

This problem is solved by **Docker Compose. **Docker compose is a tool which is used for multi-container applications in a single host.

For example in my previous blog I have to run two container : first wordpress container and second mysql container as backend.

We can run multi containers as services in the single host with the help of docker-compose.yaml.

Docker Swarm extends the concept of manage multiple containers deployed across multiple node docker cluster.

Installation

  1. Run this command to download the current stable release of Docker Compose in linux :
curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

#docker-compose #containers #docker #mysql #wordpress

田辺  明美

田辺 明美

1660778940

Docker Compose と Nginx を使用して WordPress をインストールする方法

このチュートリアルでは、Docker Compose を使用して、Nginx Web サーバーで WordPress インストールを作成する方法を示します。マルチコンテナの WordPress インストールを構築する

序章

WordPressは、 PHP処理を備えたMySQLデータベース上に構築された、無料でオープンソースのコンテンツ管理システム (CMS)です。拡張可能なプラグイン アーキテクチャとテンプレート システムのおかげで、ほとんどの管理は Web インターフェースから実行できます。これが、ブログから製品ページ、e コマース サイトに至るまで、さまざまな種類の Web サイトを作成するときに WordPress が一般的な選択肢である理由です。

通常、WordPress を実行するには、LAMP (Linux、Apache、MySQL、および PHP) または LEMP (Linux、Nginx、MySQL、および PHP) スタックをインストールする必要があり、これには時間がかかる場合があります。ただし、 DockerDocker Composeなどのツールを使用すると、好みのスタックをセットアップして WordPress をインストールするプロセスを合理化できます。個々のコンポーネントを手動でインストールする代わりに、ライブラリ、構成ファイル、環境変数などを標準化するイメージを使用できます。次に、共有オペレーティング システム上で実行される分離されたプロセスであるコンテナーでこれらのイメージを実行します。さらに、Compose を使用すると、複数のコンテナー (アプリケーションとデータベースなど) を調整して相互に通信できます。

このチュートリアルでは、複数コンテナーの WordPress インストールを構築します。コンテナーには、MySQL データベース、Nginx Web サーバー、および WordPress 自体が含まれます。また、サイトに関連付けるドメインの Let's Encryptを使用して TLS/SSL 証明書を取得することで、インストールを保護します。最後に、証明書を更新するジョブを設定してcron、ドメインの安全性を維持します。

すべての設定が完了したら、最初のステップを開始する準備が整いました。

ステップ1-Webサーバー構成の定義

コンテナーを実行する前に、まず Nginx Web サーバーの構成を定義します。構成ファイルには、WordPress 固有のロケーション ブロックがいくつか含まれ、証明書の自動更新のために Let's Encrypt 検証リクエストを Certbot クライアントに送信するロケーション ブロックも含まれます。

まず、WordPress セットアップ用のプロジェクト ディレクトリを作成します。この例では、 と呼びwordpressます。必要に応じて、このディレクトリに別の名前を付けることができます。

mkdir wordpress

次に、ディレクトリに移動します。

cd wordpress

次に、構成ファイル用のディレクトリを作成します。

mkdir nginx-conf

nanoまたはお気に入りのエディターでファイルを開きます。

nano nginx-conf/nginx.conf

このファイルに、サーバー名とドキュメント ルートのディレクティブを含むサーバー ブロックと、証明書、PHP 処理、および静的アセット要求に対する Certbot クライアントの要求を指示する場所ブロックを追加します。

次のコードをファイルに追加します。必ず独自のドメイン名に置き換えyour_domainてください。

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

サーバーブロックには次の情報が含まれています。

ディレクティブ:

  • listen: これは Nginx に port でリッスンするように指示します。これにより、証明書要求にCertbot のwebroot プラグイン80を使用できるようになります。まだポートを含めていないことに注意してください。証明書を正常に取得したら、構成を更新して SSL を含めます。443
  • server_name: これは、サーバー名と、サーバーへのリクエストに使用するサーバー ブロックを定義します。your_domainこの行を独自のドメイン名に置き換えてください。
  • index: このディレクティブは、サーバーへのリクエストを処理するときにインデックスとして使用されるファイルを定義します。ここでデフォルトの優先順位を変更し、Nginx が可能な場合に呼び出されるファイルを優先するようindex.phpに の前に移動しました。index.htmlindex.php
  • root: このディレクティブは、サーバーへのリクエストのルートディレクトリを指定します。このディレクトリ は/var/www/htmlWordPress の Dockerfileの指示により、ビルド時にマウント ポイントとして作成されます。これらの Dockerfile 手順により、WordPress リリースのファイルがこのボリュームに確実にマウントされます。

ロケーション ブロック:

  • location ~ /.well-known/acme-challenge: このロケーション ブロックは、.well-knownディレクトリへの要求を処理します。Certbot は、ドメインの DNS がサーバーに解決されることを検証するために一時ファイルを配置します。この設定を行うと、Certbot の webroot プラグインを使用してドメインの証明書を取得できるようになります。
  • location /: このロケーション ブロックでは、try_filesディレクティブを使用して、個々の URI 要求に一致するファイルをチェックします。ただし、デフォルトとして404 Not Foundステータスを返す代わりにindex.php、リクエスト引数を使用して WordPress のファイルに制御を渡します。
  • location ~ \.php$: このロケーション ブロックは PHP 処理を処理し、これらのリクエストをwordpressコンテナーにプロキシします。php:fpmWordPress Docker イメージはimageに基づくため、このブロックにはFastCGI プロトコルに固有の構成オプションも含めます。Nginx には、PHP リクエスト用の独立した PHP プロセッサが必要です。この場合、これらの要求はphp-fpm、イメージに含まれているプロセッサによって処理されphp:fpmます。さらに、このロケーション ブロックには、FastCGI 固有のディレクティブ、変数、およびオプションが含まれています。これらは、コンテナーで実行されている WordPress アプリケーションに要求をプロキシしwordpress、解析された要求 URI の優先インデックスを設定し、URI 要求を解析します。
  • location ~ /\.ht.htaccess: Nginx はファイルを提供しないため、このブロックはファイルを処理します。このdeny_allディレクティブは、.htaccessファイルがユーザーに提供されないようにします。
  • location = /favicon.icolocation = /robots.txt: これらのブロックは、へのリクエストとログに記録されないことを保証し/favicon.icoます/robots.txt
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: このブロックは、静的アセット リクエストのログ記録をオフにし、これらのアセットは通常、提供するのに費用がかかるため、高度にキャッシュ可能であることを保証します。

編集が終了したら、ファイルを保存して閉じます。を使用した場合は、 、、 の順にnano押します。CTRL+XYENTER

Nginx の構成が整ったら、実行時にアプリケーションとデータベース コンテナーに渡す環境変数の作成に進むことができます。

ステップ2-環境変数の定義

アプリケーション データを永続化し、アプリケーションからアクセスできるようにするために、データベースと WordPress アプリケーション コンテナーは、実行時に特定の環境変数にアクセスする必要があります。これらの変数には、機密情報と非機密情報の両方が含まれます。MySQLルートパスワードとアプリケーション データベースのユーザーとパスワードの機密値と、アプリケーション データベース名とホストの非機密情報です。

これらすべての値を Docker Compose ファイル (コンテナーの実行方法に関する情報を含むメイン ファイル) に設定するのではなく、機密性の高い値を.envファイルに設定し、その流通を制限します。これにより、これらの値がプロジェクト リポジトリにコピーされて公開されるのを防ぐことができます。

メイン プロジェクト ディレクトリで~/wordpress、次のファイルを開きます.env

nano .env

このファイルで設定する機密値には、MySQL rootユーザーのパスワードと、WordPress がデータベースへのアクセスに使用するユーザー名とパスワードが含まれます。

次の変数名と値をファイルに追加します。ここで、変数ごとに独自の値を指定することを忘れないでください。

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

含まれているのは、ルート管理アカウントのパスワードと、アプリケーション データベースの優先ユーザー名とパスワードです。

編集が終了したら、ファイルを保存して閉じます。

.envファイルには機密情報が含まれているため、プロジェクトの および ファイルに含まれていることを確認する必要があり.gitignoreます.dockerignore。これにより、Gitと Dockerに、それぞれ Git リポジトリと Docker イメージにコピーしないファイルが通知されます。

バージョン管理に Git を使用する予定がある場合は、現在の作業ディレクトリをリポジトリとして次のように初期化しますgit init

git init

次に、ファイルを作成して開き.gitignoreます。

nano .gitignore

ファイルに追加.envします。

.env

編集が終了したら、ファイルを保存して閉じます。

同様に、このディレクトリをビルド コンテキストとして使用しているときにコンテナーに追加.envされないように、ファイルに追加することをお勧めします。.dockerignore

ファイルを開きます。

nano .dockerignore

ファイルに追加.envします。

.env

この下に、オプションで、アプリケーションの開発に関連するファイルとディレクトリを追加できます。

.env
.git
docker-compose.yml
.dockerignore

終了したら、ファイルを保存して閉じます。

機密情報を配置したら、docker-compose.ymlファイルでのサービスの定義に進むことができます。

ステップ 3 — Docker Compose を使用したサービスの定義

ファイルdocker-compose.ymlには、セットアップのサービス定義が含まれます。Composeのサービスは実行中のコンテナーであり、サービス定義は各コンテナーの実行方法に関する情報を指定します。

Compose を使用すると、複数のコンテナー アプリケーションを実行するためにさまざまなサービスを定義できます。これは、Compose を使用すると、これらのサービスを共有ネットワークおよびボリュームとリンクできるためです。データベース、WordPress アプリケーション、および Web サーバー用に異なるコンテナーを作成するため、これは現在のセットアップに役立ちます。また、 Certbot クライアントを実行して Web サーバーの証明書を取得するためのコンテナーも作成します。

まず、docker-compose.ymlファイルを作成して開きます。

nano docker-compose.yml

次のコードを追加して、Compose ファイルのバージョンとdbデータベース サービスを定義します。

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

dbサービス定義には、次のオプションが含まれています。

  • image: これは、コンテナーを作成するためにプルするイメージを Compose に指示します。画像が更新され続けるため、将来の競合を避けるために、ここにmysql:8.0画像を固定しています。mysql:latestバージョンの固定と依存関係の競合の回避の詳細については、Dockerfile のベスト プラクティスに関する Docker ドキュメントを参照してください。
  • container_name: コンテナの名前を指定します。
  • restart: コンテナの再起動ポリシーを定義します。デフォルトは ですがno、コンテナを手動で停止しない限り再起動するように設定しています。
  • env_file.env: このオプションは、ビルド コンテキストにあるというファイルから環境変数を追加することを Compose に指示します。この場合、ビルド コンテキストは現在のディレクトリです。
  • environment: このオプションを使用すると、ファイルで定義されているもの以外に、追加の環境変数を追加でき.envます。アプリケーション データベースの名前を指定するには、MYSQL_DATABASE変数を に設定します。wordpressこれは機密情報ではないため、ファイルに直接含めることができdocker-compose.ymlます。
  • volumes: ここでは、コンテナー上のディレクトリに呼び出される名前付きボリュームをマウントしています。これは、ほとんどのディストリビューションでの MySQL の標準データ ディレクトリです。dbdata/var/lib/mysql
  • command: このオプションは、イメージのデフォルトのCMD 命令をオーバーライドするコマンドを指定します。この特定のケースでは、コンテナーで MySQL サーバーを起動するオプションを Docker イメージの標準mysqldコマンドに追加します。このオプション は、システム変数を--default-authentication-plugin=mysql_native_passwordに設定し、サーバーへの新しい認証要求を管理する認証メカニズムを指定します。PHP および WordPress イメージはMySQL の新しい認証デフォルトをサポートしないため、アプリケーション データベース ユーザーを認証するには、この調整を行う必要があります。--default-authentication-pluginmysql_native_password
  • networks: これは、アプリケーション サービスがapp-networkネットワークに参加することを指定します。これは、ファイルの下部で定義します。

次に、サービス定義の下に、アプリケーション サービスdbの定義を追加します。wordpress

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

このサービス定義では、サービスで行ったように、コンテナーに名前を付け、再起動ポリシーを定義していdbます。また、このコンテナーに固有のオプションをいくつか追加しています。

  • depends_on: このオプションを使用すると、コンテナーは依存関係の順序で開始され、wordpressコンテナーはコンテナーの後に開始さdbれます。WordPress アプリケーションは、アプリケーション データベースとユーザーの存在に依存しているため、この依存関係の順序を表現すると、アプリケーションを適切に起動できます。
  • image: このセットアップでは、5.1.1-fpm-alpineWordPress のイメージを使用しています。ステップ 1で説明したように、このイメージを使用するとphp-fpm、Nginx が PHP 処理を処理するために必要なプロセッサーがアプリケーションに確実に搭載されます。これは、 Alpine Linux プロジェクトalpineから派生したイメージでもあり、イメージ全体のサイズを抑えるのに役立ちます。イメージを使用する利点と欠点、およびこれがアプリケーションにとって意味があるかどうかの詳細については、 Docker Hub WordPress イメージ ページのイメージ バリアントセクションにある完全な説明を確認してください。alpine
  • env_file.env: ここでも、アプリケーション データベースのユーザーとパスワードを定義した場所であるため、ファイルから値を取得するように指定します。
  • environment: ここでは、.envファイルで定義した値を使用していますが、WordPress 画像が期待する変数名にそれらを割り当てています:WORDPRESS_DB_USERWORDPRESS_DB_PASSWORD. また、 を定義しています。これは、MySQL のデフォルト ポート でアクセス可能なコンテナWORDPRESS_DB_HOST上で実行される MySQL サーバーになります。Yourは、MySQL サービス定義で : に指定した値と同じになります。db3306WORDPRESS_DB_NAMEMYSQL_DATABASEwordpress
  • volumes: WordPress イメージによって作成されwordpress/var/www/htmlマウントポイントに呼び出される名前付きボリュームをマウントしています。このように名前付きボリュームを使用すると、アプリケーション コードを他のコンテナーと共有できます。
  • networkswordpress:コンテナもネットワークに追加していapp-networkます。

次に、アプリケーション サービス定義の下に、 Nginx サービスwordpressの次の定義を追加します。webserver

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

ここでは、コンテナに名前を付けてwordpress、開始順にコンテナに依存するようにしています。イメージも使用していalpineます — 1.15.12-alpineNginx image .

このサービス定義には、次のオプションも含まれています。

  • ports: これにより、手順 1でファイルに80定義した構成オプションを有効にするポートが公開されます。nginx.conf
  • volumes: ここでは、名前付きボリュームとバインド マウントの組み合わせを定義しています。
    • wordpress:/var/www/html: これにより、WordPress アプリケーション コードがNginx サーバー ブロックで/var/www/html設定したディレクトリにマウントされます。root
    • ./nginx-conf:/etc/nginx/conf.d: これにより、ホスト上の Nginx 構成ディレクトリがコンテナー上の関連するディレクトリにバインド マウントされ、ホスト上のファイルに加えた変更が確実にコンテナーに反映されます。
    • certbot-etc:/etc/letsencrypt: これにより、関連する Let's Encrypt 証明書とドメインのキーがコンテナーの適切なディレクトリにマウントされます。

このコンテナもapp-networkネットワークに追加しました。

最後に、定義の下にwebserver、サービスの最後のサービス定義を追加しますcertbot。ここに記載されている電子メール アドレスとドメイン名は、必ず自分の情報に置き換えてください。

certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

この定義は、Compose にDocker Hub からcertbot/certbotイメージをプルするように指示します。また、名前付きボリュームを使用して、Nginx コンテナーとリソースを共有します。これには、ドメイン証明書とキーが含まれcertbot-etc、アプリケーション コードが含まれwordpressます。

繰り返しになりますが、サービスが実行されたらコンテナーを開始depends_onするように指定していました。certbotwebserver

commandまた、コンテナーのデフォルト コマンドで実行するサブコマンドを指定するオプションも含めましたcertbotcertonlyサブコマンドは、次のオプションを使用して証明書を取得します。

  • --webroot: これは、Certbot に webroot プラグインを使用して、認証のために webroot フォルダーにファイルを配置するように指示します。このプラグインは、HTTP リクエストを使用して、Certbot が特定のドメイン名に応答するサーバーからリソースにアクセスできることを証明するHTTP-01 検証方法に依存しています。
  • --webroot-path: これは、webroot ディレクトリのパスを指定します。
  • --email: 登録と復旧用の優先メール。
  • --agree-tos: これは、 ACME の利用規約に同意することを示します。
  • --no-eff-email: これは、電子フロンティア財団(EFF)と電子メールを共有したくないことを Certbot に伝えます。必要に応じて、これを省略してかまいません。
  • --staging: これは、テスト証明書を取得するために Let's Encrypt のステージング環境を使用することを Certbot に伝えます。このオプションを使用すると、構成オプションをテストして、ドメイン要求の制限を回避できます。これらの制限の詳細については、Let's Encrypt のレート制限に関するドキュメントをお読みください。
  • -d: リクエストに適用するドメイン名を指定できます。この場合、 と が含まれていyour_domainますwww.your_domain。これらは必ず独自のドメインに置き換えてください。

サービス定義の下にcertbot、ネットワークとボリュームの定義を追加します。

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

最上位volumesキーは、ボリューム、、certbot-etcおよびwordpressを定義しdbdataます。Docker がボリュームを作成すると、ボリュームの内容は、/var/lib/docker/volumes/Docker によって管理されるホスト ファイルシステム上のディレクトリに格納されます。各ボリュームのコンテンツは、このディレクトリからボリュームを使用する任意のコンテナーにマウントされます。このようにして、コンテナ間でコードとデータを共有できます。

app-networkコンテナーは同じ Docker デーモン ホスト上にあるため、ユーザー定義のブリッジ ネットワークを使用すると、コンテナー間の通信が可能になります。これにより、ポートを外部に公開することなく、同じブリッジ ネットワーク上のコンテナー間のすべてのポートを開くため、アプリケーション内のトラフィックと通信が合理化されます。したがって、、、dbおよびwordpressコンテナwebserverは相互に通信でき80、アプリケーションへのフロントエンド アクセス用のポートを公開するだけで済みます。

以下はdocker-compose.ymlファイル全体です。

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

編集が終了したら、ファイルを保存して閉じます。

サービス定義が整ったら、コンテナーを開始して証明書要求をテストする準備が整います。

ステップ 4 — SSL 証明書と資格情報の取得

コマンドでコンテナを起動します。これにより、コンテナdocker-compose upが作成され、指定した順序で実行されます。-dフラグを追加すると、コマンドはdbwordpress、およびwebserverコンテナをバックグラウンドで実行します。

docker-compose up -d

次の出力は、サービスが作成されたことを確認します。

Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

を使用してdocker-compose ps、サービスのステータスを確認します。

docker-compose ps

完了するdbと、、、wordpressおよびwebserverサービスが終了しUpcertbotコンテナが終了して0ステータス メッセージが表示されます。

Output
  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp  

、、またはサービスUpState列以外、またはコンテナ以外の終了ステータスは、次のコマンドでサービス ログを確認する必要があることを意味します。dbwordpresswebserver0certbotdocker-compose logs

docker-compose logs service_name

webserver次のコマンドを使用して、証明書がコンテナーにマウントされていることを確認できますdocker-compose exec

docker-compose exec webserver ls -la /etc/letsencrypt/live

証明書のリクエストが成功すると、次のような出力が表示されます。

Output
total 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain

リクエストが成功することがわかったので、certbotサービス定義を編集して--stagingフラグを削除できます。

開くdocker-compose.yml:

nano docker-compose.yml

ファイルのcertbotサービス定義のセクションを見つけ、オプションの--stagingフラグをフラグに置き換えます。これにより、既存の証明書と同じドメインで新しい証明書を要求することを Certbot に伝えます。以下は、更新されたフラグを使用したサービス定義です。command--force-renewalcertbot

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

これで、コンテナーdocker-compose upを再作成するために実行できます。また、すでに実行されているため、サービスの開始をスキップできることを Compose に伝えるオプションcertbotも含めます。--no-depswebserver

docker-compose up --force-recreate --no-deps certbot

次の出力は、証明書の要求が成功したことを示しています。

Output
Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for your_domain
certbot      | http-01 challenge for www.your_domain
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0

証明書が整ったら、Nginx 構成を変更して SSL を含めることができます。

手順 5 — Web サーバー構成とサービス定義の変更

Nginx 構成で SSL を有効にするには、HTTP リダイレクトを HTTPS に追加し、SSL 証明書とキーの場所を指定し、セキュリティ パラメータとヘッダーを追加する必要があります。

これらの追加を含めるためにサービスを再作成するのでwebserver、ここで停止できます。

docker-compose stop webserver

構成ファイルを変更する前に、次を使用して Certbot から推奨される Nginx セキュリティ パラメータを取得しますcurl

curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

このコマンドはoptions-ssl-nginx.confnginx-confディレクトリにある というファイルにこれらのパラメータを保存します。

次に、前に作成した Nginx 構成ファイルを削除します。

rm nginx-conf/nginx.conf

別のバージョンのファイルを作成して開きます。

nano nginx-conf/nginx.conf

次のコードをファイルに追加して、HTTP を HTTPS にリダイレクトし、SSL 資格情報、プロトコル、およびセキュリティ ヘッダーを追加します。your_domain独自のドメインに置き換えることを忘れないでください:

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

HTTP サーバー ブロックは、ディレクトリへの Certbot 更新要求の webroot を指定します.well-known/acme-challenge。また、ルート ディレクトリへの HTTP 要求を HTTPS に転送するrewrite ディレクティブも含まれています。

HTTPS サーバー ブロックは、 と を有効sslにしhttp2ます。HTTP/2 が HTTP プロトコルでどのように反復するか、および Web サイトのパフォーマンスに与える利点について詳しくは、 Ubuntu 18.04 で HTTP/2 サポートを使用して Nginx をセットアップする方法の概要をお読みください。

このブロックには、SSL 証明書とキーの場所、および に保存した推奨の Certbot セキュリティ パラメータも含まれますnginx-conf/options-ssl-nginx.conf

さらに、 SSL LabsSecurity Headersサーバー テスト サイトなどでA評価を取得できるいくつかのセキュリティ ヘッダーが含まれています。これらのヘッダーには、、、、、およびが含まれます。HTTP (HSTS) ヘッダーはコメント アウトされています。この意味を理解し、その「プリロード」機能を評価した場合にのみ、これを有効にしてください。X-Frame-OptionsX-Content-Type-OptionsReferrer PolicyContent-Security-PolicyX-XSS-ProtectionStrict Transport Security

ステップ 1で説明した残りの WordPress 固有のロケーション ブロックと同様に、ディレクティブrootindexディレクティブもこのブロックに配置されます。

編集が終了したら、ファイルを保存して閉じます。

サービスを再作成する前に、サービス定義にポート マッピングをwebserver追加する必要があります。443webserver

docker-compose.ymlファイルを開きます。

nano docker-compose.yml

webserverサービス定義で、次のポート マッピングを追加します。

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

docker-compose.yml編集後の完全なファイルは次のとおりです。

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

編集が終了したら、ファイルを保存して閉じます。

サービスを再作成しwebserverます。

docker-compose up -d --force-recreate --no-deps webserver

次の方法でサービスを確認しますdocker-compose ps

docker-compose ps

出力には、、、およびサービスが実行されていることが示さdbwordpressますwebserver

Output
  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp    

コンテナーが実行されている状態で、Web インターフェースを介して WordPress のインストールを完了することができます。

ステップ6-Webインターフェースを介したインストールの完了

コンテナーが実行されている状態で、WordPress Web インターフェイスからインストールを完了します。

Web ブラウザーで、サーバーのドメインに移動します。your_domain独自のドメイン名に置き換えることを忘れないでください:

https://your_domain

使用する言語を選択してください:

WordPress 言語セレクター

[続行] をクリックすると、メインのセットアップ ページが表示されます。ここで、サイトの名前とユーザー名を選択する必要があります。ここでは、覚えやすいユーザー名 (「admin」ではなく) と強力なパスワードを選択することをお勧めします。WordPress が自動的に生成するパスワードを使用することも、独自のパスワードを作成することもできます。

最後に、メール アドレスを入力し、検索エンジンがサイトをインデックスに登録しないようにするかどうかを決定する必要があります。

WordPress メインセットアップページ

ページの下部にある[WordPress のインストール] をクリックすると、ログイン プロンプトが表示されます。

WordPressログイン画面

ログインすると、WordPress 管理ダッシュボードにアクセスできます。

WordPress メイン管理ダッシュボード

WordPress のインストールが完了したら、SSL 証明書が自動的に更新されるようにするための手順を実行できます。

ステップ7-証明書の更新

Let's Encrypt の証明書は 90 日間有効です。自動更新プロセスを設定して、失効しないようにすることができます。cronこれを行う 1 つの方法は、スケジューリング ユーティリティでジョブを作成することです。次の例ではcron、証明書を更新して Nginx 構成をリロードするスクリプトを定期的に実行するジョブを作成します。

まず、次のスクリプトを開きますssl_renew.sh

nano ssl_renew.sh

次のコードをスクリプトに追加して、証明書を更新し、Web サーバー構成をリロードします。ここにあるユーザー名の例を、 root以外の独自のユーザー名に置き換えることを忘れないでください。

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

このスクリプトは、最初にdocker-composeバイナリを という変数に割り当て、オプションCOMPOSEを指定します。これにより、 ANSI 制御文字なしでコマンドが実行されます。次に、バイナリで同じことを行います。最後に、プロジェクト ディレクトリに移動し、次のコマンドを実行します。--no-ansidocker-composedocker~/wordpressdocker-compose

  • docker-compose run: これにより、certbotコンテナーが開始され、サービス定義で指定された がオーバーライドcommandされます。サブコマンドcertbotを使用する代わりに、有効期限が近づいている証明書を更新するサブコマンドが使用されます。また、スクリプトをテストするオプションも含まれています。certonlyrenew--dry-run
  • docker-compose kill: これにより、コンテナーにSIGHUPシグナルwebserverが送信され、Nginx 構成がリロードされます。

docker system pruneその後、未使用のコンテナーとイメージをすべて削除するために実行されます。

編集が終了したら、ファイルを閉じます。次のコマンドで実行可能にします。

chmod +x ssl_renew.sh

次に、ルート crontabファイルを開いて、指定した間隔で更新スクリプトを実行します。

sudo crontab -e 

このファイルを初めて編集する場合は、エディターを選択するよう求められます。

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

このファイルの一番下に、次の行を追加します。

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

これにより、ジョブの間隔が 5 分ごとに設定されるため、更新リクエストが意図したとおりに機能したかどうかをテストできます。cron.logジョブからの関連する出力を記録するために、ログ ファイルが作成されます。

5 分後cron.log、更新リクエストが成功したかどうかを確認します。

tail -f /var/log/cron.log

次の出力は、正常な更新を確認します。

Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

端末に入力CTRL+Cして終了します。

ファイルを変更してcrontab、毎日の間隔を設定できます。たとえば、スクリプトを毎日正午に実行するには、ファイルの最後の行を次のように変更します。

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

スクリプト--dry-runからオプションを削除することもできます。ssl_renew.sh

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

あなたのcron仕事は、Let's Encrypt 証明書が資格があるときに更新することで、証明書が失効しないようにします。Logrotate ユーティリティを使用してログ ローテーションをセットアップし、ログ ファイルをローテーションおよび圧縮することもできます。

結論

このチュートリアルでは、Docker Compose を使用して、Nginx Web サーバーで WordPress インストールを作成しました。このワークフローの一環として、WordPress サイトに関連付けるドメインの TLS/SSL 証明書を取得しました。さらに、cron必要に応じてこれらの証明書を更新するジョブを作成しました。

元の記事のソース: https://www.digitalocean.com

#wordpress #docker #nginx

كيفية تثبيت WordPress باستخدام Docker Compose و Nginx

يوضح هذا البرنامج التعليمي كيفية استخدام Docker Compose لإنشاء تثبيت WordPress باستخدام خادم ويب Nginx. بناء تثبيت WordPress متعدد الحاويات

مقدمة

WordPress هو نظام إدارة محتوى مجاني ومفتوح المصدر (CMS) مبني على قاعدة بيانات MySQL مع معالجة PHP . بفضل بنية البرنامج المساعد الموسعة ونظام القوالب ، يمكن إجراء معظم إدارته من خلال واجهة الويب. هذا هو سبب كون WordPress خيارًا شائعًا عند إنشاء أنواع مختلفة من مواقع الويب ، من المدونات إلى صفحات المنتجات إلى مواقع التجارة الإلكترونية.

يتضمن تشغيل WordPress عادةً تثبيت حزمة LAMP (Linux و Apache و MySQL و PHP) أو حزمة LEMP (Linux و Nginx و MySQL و PHP) ، والتي قد تستغرق وقتًا طويلاً. ومع ذلك ، باستخدام أدوات مثل Docker و Docker Compose ، يمكنك تبسيط عملية إعداد المكدس المفضل لديك وتثبيت WordPress. بدلاً من تثبيت المكونات الفردية يدويًا ، يمكنك استخدام الصور التي توحد أشياء مثل المكتبات وملفات التكوين ومتغيرات البيئة. بعد ذلك ، قم بتشغيل هذه الصور في حاويات ، عمليات معزولة تعمل على نظام تشغيل مشترك. بالإضافة إلى ذلك ، باستخدام Compose ، يمكنك التنسيق بين عدة حاويات - على سبيل المثال ، تطبيق وقاعدة بيانات - للتواصل مع بعضها البعض.

في هذا البرنامج التعليمي ، ستقوم بإنشاء تثبيت WordPress متعدد الحاويات. ستتضمن حاوياتك قاعدة بيانات MySQL وخادم ويب Nginx و WordPress نفسه. ستقوم أيضًا بتأمين التثبيت الخاص بك عن طريق الحصول على شهادات TLS / SSL باستخدام Let's Encrypt للمجال الذي تريد ربطه بموقعك. أخيرًا ، ستقوم بإعداد cronوظيفة لتجديد شهاداتك بحيث يظل نطاقك آمنًا.

بمجرد الانتهاء من إعداد كل شيء ، تكون جاهزًا لبدء الخطوة الأولى.

الخطوة 1 - تحديد تكوين خادم الويب

قبل تشغيل أي حاويات ، فإن خطوتك الأولى هي تحديد التكوين لخادم الويب Nginx الخاص بك. سيتضمن ملف التكوين الخاص بك بعض كتل المواقع الخاصة بـ WordPress ، جنبًا إلى جنب مع كتلة الموقع لتوجيه طلبات التحقق من Let's Encrypt إلى عميل Certbot لتجديد الشهادة تلقائيًا.

أولاً ، قم بإنشاء دليل مشروع لإعداد WordPress الخاص بك. في هذا المثال ، يطلق عليه wordpress. يمكنك تسمية هذا الدليل بشكل مختلف إذا كنت ترغب في:

mkdir wordpress

ثم انتقل إلى الدليل:

cd wordpress

بعد ذلك ، قم بعمل دليل لملف التكوين:

mkdir nginx-conf

افتح الملف باستخدام nanoأو المحرر المفضل لديك:

nano nginx-conf/nginx.conf

في هذا الملف ، أضف كتلة خادم مع توجيهات لاسم الخادم وجذر المستند ، وكتل الموقع لتوجيه طلب عميل Certbot للحصول على الشهادات ومعالجة PHP وطلبات الأصول الثابتة.

أضف التعليمات البرمجية التالية إلى الملف. تأكد من استبدال your_domainاسم المجال الخاص بك:

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

يتضمن حظر الخادم الخاص بنا المعلومات التالية:

التوجيهات:

  • listen: هذا يخبر Nginx بالاستماع على المنفذ 80، مما سيسمح لك باستخدام المكون الإضافي webroot الخاص بـ Certbot لطلبات الشهادة الخاصة بك. لاحظ أنك لم تقم بتضمين المنفذ 443حتى الآن - سوف تقوم بتحديث التكوين الخاص بك لتضمين SSL بمجرد حصولك على شهاداتك بنجاح.
  • server_name: هذا يحدد اسم الخادم الخاص بك وكتلة الخادم التي يجب استخدامها للطلبات إلى الخادم الخاص بك. تأكد من استبدال your_domainاسم المجال الخاص بك في هذا السطر.
  • index: يحدد هذا التوجيه الملفات التي سيتم استخدامها كفهارس عند معالجة الطلبات إلى الخادم الخاص بك. لقد قمت بتعديل الترتيب الافتراضي للأولوية هنا ، فانتقل index.phpإلى الأمام index.htmlبحيث يعطي Nginx الأولوية للملفات التي يتم استدعاؤها index.phpعندما يكون ذلك ممكنًا.
  • root: يقوم هذا التوجيه بتسمية الدليل الجذر للطلبات إلى الخادم الخاص بك. /var/www/htmlيتم إنشاء هذا الدليل كنقطة تحميل في وقت الإنشاء عن طريق التعليمات الموجودة في ملف WordPress Dockerfile الخاص بك . تضمن إرشادات Dockerfile هذه أيضًا تحميل الملفات من إصدار WordPress على هذا المجلد.

كتل الموقع:

  • location ~ /.well-known/acme-challenge: ستتعامل كتلة الموقع هذه مع الطلبات إلى .well-knownالدليل ، حيث سيضع Certbot ملفًا مؤقتًا للتحقق من أن DNS لمجالك يحل إلى الخادم الخاص بك. باستخدام هذا التكوين ، ستتمكن من استخدام المكون الإضافي webroot الخاص بـ Certbot للحصول على شهادات لمجالك.
  • location /: في كتلة الموقع هذه ، try_filesيتم استخدام توجيه للتحقق من الملفات التي تطابق طلبات URI الفردية. بدلاً من إرجاع الحالة 404 Not Found كإعداد افتراضي ، ومع ذلك ، ستمرر التحكم إلى index.phpملف WordPress باستخدام وسيطات الطلب.
  • location ~ \.php$: ستتعامل كتلة الموقع هذه مع معالجة PHP وتوكيل هذه الطلبات إلى wordpressالحاوية الخاصة بك. نظرًا لأن صورة WordPress Docker الخاصة بك ستستند إلى php:fpmالصورة ، فسوف تقوم أيضًا بتضمين خيارات التكوين الخاصة ببروتوكول FastCGI في هذه الكتلة. يتطلب Nginx معالج PHP مستقل لطلبات PHP. في هذه الحالة ، سيتم التعامل مع هذه الطلبات بواسطة php-fpmالمعالج المضمن في php:fpmالصورة. بالإضافة إلى ذلك ، تشتمل كتلة الموقع هذه على توجيهات ومتغيرات وخيارات خاصة بـ FastCGI والتي من شأنها أن تؤدي إلى طلبات وكيل لتطبيق WordPress قيد التشغيل في wordpressالحاوية الخاصة بك ، وتعيين الفهرس المفضل لمعرف URI للطلب الذي تم تحليله ، وتحليل طلبات URI.
  • location ~ /\.ht: ستتعامل هذه الكتلة مع .htaccessالملفات لأن Nginx لن يخدمها. يضمن deny_allالتوجيه عدم .htaccessتقديم الملفات للمستخدمين أبدًا.
  • location = /favicon.ico، location = /robots.txt: هذه الكتل تضمن أن الطلبات إلى /favicon.icoولن /robots.txtيتم تسجيلها.
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: يعمل هذا الحظر على إيقاف التسجيل لطلبات الأصول الثابتة ويضمن أن تكون هذه الأصول قابلة للتخزين المؤقت بدرجة عالية ، نظرًا لأن عرضها باهظ التكلفة عادةً.

احفظ وأغلق الملف عند الانتهاء من التحرير. إذا استخدمت nano، فافعل ذلك بالضغط على CTRL+X، Yثم ENTER.

مع ضبط Nginx الخاص بك ، يمكنك الانتقال إلى إنشاء متغيرات البيئة لتمريرها إلى التطبيق وحاويات قاعدة البيانات في وقت التشغيل.

الخطوة 2 - تحديد متغيرات البيئة

ستحتاج قاعدة بياناتك وحاويات تطبيق WordPress إلى الوصول إلى متغيرات بيئة معينة في وقت التشغيل حتى تستمر بيانات التطبيق الخاصة بك ويمكن الوصول إليها من خلال تطبيقك. تتضمن هذه المتغيرات معلومات حساسة وغير حساسة: قيم حساسة لكلمة مرور جذر MySQL ومستخدم وكلمة مرور قاعدة بيانات التطبيق ، ومعلومات غير حساسة لاسم قاعدة بيانات التطبيق والمضيف.

بدلاً من تعيين كل هذه القيم في ملف Docker Compose الخاص بك - الملف الرئيسي الذي يحتوي على معلومات حول كيفية تشغيل الحاويات الخاصة بك - قم بتعيين القيم الحساسة في .envملف وتقييد تداوله. سيمنع هذا نسخ هذه القيم إلى مستودعات مشروعك وكشفها للجمهور.

في دليل المشروع الرئيسي ~/wordpress، افتح ملفًا يسمى .env:

nano .env

تتضمن القيم السرية التي قمت بتعيينها في هذا الملف كلمة مرور لمستخدم جذر MySQL ، واسم مستخدم وكلمة مرور يستخدمهما WordPress للوصول إلى قاعدة البيانات.

أضف أسماء المتغيرات والقيم التالية إلى الملف. تذكر تقديم القيم الخاصة بك هنا لكل متغير:

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

تم تضمين كلمة مرور لحساب المسؤول الرئيسي ، بالإضافة إلى اسم المستخدم وكلمة المرور المفضلين لديك لقاعدة بيانات التطبيق.

احفظ وأغلق الملف عند الانتهاء من التحرير.

نظرًا لأن ملفك .envيحتوي على معلومات حساسة ، فأنت تريد التأكد من تضمينها في مشروعك وملفاتك .gitignore. .dockerignoreيخبر هذا Git و Docker بالملفات التي لا يجب نسخها إلى مستودعات Git وصور Docker ، على التوالي.

إذا كنت تخطط للعمل مع Git للتحكم في الإصدار ، فقم بتهيئة دليل العمل الحالي كمستودع باستخدام git init:

git init

ثم أنشئ .gitignoreملفًا وافتحه:

nano .gitignore

أضف .envإلى الملف:

.env

احفظ وأغلق الملف عند الانتهاء من التحرير.

.envوبالمثل ، يُعد إضافة إلى ملف إجراء احترازيًا جيدًا .dockerignore، بحيث لا ينتهي به الأمر في حاوياتك عندما تستخدم هذا الدليل كسياق للبناء.

افتح الملف:

nano .dockerignore

أضف .envإلى الملف:

.env

أدناه ، يمكنك اختياريًا إضافة ملفات وأدلة مرتبطة بتطوير تطبيقك:

.env
.git
docker-compose.yml
.dockerignore

احفظ وأغلق الملف عند الانتهاء.

مع وجود معلوماتك الحساسة في مكانها الصحيح ، يمكنك الآن الانتقال إلى تحديد خدماتك في docker-compose.ymlملف.

الخطوة 3 - تحديد الخدمات باستخدام Docker Compose

docker-compose.ymlسيحتوي ملفك على تعريفات الخدمة للإعداد الخاص بك. الخدمة في Compose عبارة عن حاوية قيد التشغيل ، وتحدد تعريفات الخدمة معلومات حول كيفية تشغيل كل حاوية.

باستخدام Compose ، يمكنك تحديد خدمات مختلفة لتشغيل تطبيقات متعددة الحاويات لأن Compose يسمح لك بربط هذه الخدمات مع الشبكات والأحجام المشتركة. سيكون هذا مفيدًا لإعدادك الحالي نظرًا لأنك ستنشئ حاويات مختلفة لقاعدة البيانات الخاصة بك وتطبيق WordPress وخادم الويب. ستقوم أيضًا بإنشاء حاوية لتشغيل عميل Certbot للحصول على شهادات لخادم الويب الخاص بك.

للبدء ، أنشئ docker-compose.ymlالملف وافتحه:

nano docker-compose.yml

أضف الكود التالي لتحديد إصدار ملف Compose dbوخدمة قاعدة البيانات:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

يحتوي dbتعريف الخدمة على الخيارات التالية:

  • image: هذا يخبر إنشاء الصورة المراد سحبها لإنشاء الحاوية. أنت تقوم بتثبيت mysql:8.0الصورة هنا لتجنب التعارضات المستقبلية حيث mysql:latestيستمر تحديث الصورة. لمزيد من المعلومات حول تثبيت الإصدار وتجنب تعارضات التبعية ، اقرأ وثائق Docker على أفضل ممارسات Dockerfile .
  • container_name: هذا يحدد اسم الحاوية.
  • restart: هذا يحدد سياسة إعادة تشغيل الحاوية. الإعداد الافتراضي هو no، ولكنك قمت بتعيين الحاوية لإعادة التشغيل ما لم يتم إيقافها يدويًا.
  • env_file: يخبر هذا الخيار إنشاء أنك تريد إضافة متغيرات البيئة من ملف يسمى .env، موجود في سياق البناء الخاص بك. في هذه الحالة ، يكون سياق البناء هو دليلك الحالي.
  • environment: يتيح لك هذا الخيار إضافة متغيرات بيئة إضافية ، بخلاف تلك المحددة في ملفك .env. ستقوم بتعيين MYSQL_DATABASEالمتغير على قدم المساواة wordpressلتوفير اسم لقاعدة بيانات التطبيق الخاص بك. نظرًا لأن هذه المعلومات غير حساسة ، يمكنك تضمينها مباشرةً في docker-compose.ymlالملف.
  • volumes: هنا ، تقوم بتركيب مجلد مسمى يسمى dbdataبالدليل /var/lib/mysqlالموجود على الحاوية. هذا هو دليل البيانات القياسي لـ MySQL في معظم التوزيعات.
  • command: يحدد هذا الخيار أمرًا لتجاوز تعليمات CMD الافتراضية للصورة. في هذه الحالة بالذات ، ستضيف خيارًا إلى mysqldالأمر القياسي لصورة Docker ، والذي يبدأ خادم MySQL في الحاوية. يقوم هذا الخيار --default-authentication-plugin=mysql_native_passwordبتعيين --default-authentication-pluginمتغير النظام إلى mysql_native_password، مع تحديد آلية المصادقة التي يجب أن تحكم طلبات المصادقة الجديدة إلى الخادم. نظرًا لأن PHP وبالتالي صورة WordPress الخاصة بك لن تدعم الإعداد الافتراضي للمصادقة الأحدث لـ MySQL ، يجب عليك إجراء هذا التعديل من أجل مصادقة مستخدم قاعدة بيانات التطبيق الخاص بك.
  • networks: هذا يحدد أن خدمة التطبيق الخاص بك ستنضم إلى app-networkالشبكة ، والتي ستحددها في أسفل الملف.

بعد ذلك ، أسفل dbتعريف خدمتك ، أضف تعريف wordpressخدمة التطبيق الخاص بك:

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

في تعريف الخدمة هذا ، تقوم بتسمية الحاوية الخاصة بك وتحديد سياسة إعادة التشغيل ، كما فعلت مع dbالخدمة. أنت تضيف أيضًا بعض الخيارات الخاصة بهذه الحاوية:

  • depends_on: يضمن هذا الخيار أن الحاويات الخاصة بك ستبدأ بترتيب التبعية ، مع wordpressبدء الحاوية بعد dbالحاوية. يعتمد تطبيق WordPress الخاص بك على وجود قاعدة بيانات التطبيق والمستخدم ، لذا فإن التعبير عن ترتيب التبعية هذا سيمكن تطبيقك من البدء بشكل صحيح.
  • image: بالنسبة لهذا الإعداد ، أنت تستخدم 5.1.1-fpm-alpineصورة WordPress . كما تمت مناقشته في الخطوة 1 ، يضمن استخدام هذه الصورة أن يحتوي تطبيقك على php-fpmالمعالج الذي يتطلبه Nginx للتعامل مع معالجة PHP. هذه أيضًا alpineصورة مشتقة من مشروع Alpine Linux ، والتي ستساعد في تقليل حجم الصورة الإجمالي. لمزيد من المعلومات حول مزايا وعيوب استخدام alpineالصور وما إذا كان هذا مفيدًا لتطبيقك أم لا ، راجع المناقشة الكاملة ضمن قسم متغيرات الصور في صفحة صورة Docker Hub WordPress .
  • env_file: مرة أخرى ، تحدد أنك تريد سحب القيم من ملفك .env، لأن هذا هو المكان الذي حددت فيه مستخدم قاعدة بيانات التطبيق وكلمة المرور.
  • environment: هنا ، أنت تستخدم القيم التي حددتها في ملفك .env، لكنك تقوم بتعيينها لأسماء المتغيرات التي تتوقعها صورة WordPress: WORDPRESS_DB_USERو WORDPRESS_DB_PASSWORD. أنت تقوم أيضًا بتعريف WORDPRESS_DB_HOST، والذي سيكون خادم MySQL الذي يعمل على dbالحاوية التي يمكن الوصول إليها على المنفذ الافتراضي لـ MySQL ، 3306. WORDPRESS_DB_NAMEستكون القيمة نفسها التي حددتها في تعريف خدمة MySQL MYSQL_DATABASEلـ :.wordpress
  • volumes: أنت تقوم بتركيب وحدة تخزين مسماة تسمى wordpressنقطة /var/www/htmlالتحميل التي تم إنشاؤها بواسطة صورة WordPress . سيسمح لك استخدام حجم مسمى بهذه الطريقة بمشاركة رمز التطبيق الخاص بك مع الحاويات الأخرى.
  • networks: أنت تقوم أيضًا بإضافة wordpressالحاوية إلى app-networkالشبكة.

بعد ذلك ، أسفل wordpressتعريف خدمة التطبيق ، أضف التعريف التالي لخدمة webserverNginx:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

هنا ، تقوم بتسمية الحاوية الخاصة بك وتجعلها تعتمد على wordpressالحاوية في ترتيب البداية. أنت تستخدم أيضًا alpineصورة - 1.15.12-alpineصورة Nginx .

يتضمن تعريف الخدمة هذا أيضًا الخيارات التالية:

  • ports: يعرض هذا المنفذ 80لتمكين خيارات التكوين التي حددتها في ملفك nginx.confفي الخطوة 1 .
  • volumes: هنا ، أنت تحدد مجموعة من الأحجام المسماة وحوامل الربط :
    • wordpress:/var/www/html: سيؤدي هذا إلى تحميل رمز تطبيق WordPress الخاص بك إلى /var/www/htmlالدليل ، الدليل الذي قمت بتعيينه على أنه rootفي كتلة خادم Nginx.
    • ./nginx-conf:/etc/nginx/conf.d: سيؤدي هذا إلى ربط دليل تكوين Nginx على المضيف بالدليل ذي الصلة في الحاوية ، مما يضمن أن أي تغييرات تجريها على الملفات الموجودة على المضيف ستنعكس في الحاوية.
    • certbot-etc:/etc/letsencrypt: سيؤدي هذا إلى تحميل الشهادات والمفاتيح ذات الصلة Let's Encrypt للمجال الخاص بك إلى الدليل المناسب في الحاوية.

لقد أضفت أيضًا هذه الحاوية إلى app-networkالشبكة.

أخيرًا ، أسفل webserverالتعريف الخاص بك ، أضف تعريف الخدمة الأخير certbotللخدمة. تأكد من استبدال عنوان البريد الإلكتروني وأسماء المجالات المدرجة هنا بمعلوماتك الخاصة:

certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

يخبر هذا التعريف Compose بسحب certbot/certbotالصورة من Docker Hub. كما يستخدم أيضًا وحدات تخزين مسماة لمشاركة الموارد مع حاوية Nginx ، بما في ذلك شهادات المجال والمفتاح certbot-etcوكود التطبيق wordpress.

مرة أخرى ، لقد اعتدت depends_onعلى تحديد أن certbotالحاوية يجب أن تبدأ بمجرد تشغيل webserverالخدمة.

لقد قمت أيضًا بتضمين commandخيار يحدد أمرًا فرعيًا ليتم تشغيله باستخدام certbotالأمر الافتراضي للحاوية. سيحصل الأمر certonlyالفرعي على شهادة بالخيارات التالية:

  • --webroot: هذا يخبر Certbot أن يستخدم المكون الإضافي webroot لوضع الملفات في مجلد webroot للمصادقة. يعتمد هذا المكون الإضافي على طريقة التحقق من HTTP-01 ، والتي تستخدم طلب HTTP لإثبات أن Certbot يمكنه الوصول إلى الموارد من خادم يستجيب لاسم مجال معين.
  • --webroot-path: هذا يحدد مسار دليل webroot.
  • --email: بريدك الإلكتروني المفضل للتسجيل والاسترداد.
  • --agree-tos: يشير هذا إلى موافقتك على اتفاقية المشتركين لدى عربكو .
  • --no-eff-email: هذا يخبر Certbot أنك لا ترغب في مشاركة بريدك الإلكتروني مع Electronic Frontier Foundation (EFF). لا تتردد في حذف هذا إذا كنت تفضل ذلك.
  • --staging: هذا يخبر Certbot أنك ترغب في استخدام بيئة تشغيل Let's Encrypt للحصول على شهادات اختبار. يتيح لك استخدام هذا الخيار اختبار خيارات التكوين الخاصة بك وتجنب حدود طلب النطاق المحتملة. لمزيد من المعلومات حول هذه الحدود ، يرجى قراءة وثائق حدود معدلات Let's Encrypt .
  • -d: هذا يسمح لك بتحديد أسماء النطاقات التي ترغب في تطبيقها على طلبك. في هذه الحالة ، قمت بتضمين your_domainو www.your_domain. تأكد من استبدالها بالمجال الخاص بك.

أسفل certbotتعريف الخدمة ، أضف تعريفات الشبكة ووحدة التخزين:

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

volumesيحدد مفتاح المستوى الأعلى الأحجام certbot-etcو wordpressو dbdata. عندما يقوم Docker بإنشاء وحدات تخزين ، يتم تخزين محتويات المجلد في دليل على نظام الملفات المضيف /var/lib/docker/volumes/، والذي يديره Docker. ثم يتم تحميل محتويات كل مجلد من هذا الدليل إلى أي حاوية تستخدم المجلد. بهذه الطريقة ، يمكن مشاركة التعليمات البرمجية والبيانات بين الحاويات.

تتيح شبكة الجسر المعرفة من قبل المستخدم app-networkالاتصال بين الحاويات الخاصة بك لأنها على نفس مضيف Docker daemon. يعمل هذا على تبسيط حركة المرور والاتصال داخل التطبيق ، حيث يفتح جميع المنافذ بين الحاويات على نفس شبكة الجسر دون تعريض أي منافذ للعالم الخارجي. وبالتالي ، dbيمكن لـ wordpressو و webserverحاويات الاتصال ببعضها البعض ، وتحتاج فقط إلى كشف المنفذ 80للوصول إلى الواجهة الأمامية للتطبيق.

ما يلي هو docker-compose.ymlملف كامل:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

احفظ وأغلق الملف عند الانتهاء من التحرير.

مع وجود تعريفات الخدمة الخاصة بك في مكانها الصحيح ، فأنت على استعداد لبدء الحاويات واختبار طلبات الشهادة الخاصة بك.

الخطوة 4 - الحصول على شهادات وبيانات اعتماد SSL

ابدأ حاوياتك docker-compose upبالأمر ، الذي سينشئ الحاويات ويشغلها بالترتيب الذي حددته. بإضافة -dالعلم ، سيقوم الأمر بتشغيل db، wordpressوالحاويات webserverفي الخلفية:

docker-compose up -d

يؤكد الإخراج التالي أنه تم إنشاء خدماتك:

Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

باستخدام docker-compose ps، تحقق من حالة خدماتك:

docker-compose ps

بمجرد الانتهاء ، ستكون خدماتك db، wordpressو ، وستكون الحاوية قد خرجت برسالة الحالة:webserverUpcertbot0

Output
  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp  

أي شيء بخلاف Upالعمود Stateالخاص بـ db، wordpressأو الخدمات ، أو حالة webserverالخروج بخلاف الحاوية يعني أنك قد تحتاج إلى التحقق من سجلات الخدمة باستخدام الأمر:0certbotdocker-compose logs

docker-compose logs service_name

يمكنك الآن التحقق من أن شهاداتك قد تم تثبيتها في webserverالحاوية باستخدام docker-compose exec:

docker-compose exec webserver ls -la /etc/letsencrypt/live

بمجرد نجاح طلبات الشهادة الخاصة بك ، يكون ما يلي هو الإخراج:

Output
total 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain

الآن بعد أن عرفت أن طلبك سينجح ، يمكنك تعديل certbotتعريف الخدمة لإزالة --stagingالعلامة.

فتح docker-compose.yml:

nano docker-compose.yml

ابحث عن قسم الملف الذي يحتوي على certbotتعريف الخدمة ، واستبدل --stagingالعلامة في commandالخيار --force-renewalبالعلامة ، والتي ستخبر Certbot أنك تريد طلب شهادة جديدة بنفس المجالات مثل الشهادة الحالية. فيما يلي certbotتعريف الخدمة بالعلامة المحدثة:

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

يمكنك الآن الجري docker-compose upلإعادة إنشاء certbotالحاوية. ستقوم أيضًا بتضمين --no-depsالخيار لإخبار Compose أنه يمكنه تخطي بدء webserverالخدمة ، نظرًا لأنه قيد التشغيل بالفعل:

docker-compose up --force-recreate --no-deps certbot

يشير الإخراج التالي إلى نجاح طلب الشهادة الخاص بك:

Output
Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for your_domain
certbot      | http-01 challenge for www.your_domain
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0

مع وجود شهاداتك في مكانها الصحيح ، يمكنك الانتقال إلى تعديل تكوين Nginx لتضمين SSL.

الخطوة 5 - تعديل تكوين خادم الويب وتعريف الخدمة

سيتضمن تمكين SSL في تكوين Nginx إضافة إعادة توجيه HTTP إلى HTTPS ، وتحديد شهادة SSL والمواقع الرئيسية ، وإضافة معلمات الأمان والعناوين.

نظرًا لأنك ستعيد إنشاء webserverالخدمة لتشمل هذه الإضافات ، يمكنك إيقافها الآن:

docker-compose stop webserver

قبل تعديل ملف التكوين ، احصل على معلمة أمان Nginx الموصى بها من Certbot باستخدام curl:

curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

سيحفظ هذا الأمر هذه المعلمات في ملف يسمى options-ssl-nginx.conf، موجود في nginx-confالدليل.

بعد ذلك ، قم بإزالة ملف تكوين Nginx الذي قمت بإنشائه مسبقًا:

rm nginx-conf/nginx.conf

قم بإنشاء وفتح نسخة أخرى من الملف:

nano nginx-conf/nginx.conf

أضف التعليمات البرمجية التالية إلى الملف لإعادة توجيه HTTP إلى HTTPS ولإضافة بيانات اعتماد SSL والبروتوكولات ورؤوس الأمان. تذكر أن تستبدل your_domainالمجال الخاص بك:

server {
        listen 80;
        listen [::]:80;

        server_name your_domain www.your_domain;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

تحدد كتلة خادم HTTP جذر الويب لطلبات تجديد Certbot إلى .well-known/acme-challengeالدليل. يتضمن أيضًا توجيهًا لإعادة الكتابة يوجه طلبات HTTP إلى الدليل الجذر إلى HTTPS.

تعمل كتلة خادم HTTPS على تمكين sslو http2. لقراءة المزيد حول كيفية تكرار HTTP / 2 على بروتوكولات HTTP والفوائد التي يمكن أن توفرها لأداء موقع الويب ، يرجى قراءة مقدمة كيفية إعداد Nginx مع دعم HTTP / 2 على Ubuntu 18.04 .

يتضمن هذا الحظر أيضًا شهادة SSL الخاصة بك والمواقع الرئيسية ، جنبًا إلى جنب مع معلمات أمان Certbot الموصى بها التي قمت بحفظها nginx-conf/options-ssl-nginx.conf.

بالإضافة إلى ذلك ، تم تضمين بعض رؤوس الأمان التي ستمكنك من الحصول على تصنيفات A على أشياء مثل SSL Labs ومواقع اختبار خادم Security Headers . تتضمن هذه الرؤوس X-Frame-Optionsو X-Content-Type-Optionsو Referrer Policyو Content-Security-Policyو X-XSS-Protection. تم التعليق على رأس HTTPStrict Transport Security (HSTS) - قم بتمكين هذا فقط إذا فهمت الآثار وقمت بتقييم وظيفة "التحميل المسبق" الخاصة به .

توجد أيضًا توجيهاتك وتوجيهاتك في هذه الكتلة ، وكذلك باقي كتل الموقع الخاصة بـ WordPress التي تمت مناقشتها في rootالخطوة 1 .index

بمجرد الانتهاء من التحرير ، احفظ الملف وأغلقه.

قبل إعادة إنشاء webserverالخدمة ، ستحتاج إلى إضافة 443تعيين منفذ webserverلتعريف الخدمة الخاص بك.

افتح ملفك docker-compose.yml:

nano docker-compose.yml

في webserverتعريف الخدمة ، أضف تعيين المنفذ التالي:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

هذا هو الملف الكامل docker-compose.ymlبعد التعديلات:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

احفظ وأغلق الملف عند الانتهاء من التحرير.

إعادة إنشاء webserverالخدمة:

docker-compose up -d --force-recreate --no-deps webserver

تحقق من خدماتك مع docker-compose ps:

docker-compose ps

يجب أن يشير الإخراج إلى أن خدماتك dbو wordpressو webserverخدماتك قيد التشغيل:

Output
  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp    

مع تشغيل الحاويات الخاصة بك ، يمكنك إكمال تثبيت WordPress الخاص بك من خلال واجهة الويب.

الخطوة 6 - استكمال التثبيت من خلال واجهة الويب

مع تشغيل الحاويات الخاصة بك ، قم بإنهاء التثبيت من خلال واجهة ويب WordPress.

في متصفح الويب الخاص بك ، انتقل إلى مجال الخادم الخاص بك. تذكر استبدال your_domainاسم المجال الخاص بك:

https://your_domain

حدد اللغة التي تريد استخدامها:

مُحدِّد لغة WordPress

بعد النقر فوق " متابعة " ، ستنتقل إلى صفحة الإعداد الرئيسية ، حيث ستحتاج إلى اختيار اسم لموقعك واسم مستخدم. إنها لفكرة جيدة أن تختار هنا اسم مستخدم يسهل تذكره (بدلاً من "admin") وكلمة مرور قوية. يمكنك استخدام كلمة المرور التي ينشئها WordPress تلقائيًا أو إنشاء كلمة المرور الخاصة بك.

أخيرًا ، ستحتاج إلى إدخال عنوان بريدك الإلكتروني وتحديد ما إذا كنت تريد تثبيط محركات البحث عن فهرسة موقعك أم لا:

صفحة الإعداد الرئيسية لـ WordPress

سيؤدي النقر فوق تثبيت WordPress في أسفل الصفحة إلى نقلك إلى مطالبة تسجيل الدخول:

شاشة تسجيل الدخول إلى ووردبريس

بمجرد تسجيل الدخول ، سيكون لديك حق الوصول إلى لوحة تحكم إدارة WordPress:

لوحة تحكم المسؤول الرئيسية لـ WordPress

بعد اكتمال تثبيت WordPress ، يمكنك اتخاذ خطوات للتأكد من تجديد شهادات SSL تلقائيًا.

الخطوة 7 - تجديد الشهادات

تعد شهادات Let's Encrypt صالحة لمدة 90 يومًا. يمكنك إعداد عملية تجديد آلية للتأكد من عدم انقضاءها. تتمثل إحدى طرق القيام بذلك في إنشاء وظيفة باستخدام cronأداة الجدولة المساعدة. في المثال التالي ، ستقوم بإنشاء cronوظيفة لتشغيل برنامج نصي بشكل دوري يقوم بتجديد شهاداتك وإعادة تحميل تكوين Nginx الخاص بك.

أولاً ، افتح برنامج نصي يسمى ssl_renew.sh:

nano ssl_renew.sh

أضف الكود التالي إلى البرنامج النصي لتجديد شهاداتك وإعادة تحميل تكوين خادم الويب. تذكر استبدال اسم المستخدم النموذجي هنا باسم المستخدم الخاص بك غير الجذر :

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

يقوم هذا البرنامج النصي أولاً بتعيين docker-composeالثنائي إلى متغير يسمى COMPOSE، ويحدد --no-ansiالخيار ، والذي سيقوم بتشغيل docker-composeالأوامر بدون أحرف تحكم ANSI . ثم يفعل الشيء نفسه مع dockerالثنائي. أخيرًا ، يتغير إلى ~/wordpressدليل المشروع ويقوم بتشغيل docker-composeالأوامر التالية:

  • docker-compose run: سيؤدي هذا إلى بدء certbotحاوية وتجاوز ما تم commandتوفيره في certbotتعريف الخدمة الخاص بك. بدلاً من استخدام الأمر certonlyالفرعي ، renewيتم استخدام الأمر الفرعي ، والذي سيقوم بتجديد الشهادات التي أوشكت على الانتهاء. كما تم تضمين --dry-runخيار اختبار البرنامج النصي الخاص بك.
  • docker-compose kill: سيرسل هذا SIGHUPإشارة إلى webserverالحاوية لإعادة تحميل تهيئة Nginx.

ثم يتم تشغيله docker system pruneلإزالة جميع الحاويات والصور غير المستخدمة.

أغلق الملف عند الانتهاء من التحرير. اجعله قابلاً للتنفيذ باستخدام الأمر التالي:

chmod +x ssl_renew.sh

بعد ذلك ، افتح ملف الجذر crontab الخاص بك لتشغيل البرنامج النصي للتجديد في فترة زمنية محددة:

sudo crontab -e 

إذا كانت هذه هي المرة الأولى التي تقوم فيها بتحرير هذا الملف ، فسيُطلب منك اختيار محرر:

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

في الجزء السفلي من هذا الملف ، أضف السطر التالي:

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

سيؤدي هذا إلى تعيين الفاصل الزمني للوظيفة على كل خمس دقائق ، بحيث يمكنك اختبار ما إذا كان طلب التجديد الخاص بك يعمل على النحو المنشود أم لا. يتم إنشاء ملف سجل cron.logلتسجيل المخرجات ذات الصلة من الوظيفة.

بعد خمس دقائق ، تحقق cron.logلتأكيد نجاح طلب التجديد أم لا:

tail -f /var/log/cron.log

المخرجات التالية تؤكد نجاح التجديد:

Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

اخرج عن طريق الدخول CTRL+Cفي المحطة الخاصة بك.

يمكنك تعديل crontabالملف لتعيين فاصل زمني يومي. لتشغيل البرنامج النصي كل يوم ظهرًا ، على سبيل المثال ، يمكنك تعديل السطر الأخير من الملف كما يلي:

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

ستحتاج أيضًا إلى إزالة --dry-runالخيار من ssl_renew.shالبرنامج النصي الخاص بك:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

cronستضمن وظيفتك عدم انتهاء صلاحية شهادات Let's Encrypt الخاصة بك عن طريق تجديدها عندما تكون مؤهلة . يمكنك أيضًا إعداد تدوير السجل باستخدام الأداة المساعدة Logrotate لتدوير ملفات السجل وضغطها.

استنتاج

في هذا البرنامج التعليمي ، استخدمت Docker Compose لإنشاء تثبيت WordPress باستخدام خادم ويب Nginx. كجزء من سير العمل هذا ، حصلت على شهادات TLS / SSL للمجال الذي تريد ربطه بموقع WordPress الخاص بك. بالإضافة إلى ذلك ، قمت بإنشاء cronوظيفة لتجديد هذه الشهادات عند الضرورة.

مصدر المقال الأصلي على https://www.digitalocean.com

#wordpress #docker #nginx