WordPress Container auf Docker

Dieser Blog-Eintrag beschreibt, wie man auf WordPress auf einem Docker-Host installieren und damit mehrere WordPress-Instanzen auf einem Host betreiben kann.
Ich betreibe die Docker-Container hinter einem Proxy-Server, der aber nicht als Container läuft. Der Proxy-Server leitet die HTTPS-Requests an die entsprechenden Docker-Container weiter.

Dieser Beitrag setzt ein vorinstalliertes Photon 3.0 inkl. Docker und Docker-Compose voraus. Siehe hier.

Die Docker-Container können über diverse Befehle gemanaged werden. Siehe dazu eine kleine Übersicht hier.

WordPress installieren

Wir installieren WordPress mit Hilfe von Docker Compose. Dazu erstellen wir ein template:

mkdir wordpress
cd wordpress
vi docker-compose.yml

Im yml-Script erstellen wir eine WordPress- inkl. DB-Instanz.

WordPress-Instanz

  • Die WordPress-Instanz hat eine Abhängigkeit zur DB.
  • Die WordPress-Files werden unter /var/www/html abgelegt
  • der Host-Port 80 wird zur wordpress-Instanz port 80 weitergeleitet (“80:80”)
  • Die DB ist über Port 3306 anzusprechen (WORDPRESS_DB_HOST: db:3306)
  • Der DB-User ist wordpress (WORDPRESS_DB_USER: wordpress)
  • Das DB-Passowort ist zu setzen: WORDPRESS_DB_PASSWORD: <wordpress_db_password>

DB-Instanz

  • Die DB-Files werden hier abgelegt: db_data:/var/lib/mysql
  • Passort setzen: MYSQL_ROOT_PASSWORD: <mysql root password>
  • Datenbank definieren: MYSQL_DATABASE: wordpress
  • User definieren: MYSQL_USER <wordpress>
  • DB-Passwort setzen: MYSQL_PASSWORD: (wordpress db password)
version: '3.3' services:

wordpress:
   depends_on:
     - db
   image: wordpress:latest
   volumes:
     - wordpress_files:/var/www/html
   ports:
     - "8080:80"
   restart: always
   environment:
     WORDPRESS_DB_HOST: db:3306
     WORDPRESS_DB_USER: wordpress
     WORDPRESS_DB_PASSWORD: (wordpress_db_password)

db:
   image: mysql:5.7
   command: '--default-authentication-plugin=mysql_native_password'
   volumes:
     - db_data:/var/lib/mysql
   restart: always
   environment:
     MYSQL_ROOT_PASSWORD: (mysql root password)
     MYSQL_DATABASE: wordpress
     MYSQL_USER: wordpress
     MYSQL_PASSWORD: (wordpress db password)
   volumes:
     wordpress_files:
     db_data:

 

Die letzten beiden Linien restellen lokale Verzeichnisse auf dem Photon-Host. Hier werden die WordPress- und SQL-Files abgespeichert. Diese Files überleben somit, wenn der container zerstört und neu generiert wird.

Die Volumes werden unter

cd /var/lib/docker/volumes

erstellt und bleiben bestehen. Dies solange bis die Volumes mittels

docker-compose down -v

zerstört werden.

WordPress Container starten

Nun kann der Container einfach gestartet werden. Dank Docker Compose braucht man nur noch einen Befehl. Docker Compose erkennt automatisch das YAML im aktuellen Verzeichnis, durchläuft die Konfiguration und startet die Container-Anwendung:

docker-compose up -d

Den Prozess kann man anzeigen lassen

docker ps

Nun ist über http://<ip>:8080 auf die WordPress-Instanz zugegriffen werden.

WordPress Container mit SSL erweitern

Das so bereitgestellte Container-Image bietet WordPress “out-of-the-Box” über Port 80 an. Port 443 ist nicht aktiviert. Man geht dabei davon aus, dass die Verschlüsselung (https) eine zusätzliche, neue Funktion darstellt und damit über einen weiteren Container abzubilden ist. Dazu kann ein Proxy-Container aufgebaut werden, für den es auch bereits fertige Docker-Images gibt. Architektonisch mag das Sinn machen.

Ich möchte das aber nicht so umsetzen. Ich betreibe bereits einen Proxy-Server und dieser soll auch so weiter beibehalten werden. Ich verzichte also auf einen Proxy-Container und erweitere das WordPress-Image durch die SSL-Funktionalität. Damit das geht, muss ich das docker-compose.yml bzw. die WordPress-Container Beschreibung erweitern.

Als erstes erstelle ich ein zusätzliches File

vi wordpress/wp-init.sh
!/usr/bin/env bash
apt-get update
apt-get install -y --no-install-recommends ssl-cert
rm -r /var/lib/apt/lists/*
a2enmod ssl
a2dissite 000-default.conf
a2ensite apache2-vhosts.conf
docker-entrypoint.sh apache2-foreground

Dieses Bash-Script soll bei jedem Starten des Containers ausgeführt werden. Mittels diesem Script wird
– SSL nachinstalliert
– Die Default Konfig “000-default.conf” auf dem Apachen entfernt und stattdessen
– eine neue Konfig “apache2-vhosts.conf” installiert.
– Anschliessend wird der Apache neu gestartet.

Damit das Script funktioniert braucht es noch eine Apache-Config. Diese Config wird in den WordPress-Container gemappt und beim Container-Start aktiviert. Damit kann ich von ausserhalb des Containers, die Apache-Config manipulieren:

vi wordpress/apache2-vhosts.conf
NameVirtualHost * 
<VirtualHost *:443> 
   ServerName domain.ch 
   DocumentRoot /var/www/html/ 
   DirectoryIndex index.php 
   Options -Indexes 
   SSLEngine On 
   SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem 
   SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key 
   SSLCACertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem 
</VirtualHost>

Nun ist das das docker-compose.yml zu erweitern (siehe die markierten Erweiterungen):

version: '3.3'
   services:
   wordpress:
     depends_on:
       - db_node
     image: wordpress:latest
     volumes:
       - wordpress_files:/var/www/html
       - ./wp-init.sh:/usr/local/bin/apache2-custom.sh
       - ./apache2-vhosts.conf:/etc/apache2/sites-available/apache2-vhosts.conf
     ports:
       - "8080:80"
       - "8443:443"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db_node:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: (wordpress db password)
     container_name: wordpress_web
     command: "bash -c apache2-custom.sh"

   db_node:
     image: mysql:5.7
     command: '--default-authentication-plugin=mysql_native_password'
     volumes:
       - db_data:/var/lib/mysql
     ports:
       - 6601:3306
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: (wordpress root password)
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: (wordpress db password)
     container_name: wordpress_db
     volumes:
       wordpress_files:
       db_data:

Wie man sieht wird
– das wp-init.sh Skript in den Container gemappt
– Die Apache-Config apache2-vhosts.conf in den Container gemappt.
– Der Container um den Port 8443 erweitert, der Container-Intern auf 443 routet und
– Das Commando “bash -c apache2-custom.sh” bei starten ausgeführt.

Damit startet der Container ab sofort mit aktiviertem SSL und der Apache-Container kann über das File apache2-vhosts.conf konfiguriert werden.

Reverse Proxy

Auf dem Reverse-Proxy wird nun einfach eine Reverse-Rule für den Container eingeführt. Der Reverse-Proxy leitet die HTTPS-Anfragen intern an den Container-Host mit Port 8443 weiter. Diese kann so aussehen:

<VirtualHost serverIp:80> 
ServerAdmin info@domain.ch 
ServerName www.domain.ch 
ServerAlias domain.ch 
RewriteEngine on 
ReWriteCond %{SERVER_PORT} !^443$ RewriteRule ^/(.*) https://www.domain.ch/$1 [NC,R,L] 
</VirtualHost>

<VirtualHost serverIp:443> 
ServerAdmin info@domain.ch 
ServerName www.domain.ch 

#aktiviert SSL Unterstuetzung 
SSLEngine On 
SSLProxyEngine on 
SSLProxyVerify none 
SSLProxyCheckPeerCN off 
SSLProxyCheckPeerName off 
SSLProxyCheckPeerExpire off 

SSLCertificateKeyFile /etc/letsencrypt/live/www.domain.ch/privkey.pem 
SSLCertificateFile /etc/letsencrypt/live/www.domain.ch/cert.pem 
SSLCertificateChainFile /etc/letsencrypt/live/www.domain.ch/chain.pem 

# Regeln zum umleiten auf den internen Server 
ProxyPreserveHost On 
ProxyRequests Off 
ProxyPass / https://www.domain.ch:8443/ 
ProxyPassReverse / https://www.domain.ch:8443/ 

RequestHeader unset Accept-Encoding 

ErrorLog /var/log/apache2/error.log 

# Possible values include: debug, info, notice, warn, error, crit, 
# alert, emerg. 
LogLevel warn 

CustomLog /var/log/apache2/access.log combined 
ServerSignature On 
</VirtualHost>

SMTP auf WordPress-Container

Ich betreibe einen eigenen Mailserver. Ich stellte rasch fest, dass WordPress keine Mails über diesen Server versenden kann. Dies, weil das WordPress-Image einerseits grundsätzlich keinen SMTP-Agent mit dabei hat und andererseits mein Mailserver auch nicht aus dem Container heraus erreichbar war:

Um das Problem zu lösen habe ich mir einfach das Plugin “WP Mail SMTP” installiert. Dieses erweitert WordPress um die Mailfunktion. Das Connectivity-Problem konnte ich mit einer einfach Erweiterung von /etc/hosts lösen:

192.168.xx.xx    mx.domain.ch

Man beachte, dass ich die interne IP des Mailservers verwende.

Damit diese Erweiterung auch bei einem neuen Create des Containers übernommen wird, muss wordpress/wp-init.sh noch modifiziert werden:

#!/usr/bin/env bash

# modify /etc/hosts with mx.intelli.ch
cat >> /etc/hosts <<-EOF

/* mx.intelli.ch */
192.168.xx.xx    mx.domain.ch
EOF

apt-get update
apt-get install -y  --no-install-recommends ssl-cert   # SSL
rm -r /var/lib/apt/lists/*

a2enmod ssl
a2dissite 000-default.conf
a2ensite apache2-vhosts.conf

# finally execute default command
docker-entrypoint.sh apache2-foreground

Links

Hot-Backup von ESXi VMs

Um Backups von ESXi VMs im laufenden Zustand machen zu können, braucht es

  • Verständnis was VmWare unter einem Snapshot versteht
  • Das Scipt ghettoVCB.sh =>  ghettoVCB

Exkurs VMWare-Snapshot

Bei einem VMware Snapshot wird eine weitere Festplattendatei erstellt welche ab Zeitpunkt des Snapshots alle geänderten Blöcke aufnimmt. Gleichzeitig wird der Exklusiv Zugriff auf die Basis Festplatte aufgehoben so das andere Prozesse lesen koennen.

Dieses “lesen” kann ein Kopierbefehl einens Backupprogramms sein. Da keine Schreibzugriffe mehr in die Datei erfolgen ist der Zustand also konsistent. Snapshots sind also keine Backups. Ein Snapshot “friert” lediglich einen Zustand ein (Basis Festplatte) und schreibt alle ab diesem Zeitpunkt anfallenden Änderungen in eine neue Snapshot Datei (Delta).

 

  • Die Basisplatte und der bzw. die Snapshots zusammen ergeben den akt. Stand. Fehlt ein Element in der Kette ist kein vollstaendiges Restore mehr moeglich. Beides muss zur gleichen Zeiten fuer den HOST zugaenglich sein.
  • Snapshots wachsen bis zur max. konfigurierten Festplattengroesse heran. Die Groesse des Datastores ist also zu ueberwachen.
  • Beim löeschen von mehr als 2 Snapshots ist zu bedenken das ein Helper angelegt wird und immer die Groesse der zusammen zufuehrenden Snaps benoetigt wird.
  • Laufende Snaps kosten ein wenig Performance. Die Gefahr von Fragmentierierung ignorieren wir da die Snaps immer in 16MB Bloecken wachsen.
  • Grosse Snaps loeschen, hier versteht VMware das einpflegen der Aenderungen, dauert lange

Beispiel:

  • Basisplatte
  • Snapshot1
  • Snapshot2
  • Snapshot3
  • Snapshotx

Löscht man jetzt Snapshotx wird dieser (und damit alle davorigen Snapshots) in die Basisplatte eingepflegt.
Löscht man Snapshot2 wird dessen Zustand und der von Snapshot1 in die Basisplatte eingepflegt und Snapshot3 usw. werden zu Snapshot1 usw,

Die .VMDK-Files (Virtuell Maschine Disk Files) können im laufenden Betrieb nicht kopiert oder verschoben werden, da sie ja in Gebrauch sind. Dies sieht aber nach einem Snapshot anders aus. Bei einem Snapshot werden die .VMDK-Files im Prinzip gekappt und neue Files (VMSN und VMSD) angelegt, in welche die kompletten Änderungen des Snapshots geschrieben werden. Wenn man ein Snapshot der VM macht, wird die Basis-Festplatte in den Read-Only Modus gesetzt, wordurch diese nun, da konsisten, kopiert werden kann. Das Verhalten von Snapshots kann also ausgenutzt werden um Backups im laufenden System erstellen zu können (Hilfsmittel zum Backup):

Komplettbackup 1

  1. Das Konfigurations-File der VM sichern/kopieren (VMX-File)-> nach dem Snaphsot der vituellen Maschine ändern sich die Verweise in der Konfiguration.
  2. Man erstellt einen ersten Snapshot einer VM. Es bestehen anonsten keine Snapshots dieser VM. Der Snapshot wird also gemacht, und die Basis-Festplatte kopiert. Anschliessend den Snapshot wieder loeschen. Dieses Vorgehen benötigt entsprechend viel Platz, wenn mehrere Backups der gleichen VM notwendig sind.

Komplettbackup 2

  1. Man macht täglich einen Snapshot und sicherst den Snapshot des Vortages. Bedeutet weniger Platz da quasi nur Aenderungen dann noch anfallen. Aber ein Restore erfordert Knowhow und dein ESX wird mehr belastet.

Soweit der Exkurs… Um ein Backup zu erstellen, können wir das mit den Snapshots manuell machen oder aber mit dem ghettoVCB-Script arbeiten. Das macht nämlich genau das oben beschriebene.

Installation von ghettoVCB

Die Installation ist simple. Einfach ein Verzeichnis auf dem ESXi-Datastore erstellen und die ghettoVCB-Scripts hineinkopieren. Das wird ganz schön auf Youtube gezeigt: http://www.youtube.com/watch?v=mVrjxzKEEu4

ghettoVCB konfigurieren und Backup durchführen

Die Konfigurationsmölgichkeiten findet man hier: http://communities.vmware.com/docs/DOC-8760

ghettoVCB.conf File

Ich habe mein ghettoVCB.conf File folgendermassen konfiguriert (ist eingentlich alles Standard):

VM_BACKUP_VOLUME=/vmfs/volumes/65d7a6db-6bc8d65a/VmBackups
DISK_BACKUP_FORMAT=thin
VM_BACKUP_ROTATION_COUNT=1
POWER_VM_DOWN_BEFORE_BACKUP=0
ENABLE_HARD_POWER_OFF=0
ITER_TO_WAIT_SHUTDOWN=3
POWER_DOWN_TIMEOUT=5
ENABLE_COMPRESSION=0
VM_SNAPSHOT_MEMORY=0
VM_SNAPSHOT_QUIESCE=0
SNAPSHOT_TIMEOUT=15

VMs zum Backup

Habe ein File “vms_to_backup” erstellt, welches eine Liste der Namen der VMs beinhaltet. Bei den Namen handelt es sich um die Namen, welche auch im vSphereClient angezeigt werden:

TestVM32Bit

Backup run

Nun kann die VM im laufenden Zustand gebackuped werden (Option -d dryrun führt einen Testlauf durch):

./ghettoVCB.sh -f vms_to_backup -g ./ghettoVCB.conf -d dryrun

Backup automatisch durchführen (Cron-Tab)

Um das Backup automatisch durchzuführen, kann dies in der Cron-Tab von ESXi konfiguriert werden:

In Crontab registrieren, Job soll jeden Donnerstag um 17:00 Uhr durchgeführt werden

echo "0 17 * * 4 /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/vms_to_backup -g /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root

Wenn man dies Ausführt, wird der crontab automatisch an die richtige Datei angehängt.
Nun muss crond neu gestartet werden:

ESXi 4.1

/bin/kill $(cat /var/run/crond.pid)
/bin/busybox crond

Die Cron-Tab von ESXi wird bei jedem Start wieder neu geschrieben. Um die Zeile deswegen bei jedem Start auszuführen, muss diese noch in die /etc/rc.local eingetragen werden. Meine rc.local sieht anschliessend so aus:

vi /etc/rc.local
 #! /bin/ash
export PATH=/sbin:/bin

log() {
echo "$1"
logger init "$1"
}

#execute all service retgistered in /etc/rc.local.d
if [ -d /etc/rc.local.d ]; then
for filename in `find /etc/rc.local.d/ | sort`
do
if [ -f $filename ] && [ -x $filename ]; then
log "running $filename"
$filename
fi
done
fi

/bin/kill $(cat /var/run/crond.pid)
/bin/echo "0 17 * * 4 /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/vms_to_backup -g /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root
crond

ESXi 5.5

kill $(cat /var/run/crond.pid)
crond

Die Cron-Tab von ESXi wird bei jedem Start wieder neu geschrieben. Um die Zeile deswegen bei jedem Start auszuführen, muss diese noch in die /etc/rc.local eingetragen werden. Meine rc.local sieht anschliessend so aus:

vi /etc/rc.local.d/local.sh
#!/bin/sh

# local configuration options

# Note: modify at your own risk! If you do/use anything in this
# script that is not part of a stable API (relying on files to be in
# specific places, specific tools, specific output, etc) there is a
# possibility you will end up with a broken system after patching or
# upgrading. Changes are not supported unless under direction of
# VMware support.
/bin/kill $(cat /var/run/crond.pid)
echo "0 17 * * 4 /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/vms_to_backup -g /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root
crond
exit 0

Nun nur noch autobackup durchführen, das ganze in der ESXi Konfuguration zu speichern:

/sbin/auto-backup.sh

Das wars! Jetzt werden die VMs automatisch regelmässig gesichert.

Restore durchführen

Um einen Restore druchzuführen, habe ich ein file vms_to_restore erstellt, wobei dieses pro Linie einen Restore-Parameter mit folgendem Format enthalten muss:

";;"
# DISK_FORMATS
# 1 = zeroedthick
# 2 = 2gbsparse
# 3 = thin
# 4 = eagerzeroedthick

z.B.:

"/vmfs/volumes/QnapTSDatastore/VmBackups/TestVM32Bit/TestVM32Bit-2013-01-03_13-25-54;/vmfs/volumes/ESXi Raid1/TestVM;3"

Anschliessend kann das Restore folgendermassen gestartet werden (Option -d 2 = Dryrun):

./ghettoVCB-restore.sh -c vms_to_restore -d 2

Dies stellt das von ghettoVCB erstellte Backup “TestVM32Bit-2013-01-03_13-25-54” unter dem Pfad “/vmfs/volumes/ESXi Raid1/TestVM” her bzw. kopiert diese dahin und registriert die VM neu beim ESXi-Host.

Die Fileformate

zeroedthick (default)

vmdk wird in voller Groesse angelegt – dieser Typ wird bei der Erstellung nicht mit Nullen ueberschrieben – das passiert erst spaeter im Betrieb

eagerzeroedthick

vmdk wird in voller Groesse angelegt – dieser Typ wird bei der Erstellung mit Nullen ueberschrieben

thick

vmdk wird in voller Groesse angelegt – und nie genullt

thin

vmdk waechst nach Bedarf – dies ist ein Feature des VMFS dateisystems – und ist auf den meisten NFS-servern nicht moeglich

2gbsparsed

vmdk wird in maximal 2 Gb grosse Stuecke aufgeteilt – die jeweils nach Bedarf wachsen – dieses Format ist it Workstation kompatibel

Firefox Security

Plugins

Folgende Plugins sind für Firefox empfehlenswert um spurenarmer zu surfen:

Firefox about:config Anpassungen

Suchfeld rechts oben wieder anzeigen

browser.search.widget.inNavBar = true

Anzeige von Vorschlägen bei der Eingabe deaktivieren

browser.urlbar.suggest.searches = false
browser.urlbar.suggest.openpage = false

Suchvorschläge deaktivieren

browser.urlbar.suggest.bookmark = false
browser.urlbar.suggest.history = false

Unterbinden, dass Firefox nach Hause telefoniert um festzustellen aus welchem Land man stammt. Das benutzt Firefox um zu entscheiden, welche Suchmaschine standardmässig genutzt werden soll (USA = Yahoo und alle anderen mit Google)

browser.search.countryCode = CH
browser.search.geoSpecificDefaults = false
browser.search.geoip.url = "" (leerer String)

 

Links

dd-wrt: exclude IPs von VPN

Ich verwende OpenVPN auf dd-wrt und leite den gesamten Traffic über einen VPN-Anbieter. Leider b(l)ockt hier Netflix. Um den Traffic des Netflix-Devices nicht über OpenVPN zu leiten gibt es hier ein schönes Tutorial:

https://www.ivpn.net/knowledgebase/124/DD-WRT—How-do-I-exclude-hosts-or-bypass-VPN-tunnel.html

…das geht aber irgendwie nicht.

Next try:

http://www.titam.ca/2015/07/notes-on-various-ways-of-configuring.html

https://jamiegoodwin.uk/how-to-restrict-openvpn-to-certain-devices-in-dd-wrt/

Wichtig:

Die Zugriffsbeschränkung von dd-wrt funktioniert nicht zusammen mit vpn. Die Zugriffsbeschränkung zieht nur bei einer direkten internet-Verbindung. VPN gilt “quasi” als interne Verbindung. Um einem Internen Host (z.B. dem xiaomi mi home) die Zugriffbeschränkung in das Internet zu entziehen muss man also diesen bestimmten Host (xiaomi mi home) ohne VPN vetreiben und so die Zugriffsbeschränkung aktivieren.

Um die IPs vom VPN zu exkludieren, muss man dies in dd-wrt mittels Netz-Definition (nicht durch Eingabe der spezifischen IP) definieren. Das geht rasch mit folgenden Link. Einfach IPs eingeben und sich das Netz berechnen lassen:

https://www.ipaddressguide.com/cidr

Motorola Moto X4 Stock Rom installieren

Hier habe ich beschrieben, wie man das LOS auf einem Moto X4 installieren kann. Dieser Beitrag beschreibt nun, wie man das alte Stock-Rom wieder aufspielen kann.

Um auf dem Moto X4 das Stock Rom zu installieren kann man diesem Video folgen:

Anleitung

Um das Stock-Rom installieren zu können muss man

Hier noch ein Video, das die A/B Slots auf dem Moto X4 erklärt

Links

Motorola Moto X4 – Installation Lineage OS

Heute wurde mein neues Telefon angeliefert, das Motorola Moto X4. Die Gründe für das Moto X4 waren:

  • Nicht zu gross (5.2″)
  • Dual-Sim
  • Akku 3000 mAh
  • Preis unter CHF 300.00
  • NFC vorhanden
  • Offizieller Build-Release von Lineage OS

Ich möchte das Telefon nicht mit dem Stock-Release von Motorola benutzen. Das Moto X4 soll mit Lineage OS beglückt werden. Dieser Blog-Post basiert auf dem Post von eines Pro-Linux Artikels sowie einem Install-Video und beinhaltet zusätzlich Änderungen aufgrund meinen eigenen Erfahrungen mit dem Moto X4 (Installation TWRP, etc.).

Installation

Mein Installations-Ablauf:

  • Developer-Modus einschalten
  • Handy über adb-Tools (Android Debug Bridge – kurz ADB) starten
  • Bootloader OEM-Sperre entfernen
  • Team Win Recovery Project (TWRP) flashen (Recovery-Modus)
  • Backup des Stock-ROMS erstellen
  • Firmware für Moto X4 aufspielen
  • LineageOS auf SD-Karte aufspielen

Siehe auch

Link

Developer-Modus einschalten

  • Das Telefon beim ersten Start ohne Sim-Karte und ohne Speicher-Karte starten.
  • Durchbooten bis zum Desktop
  • Einstellungen > Über das Telefon aufrufen
  • 7x auf die Build-Nummer Tippen => Das Telefon meldet nun, dass Sie nun “Entwickler” sind => Developer-Modus ist damit aktiviert.
  • Nun erscheint unter den Einstellungen zusätzlich der Eintrag “Entwickleroptionen”
  • Unter den Entwickleroptionen folgende Optionen aktivieren:
    • OEM Entsperrung und
    • USB Debugging

Nun ist das Telefon soweit bereit um es verändern zu können.

Handy über adb-Tools (Android Debug Bridge – kurz ADB) starten

Mit der Android Debug Bridge – kurz ADB – kann man ein Android-Smartphone verwalten. Es ist grundsätzlich für Entwickler gedacht und bietet ein paar coole Funktionen. Ich verwende die adb unter Ubuntu-Linux. Die adb kann folgendermassen installiert werden:

sudo apt-get install android-tools-adb
sudo apt-get install android-tools-fastboot

Nun das Telefon mit dem Linux-Rechner verbinden:

  • Per USB3-Kabel das Telefon mit dem Linux-Rechner verbinden
  • Auf dem Telefon nochmals kurz USB-Debugging de- und wieder aktivieren
  • Nun können über die Linux-Konsole Befehle an das Telefon gesendet werden. Damit das aber funktioniert, muss der Linux-Rechner noch autorisiert werden. Dies geschieht indem ein Befehl an das Telefon gesendet wird.
  • adb reboot bootloader
  • Auf dem Telefon erscheint automatisch die Anfrage ob der Rechner autorisiert werden soll. Hier nun die Genehmigung erteilen:
  • Ein Reboot des Bootloaders zeigt nun folgendes Bild, wobei ersichtlich ist, dass das Gerät “oem_locked” ist:
  • Um Lineage OS aufspielen zu können, muss der auf dem Bootloader der oem-lock entfernt werden.

Bootloader OEM-Sperre entfernen

Motorola bietet Entwicklern die Möglichkeit, den oem-lock zu entfernen. Damit einher geht, dass die Garantie entfällt. Und so geht es:

  • Link zu Motorola aufrufen > Unlock your bootloader > Get started > Next
  • Nun muss man sich anmelden. Das geht entweder mit einem Google-Account oder aber mit einem Motorola-Konto. Ich habe weder noch. Ich verwende deswegen den Link “Mit Motorola ID anmelden”. Hier werde ich aufgefordert eine Motorola-ID zu erstellen.
  • Nun eine Motorola-ID erstellen und anschliessend anmelden. Nach dem Login wird angezeigt, wie man das Device unlocked:
    • fastboot oem get_unlock_data
      ...
      (bootloader) Unlock data:
      (bootloader) 3AasdfaSDddasdf1#5asdd232344839
      (bootloader) 434E5A006DASDFASD678340000#3F14
      (bootloader) BF2C22D54C36CD73EB12C31DF400F1A
      (bootloader) 55769#FE0D752201561568645130000
      (bootloader) 0000000
      OKAY [  0.013s]
      finished. total time: 0.013s

      Daraus muss ein einzeiliger String erstellt werden, den man auf der unlock-Seite von Motorola eingibt:

    • Nun erscheint am Ende der Motorola-Site ein Unlock-Button:
    • Nun wird ein Mail mit dem Unlock-Key zugestellt:
    • Mit dem Key kann nun der Bootloader unlocked werden. Anstelle “UNIQUE_KEY” muss der im Mail zugestellte Key verwendet werden:
    • fastboot oem unlock UNIQUE_KEY
    • Der Befehl muss nun nochmals zwecks Bestätigung wiederholt werden. Anschliessend ist das Gerät offiziell unlocked! 🙂
    • Um zu überprüfen ob der Unlock wirklich geklappt hat, kann das Telefon nochmals gerebooted werden und dann nochmals in den Bootloader gebooted werden:
    • adb reboot bootloader
    • Voilà. “flashing_unlocked” bestätigt dies:

Team Win Recovery Project (TWRP) flashen (Recovery-Modus)

Team Win Recovery Project (TWRP) ist ein Custom-Recovery-System für Android-Geräte. Es wird über unseren unlocked Bootloader in die Recovery-Partition des Telefons geschrieben. Anschliessend kann TWRP über den Bootloader unabhängig vom System gestartet werden. Mit TWRP können wir unser System Backupen, Restoren aber auch ein anderes OS (Custom-Roms) aufspielen:

  • Die TWRP-Version für Moto X4 auf twrp.me suchen und downloaden => https://twrp.me/motorola/motorolamotox4.html
  • Bei einer Erstinstallation müssen zwei Files heruntergeladen werden (twrp-installer-payton-3.2.3-1.zip und twrp-3.2.3-1-payton.img)
  • Nun temporär TWRP auf dem Telefon starten. Das kann durch folgenden Befehl ausgelöst werden:
  • fastboot boot Downloads/twrp-3.2.3-1-payton.img

    Nun kann das ZIP-File auf das Telefon bzw. auf die sdcard kopiert werden:

  • adb push Downloads/twrp-installer-payton-3.2.3-1.zip /sdcard
    [100%] /sdcard/twrp-installer-payton-3.2.3-1.zip

    Nun kann im TWRP über “Installieren” das Installer-ZIP ausgewählt und installiert werden. Damit wird TWRP fix auf der Recovery-Partition installiert:

  • Nun das Telefon neu starten. Dabei installiere ich die TWRP-App als Systemapplikation, so dass zukünftige TWRP-Updates über die App installiert werden können:
  • Das Telefon Startet nun neu.
  • Ab sofort kann beim Aufstarten des Telefons mittles gleichzeitigem Drücken von  “Power Button” und “Lautstärke Down” in den Bootloader gebootet werden.
  • Im Bootloader kann nun mittles Lautstärken-Buttons der Recovery-Mode ausgewählt und bestätigt werden (Power Button). Anschliessend wird in TWRP gebootet:
  • Nun können diverse Funktionen mit TWRP verwendet werden. 🙂

Backup des Stock-ROMS erstellen

Mittles TWRP erstellen wir nun ein Backup unseres Stock-ROMs. Dies, damit wir im “Worst Case” Fall das System wieder in den Ursprungs-Zustand versetzten können:

  • In TWRP booten
  • Löschen/Wipe auswählen
  • Erweitertes Löschen auswählen
  • Optionen auswählen
    • Dalvik / ART Cache
    • Interner Speicher
  • Löschen bestätigen
  • Zurück
  • Diesen Löschvorgang zweimal durchführen => Soll teilweise nötig sein…
  • Zurück zum TWRP Start-Screen gehen.
  • Sichern / Backup auswählen und folgende Partitionen auswählen:
    • Boot (64MB)
    • Data (ohne /data/media)
    • System (2690MB)
  • Name des Backup-Files benennen
  • Speicher auswählen (ich verwende den internen Speicher)
  • Sicherung erstellen
  • In meinem Falle hat das nicht funktioniert (Fehler 255), deswegen hab ich diesen Schritt übersprungen – No Risk No Fun

Firmware für Moto X4 aufspielen

  • Download https://www.androidfilehost.com/?fid=890278863836292604
  • Entpacken und flash-all.sh ausführen. Dies kopiert die Images von Slot A nach Partition B. Das ist notwendig um Lineageos auf Partition B installieren zu können.
  • $ ./flash_all.sh 
    target reported max download size of 536870912 bytes
    sending 'abl_a' (1024 KB)...
    OKAY [  0.024s]
    writing 'abl_a'...
    OKAY [  0.062s]
    ...
    ...
    ...
    OKAY [  0.039s]
    finished. total time: 0.121s

    Jetzt mit fastboot das twrp-image auf das Telefon pushen und booten:

  • fastboot boot twrp-3.2.3-1-payton.img

    Es wird nun TWRP gestartet.

  • Nun das TWRP-ZIP auf das Telefon kopieren
  • adb push twrp-installer-payton-3.2.3-1.zip /sdcard/

    Nun im TWRP über Install das kopierte TWRP auswählen und installieren (swipe to install).

  • Dies installiert das TWRP sowohl auf Slot A als auch auf Slot B.
  • Nun rebooten (keine twrp-Apps installieren). Wenn das Stock Rom wieder sauber bootet, hat alles funktioniert.
  • Wieder in den bootloader booten und Recovery Mode auswählen > Es wird nun TWRP gestartet.
  • Nun das LineageOS Rom und die GApps auf das Telefon kopieren
  • adb push lineage-15.1-20181002-nightly-payton-signed.zip /sdcard/
    [100%] /sdcard/lineage-15.1-20181002-nightly-payton-signed.zip
    ralwet@Z97X-Gaming-5:~/Schreibtisch/Moto X4 Work$ adb push MindTheGapps-8.1.0-arm64-20180808_153856.zip /sdcard/
    [100%] /sdcard/MindTheGapps-8.1.0-arm64-20180808_153856.zip

    Nun im TWRP > Install

  • LineageOs auswählen
  • Add more ZIP auswählen und
  • das TWRP-ZIP File mit auswählen (gem. Video)
  • Dann Swipe to Install
  • Nachdem die Installation abgeschlossen ist, nicht rebooten sondern
  • Wipe Cache auswählen
  • Dann Reboot > Recovery => Dies bootet wieder nach TWRP
  • Nun über Install die GApps mit installieren (Minde the Gapps ZIP)
  • Nun Reboot System