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.
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.
Hier musst du dein Administratorkonto anlegen und einen Blogtitel auswählen.
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.
Am Ende der Einrichtung wirst du mit dem Administrationsbereich von Ghost begrüßt.
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.
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.