Wie man Ghost CMS mit Docker auf Ubuntu 20.04 installiert

Ghost ist eine Open-Source-Blogging-Plattform, mit der du einen professionell aussehenden Blog erstellen kannst. Sie wurde 2013 als Alternative zu WordPress ins Leben gerufen, weil es zu komplex geworden war. Ghost ist in JavaScript geschrieben und wird von Node.js angetrieben.

In diesem Tutorial zeigen wir dir, wie du Ghost CMS mit Docker auf einem Server mit Ubuntu 20.04 installierst. Außerdem werden wir Nginx als Proxy und ein Let’s Encrypt SSL-Zertifikat verwenden, um unsere Installation zu sichern.

Voraussetzungen

  • Ein Server, auf dem Ubuntu 20.04 läuft.
  • Ein sudo-Benutzer ohne Root-Rechte.
  • Stelle sicher, dass alles auf dem neuesten Stand ist.
    $ sudo apt update 
    $ sudo apt upgrade
    

Schritt 1 – UFW-Firewall konfigurieren

Der erste Schritt besteht darin, die Firewall zu konfigurieren. Ubuntu wird standardmäßig mit ufw (Uncomplicated Firewall) ausgeliefert.

Überprüfe, ob die Firewall läuft.

$ sudo ufw status

Du solltest die folgende Ausgabe erhalten.

Status: inactive

Erlaube den SSH-Port, damit die Firewall die aktuelle Verbindung nicht unterbricht, wenn du sie aktivierst.

$ sudo ufw allow OpenSSH

Lasse auch HTTP- und HTTPS-Ports zu.

$ sudo ufw allow 80
$ sudo ufw allow 443

Aktiviere die Firewall

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Überprüfe den Status der Firewall erneut.

$ sudo ufw status

Du solltest eine ähnliche Ausgabe sehen.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Schritt 2 – Installiere Certbot und erhalte das SSL-Zertifikat

Bevor wir weitermachen, müssen wir das Certbot-Tool installieren und ein SSL-Zertifikat für unsere Domain einrichten.

Um Certbot zu installieren, verwenden wir den Snapd-Paketinstaller. Das offizielle Repository von Certbot ist veraltet und das Certbot-Paket von Ubuntu ist mehr als ein Jahr alt. Snapd enthält immer die neueste stabile Version von Certbot und du solltest diese verwenden. Glücklicherweise ist Snapd bei Ubuntu 20.04 bereits vorinstalliert.

Stelle sicher, dass deine Version von Snapd auf dem neuesten Stand ist.

$ sudo snap install core 
$ sudo snap refresh core

Entferne alle alten Versionen von Certbot.

$ sudo apt remove certbot

Installiere Certbot.

$ sudo snap install --classic certbot

Stelle mit folgendem Befehl sicher, dass der Certbot-Befehl ausgeführt werden kann, indem du einen symbolischen Link auf das Verzeichnis /usr/bin erstellst.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Erstelle ein SSL-Zertifikat.

$ sudo certbot certonly --standalone -d example.com

Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/example.com auf deinem Server heruntergeladen.

Schritt 3 – Docker und Docker Compose installieren

Der erste Schritt besteht darin, die Docker Engine und Docker Compose zu installieren. Deinstalliere zunächst alle alten Versionen von Docker.

$ sudo apt remove docker docker-engine docker.io containerd runc

Installiere einige Pakete, die benötigt werden, damit Docker läuft.

$ sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release

Füge den offiziellen GPG-Schlüssel von Docker hinzu.

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Füge das offizielle Repository von Docker hinzu.

$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Aktualisiere die System-Repositories.

$ sudo apt update

Installiere die neueste Version der Docker Engine.

$ sudo apt install docker-ce docker-ce-cli containerd.io

Überprüfe, ob die Docker Engine läuft und korrekt installiert ist.

$ sudo docker run hello-world

Standardmäßig benötigt Docker sudo, um zu laufen. Um dies zu umgehen, können wir das aktuelle Benutzerkonto zur Benutzergruppe docker hinzufügen.

$ sudo usermod -aG docker ${USER}

Um die neue Gruppenzugehörigkeit zu übernehmen, logge dich aus und melde dich wieder an oder verwende den folgenden Befehl.

$ su - ${USER}

Jetzt kannst du Docker-Befehle ausführen, ohne sudo zu benutzen.

Als nächstes lädst du die aktuelle stabile Version von Docker compose herunter.

sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Zum Zeitpunkt der Erstellung dieses Tutorials ist 1.28.6 die neueste Version von Docker compose. Du kannst den Befehl jederzeit ändern oder eine andere Version auswählen, indem du auf der Github-Releaseseite von Docker compose nachschaust.

Gib der installierten Version von Docker compose die Berechtigung zum Ausführen.

$ sudo chmod +x /usr/local/bin/docker-compose

Teste die Installation.

$ docker-compose --version
docker-compose version 1.28.6, build 5db8d86f

Schritt 4 – Ghost installieren

Die Ghost-Installation besteht aus drei Komponenten – dem Ghost-Paket, einem Datenbankserver wie MySQL und einem Webserver (Nginx). Alle diese Dienste können mit einer einzigen Docker Compose-Datei installiert werden.

Docker Compose-Datei erstellen

Erstelle zunächst ein Verzeichnis, in dem du deine Docker Compose-Datei speichern und starten kannst.

$ mkdir ghost && cd ghost

Erstelle eine Datei namens docker-compose.yml und öffne sie mit dem Nano-Editor.

$ nano docker-compose.yml

Füge den folgenden Code in die Datei ein. Ersetze example.com durch deine Domäne und füge ein Datenbankpasswort anstelle des Wertes your_password ein. Lass die Werte für database__connection__password und MYSQL_ROOT_PASSWORD gleich. Ersetze <username> durch den Benutzernamen deines Servers.

version: '3.3'
services:

  ghost:
    image: ghost:latest
    restart: always
    depends_on:
      - db
    environment:
      url: https://example.com
      database__client: mysql
      database__connection__host: db
      database__connection__user: ghost
      database__connection__password: ghostdbpass
      database__connection__database: ghostdb
      mail__transport: SMTP
      mail__options__host: {Your Mail Service host}
      mail__options__port: {Your Mail Service port}
      mail__options__secureConnection: {true/false}
      mail__options__service: {Your Mail Service}
      mail__options__auth__user: {Your User Name}
      mail__options__auth__pass: {Your Password}
    volumes:
      - /home/<username>/ghost/content:/var/lib/ghost/content

  db:
    image: mariadb:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
	  MYSQL_USER: ghost
      MYSQL_PASSWORD: ghostdbpass
      MYSQL_DATABASE: ghostdb
    volumes:
      - /home/<username>/ghost/mysql:/var/lib/mysql

  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - ghost
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt/
      - /usr/share/nginx/html:/usr/share/nginx/html

Die Docker Compose-Datei erstellt einige Einhängepunkte, d.h. sie ordnet bestimmte Verzeichnisse auf dem Server Verzeichnissen innerhalb des Containers zu.

  • Die Verzeichnisse /var/lib/ghost/content und /var/lib/mysql innerhalb deines Containers werden auf /home/<username>/ghost/content und /home/<username>/ghost/mysql auf dem Server abgebildet.
  • Nginx verwendet den /etc/letsencrypt/ bind, um vom Server aus auf Let’s Encrypt-Zertifikate zuzugreifen.
  • Nginx benötigt außerdem Zugriff auf das Benutzerverzeichnis /usr/share/nginx/html, damit es auf die Let’s Encrypt Challenge-Dateien für das Zertifikat zugreifen kann.

In der obigen Datei haben wir auch Optionen für die Einrichtung von Mails angegeben. Wenn du einen gängigen SMTP-E-Mail-Dienst wie Mailgun, Mailjet, Mandrill, Postmark, Sendgrid, SendCloud, SES, Zoho oder Gmail verwendest, kannst du einfach den Namen des Dienstes sowie deinen SMTP-Benutzernamen und dein Passwort eingeben und den Rest der Felder weglassen. Andernfalls füllst du alle anderen Optionen aus und entfernst den Namen des Dienstes, dann sollte es trotzdem funktionieren. Weitere Mail-Optionen findest du in der Ghost-Dokumentation über Mail-Optionen.

Erstelle die Verzeichnisse für alle oben beschriebenen Bind-Mounts (mit Ausnahme von /etc/letsencrypt, das bereits erstellt wurde, als wir das Zertifikat erstellt haben)

$ cd ~/ghost
$ mkdir content
$ mkdir mysql
$ sudo mkdir -p /usr/share/nginx/html

Erstelle das Nginx-Docker-Image

Die Docker-Compose-Datei, die wir erstellt haben, basiert auf dem Nginx-Docker-Image. Damit es funktioniert, müssen wir eine angepasste Konfigurationsdatei für Nginx einfügen, die mit Ghost funktioniert.

Erstelle ein Verzeichnis für dieses Image im aktuellen Verzeichnis.

$ mkdir nginx

Erstelle in diesem Verzeichnis eine Datei namens Dockerfile.

$ touch nginx/Dockerfile

Füge den folgenden Code in die Datei Dockerfile ein.

FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY ghost.conf /etc/nginx/conf.d

Der obige Code weist Docker an, das neueste Nginx-Image zu verwenden. Außerdem löscht er die Standardkonfigurationsdatei von Nginx und kopiert die benutzerdefinierte Konfigurationsdatei, die wir für unser Ghost CMS erstellt haben.

Erstelle eine Datei namens ghost.conf im Verzeichnis nginx.

$ touch nginx/ghost.conf

Füge den folgenden Code in die Datei ghost.conf ein. Ersetze alle Instanzen von example.com durch deine Domain.

server {
  listen 80;
  listen [::]:80;
  server_name example.com;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { root /usr/share/nginx/html; allow all; }
  location / { return 301 https://$server_name$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;
    
  access_log /var/log/nginx/ghost.access.log;
  error_log /var/log/nginx/ghost.error.log;
  client_max_body_size 20m;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers on;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:10m;

  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://ghost:2368;
  }
}

Die obige Konfiguration leitet alle HTTP-Anfragen auf HTTPS um und dient als Proxy für den Ghost-Dienst, um ihn über deine Domain zu bedienen.

Schritt 5 – Ausführen der Website

Führe den folgenden Befehl im Verzeichnis ghost aus, um den Ghost-Dienst zu starten.

$ docker-compose up -d

Jetzt kannst du deine Installation überprüfen, indem du https://example.com in deinem Webbrowser öffnest. Es kann einige Minuten dauern, bis der Docker alle Dienste hochgefahren hat. Wenn dein Blog nicht sofort angezeigt wird, musst du ihn eventuell aktualisieren.

Ghost Homepage

Wenn deine Website nicht im Browser angezeigt wird, musst du die Docker-Logs überprüfen. Schließe dazu zuerst deinen Container.

$ cd ghost
$ docker-compose down

Führe Docker compose im angehängten Zustand aus, um die von jedem Container erzeugten Logs einzusehen.

$ docker-compose up

Um den Container herunterzufahren und zum Bash-Prompt zurückzukehren, drücke CTRL+C. Wenn du die Fehlerbehebung abgeschlossen hast, kannst du den Container wieder starten und dein Blog sollte jetzt sichtbar sein.

Schritt 6 – Einrichtung abschließen

Um die Einrichtung deines Ghost-Blogs abzuschließen, rufe https://example.com/ghost in deinem Browser auf. Das zusätzliche /ghost am Ende der Domain deines Blogs leitet dich zum Admin-Panel von Ghost oder in diesem Fall zum Setup weiter, da du zum ersten Mal darauf zugreifst.

Ghost Einrichtungsseite

Hier musst du dein Administratorkonto anlegen und einen Blogtitel auswählen.

Details zum Ghost-Setup

Du kannst auch zusätzliche Mitarbeiter/innen für deinen Blog einladen, was du auch später tun kannst, wenn du dich dafür entscheidest, es jetzt zu überspringen.

Ghost Staff Seite einladen

Am Ende der Einrichtung wirst du mit dem Administrationsbereich von Ghost begrüßt.

Ghost Admin Dashboard

Wenn du in den dunklen Modus wechseln möchtest, kannst du das tun, indem du auf den Kippschalter neben dem Zahnradknopf unten auf der Einstellungsseite klickst.

Ghost Dark Mode Toggle

Du wirst bereits einige Standardbeiträge sehen, die im Grunde genommen Anleitungen sind, die dir bei der Navigation und der Nutzung von Ghost helfen. Du kannst sie wieder entfernen oder löschen und mit dem Posten beginnen.

Schritt 7 – Ghost aktualisieren

In unserer Docker-Kompositionsdatei ziehen wir die neueste Version von Ghost, die zum Zeitpunkt der Installation verfügbar ist, sodass du deinen Ghost-Blog ganz einfach aktualisieren kannst.

Um zu aktualisieren, musst du deinen Container herunterfahren, die neuesten Images laden und dann den Container erneut starten.

$ docker-compose down
$ docker-compose pull && docker-compose up -d

Schritt 8 – Erneuere dein Let’s Encrypt SSL-Zertifikat

Let’s Encrypt-Zertifikate sind nur für 90 Tage gültig. Deshalb müssen wir einen Cronjob einrichten, der das Zertifikat automatisch erneuert.

Öffne Crontab in deinem Editor.

$ sudo crontab -e

Füge die folgende Zeile am Ende ein, damit Certbot jeden Tag um 23 Uhr ausgeführt wird. Ersetze example.com durch deine Domain.

0 23 * * *   certbot certonly -n --webroot -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'

Die tägliche Ausführung um 23 Uhr bedeutet nicht, dass dein Zertifikat jeden Tag erneuert wird, da Certbot dein Zertifikat nur erneuert, wenn das Ablaufdatum innerhalb von 30 Tagen liegt. Wenn du den Befehl jeden Abend ausführst, hat das Skript mehrere Gelegenheiten, es zu versuchen, bevor es abläuft.

Der obige Befehl startet auch den Nginx-Server innerhalb des Docker-Containers nach erfolgreicher Erneuerung neu.

Du kannst den Cronjob mit der Option --dry-run von Certbot testen.

$ sudo bash -c "certbot certonly -n --webroot --dry-run -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'"

Fazit

Damit ist unsere Anleitung zur Einrichtung von Ghost CMS auf deinem Ubuntu 20.04 basierten Server mit Docker abgeschlossen. Wenn du Fragen hast oder uns Feedback geben möchtest, schreibe es unten in die Kommentare.

Das könnte dich auch interessieren …