Hetzner - DokuWiki

Docker
K (Konfiguration von Shipyard)
 
(16 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
'''Einführung'''
+
{{Languages|Docker}}
 +
 
 +
== Einführung ==
  
 
Ich wurde von einem bekannten gefragt, wie ich die Konfiguration bei [Hetzner](https://www.hetzner.de/) mit Docker genau durchgeführt. Aus dieser Diskussion ist dieser Blog Artikel entstanden, in dem ich detailliert beschreibe, wie ich diese Lösung aufgebaut habe.
 
Ich wurde von einem bekannten gefragt, wie ich die Konfiguration bei [Hetzner](https://www.hetzner.de/) mit Docker genau durchgeführt. Aus dieser Diskussion ist dieser Blog Artikel entstanden, in dem ich detailliert beschreibe, wie ich diese Lösung aufgebaut habe.
Zeile 7: Zeile 9:
 
http://www.vr-worlds.de/vr-worlds-de-jetzt-live-auf-shipyard-docker-und-hetzner-infrastruktur/
 
http://www.vr-worlds.de/vr-worlds-de-jetzt-live-auf-shipyard-docker-und-hetzner-infrastruktur/
  
'''Auswahl eines Anbieters'''
+
== Auswahl eines Anbieters ==
  
 
Ich wollte weg von dem aktuellen Amazon Konfiguration und hin zu einer selbstgehosteten Lösung. Nach einigen prüfen verschiedener Angebote habe ich mich entschlossen es mit Hetzner(https://www.hetzner.de/) als Anbieter zu probieren, da dieser in Deutschland basiert ist und einen guten Eindruck gemacht hatte. Eine ansprechende Alternative mit ähnlichen Angeboten gab es aber natürlich auch bei 1&1 (https://www.1und1.de/).
 
Ich wollte weg von dem aktuellen Amazon Konfiguration und hin zu einer selbstgehosteten Lösung. Nach einigen prüfen verschiedener Angebote habe ich mich entschlossen es mit Hetzner(https://www.hetzner.de/) als Anbieter zu probieren, da dieser in Deutschland basiert ist und einen guten Eindruck gemacht hatte. Eine ansprechende Alternative mit ähnlichen Angeboten gab es aber natürlich auch bei 1&1 (https://www.1und1.de/).
Zeile 13: Zeile 15:
 
https://serverboerse.de/index.php?country=DE
 
https://serverboerse.de/index.php?country=DE
  
[[Datei:Hetznerserverboerse.png]]
+
[[Datei:Hetznerserverboerse.png|450px]]
  
  
Zeile 21: Zeile 23:
 
Allerdings möchte ich nicht behaupten eine komplette Marktanalyse gemacht zu haben und kann mir durchaus vorstellen, dass es andere Anbieter mit besseren Angeboten gibt. Der Markt auch wenn man sich nur auf deutsche Anbieter beschränkt ist unüberschaubar groß.
 
Allerdings möchte ich nicht behaupten eine komplette Marktanalyse gemacht zu haben und kann mir durchaus vorstellen, dass es andere Anbieter mit besseren Angeboten gibt. Der Markt auch wenn man sich nur auf deutsche Anbieter beschränkt ist unüberschaubar groß.
  
'''Architektur Überlegungen Basis Betriebsystem'''
+
== Architektur Überlegungen Basis Betriebsystem ==
  
 
Als nächstes stand für mich an, welches Betriebssystem. Windows fiel dabei sehr schnell raus, da dies hohe Lizenzkosten im Monat verursacht hätte, zudem bin ich seit 1992 mit Unix (AIX) und Linux Systemen vertraut und hatte daher keine Berührungsängste.
 
Als nächstes stand für mich an, welches Betriebssystem. Windows fiel dabei sehr schnell raus, da dies hohe Lizenzkosten im Monat verursacht hätte, zudem bin ich seit 1992 mit Unix (AIX) und Linux Systemen vertraut und hatte daher keine Berührungsängste.
  
Am Ende habe ich mich für CentOS 7.3 entschieden, da es in folgenden Punkten mich überzeugte: (https://www.centos.org/)
+
Am Ende habe ich mich für CentOS 7.3 entschieden, da es in folgenden Punkten mich überzeugte: [https://www.centos.org/]
  
 
* Von Hetzner unterstützt
 
* Von Hetzner unterstützt
Zeile 31: Zeile 33:
 
* Hohe Stabilität
 
* Hohe Stabilität
 
* Aktive Community
 
* Aktive Community
* Guten Enterprise Support (durch die nähe zu [Red Hat Linux](https://www.redhat.com/de))
+
* Guten Enterprise Support (durch die nähe zu Red Hat Linux [https://www.redhat.com/de])
  
Die einzige ernsthafte Alternative wäre für mich noch [Debian](http://www.debian.org/)“ gewesen.
+
Die einzige ernsthafte Alternative wäre für mich noch „Debian [http://www.debian.org/] gewesen.
  
[[Datei:auswahl.png]]
+
[[Datei:auswahl.png|450px]]
  
'''Überlegung Basisaufbau von Docker'''
+
== Überlegung Basisaufbau von Docker ==
  
 
Für meine Webseite habe ich folgende Basisfunktionen mir vorgestellt.
 
Für meine Webseite habe ich folgende Basisfunktionen mir vorgestellt.
Zeile 43: Zeile 45:
 
Als Dienste soll folgendes zur Verfügung stehen:
 
Als Dienste soll folgendes zur Verfügung stehen:
  
* [Ghost](https://github.com/TryGhost/Ghost) als Blog-Service
+
* Ghost [https://github.com/TryGhost/Ghost] als Blog-Service
* [ownCloud](https://owncloud.org/) als Dateispeicher, vor allem um mit Partnern und Kunden Dateien auszutauschen
+
* ownCloud [https://owncloud.org/] als Dateispeicher, vor allem um mit Partnern und Kunden Dateien auszutauschen
* [GITLab](https://about.gitlab.com/) um zusammen mit Partnern an Software gemeinsam zu Entwickeln. Zudem hat es minimale Wiki und TaskPlanung, um die Projektentwicklung zu koordinieren
+
* GITLab [https://about.gitlab.com/] um zusammen mit Partnern an Software gemeinsam zu Entwickeln. Zudem hat es minimale Wiki und TaskPlanung, um die Projektentwicklung zu koordinieren
* [Shipyard](https://shipyard-project.com/) damit auch Remote eine Verwaltung der Docker Container über eine Oberfläche möglich ist.
+
* Shipyard [https://shipyard-project.com/] damit auch Remote eine Verwaltung der Docker Container über eine Oberfläche möglich ist.
  
Damit diese Dienste über einen Port (80 für HTTP bzw. 443 für HTTPS) ansprechbar sein sollen, wird [NGINX](https://nginx.org/en/) als Proxy verwendet.
+
Damit diese Dienste über einen Port (80 für HTTP bzw. 443 für HTTPS) ansprechbar sein sollen, wird NGINX [https://nginx.org/en/] als Proxy verwendet.
  
Als Datenbank für Ghost und ownCloud soll [MariaDb](https://mariadb.org/) verwendet werden.
+
Als Datenbank für Ghost und ownCloud soll MariaDb [https://mariadb.org/] verwendet werden.
 
Im Schaubild stellt sich dies dann folgendermaßen dar:
 
Im Schaubild stellt sich dies dann folgendermaßen dar:
  
[[Datei:Schaubild1.png]]
+
[[Datei:Schaubild1.png|450px]]
  
 
Damit das alles korrekt zusammen spielt, müssen die Komponenten in folgender Reihenfolge aufgesetzt werden:
 
Damit das alles korrekt zusammen spielt, müssen die Komponenten in folgender Reihenfolge aufgesetzt werden:
Zeile 68: Zeile 70:
 
Damit man mit der Konfiguration beginnen kann, benötigt man die folgenden beiden Tools, sofern man auf Windows arbeitet. (Wird Linux als Client verwendet müssen keine zusätzlichen Tools installiert werden, da ssh und scp bereits vorhanden sind)
 
Damit man mit der Konfiguration beginnen kann, benötigt man die folgenden beiden Tools, sofern man auf Windows arbeitet. (Wird Linux als Client verwendet müssen keine zusätzlichen Tools installiert werden, da ssh und scp bereits vorhanden sind)
  
* Putty als Kommandozeile (http://www.putty.org/)
+
* Putty als Kommandozeile [http://www.putty.org/]
* Und WinScp zum Hoch und Runter laden von Dateien (https://winscp.net/eng/index.php)
+
* Und WinScp zum Hoch und Runter laden von Dateien [https://winscp.net/eng/index.php]
  
'''Basiskonfiguration von CentOS und Installation von Docker'''
+
== Basiskonfiguration von CentOS und Installation von Docker ==
  
 
Nach der Installation von CentOS sollte zunächst ein Update durchgeführt werden:
 
Nach der Installation von CentOS sollte zunächst ein Update durchgeführt werden:
  
```
+
<code>
yum -y update
+
yum -y update
```
+
</code>
  
 
Anschließend kommt die Installation von Docker
 
Anschließend kommt die Installation von Docker
  
```
+
<code>
yum -y install docker docker-registry
+
yum -y install docker docker-registry
```
+
</code>
  
 
Damit Docker auch automatisch beim neustart läuft, muss der Docker Service noch eingerichtet werden:
 
Damit Docker auch automatisch beim neustart läuft, muss der Docker Service noch eingerichtet werden:
  
```
+
<code>
systemctl enable docker.service
+
systemctl enable docker.service
systemctl start docker.service
+
systemctl start docker.service
```
+
</code>
  
 
Anschließend kann man prüfen, ob alles ordentlich konfiugriert ist in dem man den Status abfragt:
 
Anschließend kann man prüfen, ob alles ordentlich konfiugriert ist in dem man den Status abfragt:
  
```
+
<code>
root@CentOS-73-64-minimal ~]# systemctl status docker.service
+
root@CentOS-73-64-minimal ~]# systemctl status docker.service
docker.service - Docker Application Container Engine
+
docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
+
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor   preset: disabled)
 
   Active: active (running) since Fri 2017-03-31 22:14:56 CEST; 1 months 0 days ago
 
   Active: active (running) since Fri 2017-03-31 22:14:56 CEST; 1 months 0 days ago
 
     Docs: http://docs.docker.com
 
     Docs: http://docs.docker.com
Zeile 103: Zeile 105:
 
   Memory: 107.5M
 
   Memory: 107.5M
 
   CGroup: /system.slice/docker.service
 
   CGroup: /system.slice/docker.service
```
+
</code>
  
'''Konfiguration der MariaDB und Einführung in Grundlegende Docker Befehle'''
+
== Konfiguration der MariaDB und Einführung in Grundlegende Docker Befehle ==
  
 
Damit Ghost und die ownCloud auf eine zentrale Datenbank zugreifen können, muss diese als erster Container installiert werden.
 
Damit Ghost und die ownCloud auf eine zentrale Datenbank zugreifen können, muss diese als erster Container installiert werden.
  
Auch wenn Docker viel Arbeit abnimmt sind ein paar Vorüberlegungen zu treffen: (Es ist hilfreich sich auch die Dokumentation vom Docker Hub hierzu anzusehen https://hub.docker.com/_/mariadb/)
+
Auch wenn Docker viel Arbeit abnimmt sind ein paar Vorüberlegungen zu treffen: (Es ist hilfreich sich auch die Dokumentation vom Docker Hub hierzu anzusehen [https://hub.docker.com/_/mariadb/] )
  
 
* Welchen Namen soll die MariaDb verwenden? Ich habe „nicht perfekt leider ghost-mysql verwendet“.
 
* Welchen Namen soll die MariaDb verwenden? Ich habe „nicht perfekt leider ghost-mysql verwendet“.
Zeile 118: Zeile 120:
 
Die Daten werden im Home abgelegt. Ein entsprechendes Data Verzeichnis wurde erzeugt:
 
Die Daten werden im Home abgelegt. Ein entsprechendes Data Verzeichnis wurde erzeugt:
  
```
+
<code>
mkdir /home/data
+
mkdir /home/data
mkdir /home/data/MariaDb
+
mkdir /home/data/MariaDb
```
+
</code>
  
 
Auf Basis dieser Überlegungen habe ich folgende Konfiguration gewählt:
 
Auf Basis dieser Überlegungen habe ich folgende Konfiguration gewählt:
Zeile 130: Zeile 132:
 
* Docker Image das zu verwenden ist: mariadb
 
* Docker Image das zu verwenden ist: mariadb
  
```
+
<code>
docker run --name ghost-mysql -v /home/data/MariaDb/:/var/lib/mysql:z -e MYSQL_ROOT_PASSWORD=XXXXXXX -d -p 3306:3306 mariadb
+
docker run --name ghost-mysql -v /home/data/MariaDb/:/var/lib/mysql:z -e MYSQL_ROOT_PASSWORD=XXXXXXX -d -p 3306:3306 mariadb
```
+
</code>
  
 
Mit „docker ps“ kann man sich nun ansehen, ob die Datenbank korrekt läuft:
 
Mit „docker ps“ kann man sich nun ansehen, ob die Datenbank korrekt läuft:
  
```
+
<code>
 
[root@CentOS-73-64-minimal ~]# docker ps
 
[root@CentOS-73-64-minimal ~]# docker ps
 
CONTAINER ID        IMAGE                          COMMAND                  CREATED            STATUS                PORTS                                                                                      NAMES
 
CONTAINER ID        IMAGE                          COMMAND                  CREATED            STATUS                PORTS                                                                                      NAMES
 
d952d2b55a4e        mariadb                        "docker-entrypoint.sh"  3 weeks ago        Up 3 weeks            0.0.0.0:3306->3306/tcp                                                                      ghost-mysql
 
d952d2b55a4e        mariadb                        "docker-entrypoint.sh"  3 weeks ago        Up 3 weeks            0.0.0.0:3306->3306/tcp                                                                      ghost-mysql
```
+
</code>
  
 
Das Verzeichnis hat auch die entsprechenden Daten der MariaDB:
 
Das Verzeichnis hat auch die entsprechenden Daten der MariaDB:
[[Datei:Mariadb.png]]
+
 
 +
[[Datei:Mariadb.png|450px]]
  
 
Möchten Sie einen laufende Container löschen, dann können Sie das mit „docker rm“ durchführen. Sollte der Container noch laufen, kann man mit „-f“ das löschen erzwingen:
 
Möchten Sie einen laufende Container löschen, dann können Sie das mit „docker rm“ durchführen. Sollte der Container noch laufen, kann man mit „-f“ das löschen erzwingen:
[[Datei:Dockerrm.png]]
+
 
 +
[[Datei:Dockerrm.png|450px]]
  
 
Mit den Kommando „docker start“ kann man einen stehenden Container wieder neu starten. Mit „restart“ beenden und neu starten und mit „docker stop“ natürlich den Container beenden:
 
Mit den Kommando „docker start“ kann man einen stehenden Container wieder neu starten. Mit „restart“ beenden und neu starten und mit „docker stop“ natürlich den Container beenden:
[[Datei:Dockerrestart.png]]
+
 
 +
[[Datei:Dockerrestart.png|450px]]
  
 
Sollte das Docker-Image nicht starten, kann man ggf. ohne die Detach Option „-d“ den Fehler erkennen:
 
Sollte das Docker-Image nicht starten, kann man ggf. ohne die Detach Option „-d“ den Fehler erkennen:
[[Datei:Detach.png]]
+
 
 +
[[Datei:Detach.png|450px]]
  
 
In diesem Fall „chown“ error, hat die Option „:z“ gefehlt, damit das Verzeichnis auch korrekt gemounted wird, so wäre es korrekt:
 
In diesem Fall „chown“ error, hat die Option „:z“ gefehlt, damit das Verzeichnis auch korrekt gemounted wird, so wäre es korrekt:
[[Datei:Mount.png]]
+
 
 +
[[Datei:Mount.png|450px]]
  
 
Die installierten Images (also die Basisplattform für jeden Container) kann man mit „docker images“ angezeigt bekommen:
 
Die installierten Images (also die Basisplattform für jeden Container) kann man mit „docker images“ angezeigt bekommen:
[[Datei:Images.png]]
+
 
 +
[[Datei:Images.png|450px]]
  
 
Mit dieser Konfiguration ist es anschließend möglich auch mit bspw. HeidiSQL (https://www.heidisql.com/download.php) auf die Datenbank zugreifen zu können.
 
Mit dieser Konfiguration ist es anschließend möglich auch mit bspw. HeidiSQL (https://www.heidisql.com/download.php) auf die Datenbank zugreifen zu können.
  
 
Allerdings muss man in diesen Fall (ich würde es immer nur temporär machen) die Firewall des Servers um eine Regeln bei Hetzner erweitern und die IP auf die eigene Einschränken:
 
Allerdings muss man in diesen Fall (ich würde es immer nur temporär machen) die Firewall des Servers um eine Regeln bei Hetzner erweitern und die IP auf die eigene Einschränken:
[[Datei:Firewall1.png]]
+
 
 +
[[Datei:Firewall1.png|450px]]
  
 
Anschließend sollte es möglich sein, sich mit der mySQL/MariaDb Datenbank zu verbinden:
 
Anschließend sollte es möglich sein, sich mit der mySQL/MariaDb Datenbank zu verbinden:
[[Datei:Mysqlconnect.png]]
+
 
 +
[[Datei:Mysqlconnect.png|450px]]
  
 
Mit dem Kommando „docker logs ghost-mysql“ ist es möglich das Log des Container anzusehen:
 
Mit dem Kommando „docker logs ghost-mysql“ ist es möglich das Log des Container anzusehen:
[[Datei:Dockerlogs.png]]
 
  
'''Konfiguration von Ghost als Blog'''
+
[[Datei:Dockerlogs.png|450px]]
 +
 
 +
== Konfiguration von Ghost als Blog ==
  
 
Als nächstes ist Ghost auf der Maschine zu installieren.
 
Als nächstes ist Ghost auf der Maschine zu installieren.
Zeile 184: Zeile 195:
 
Der Start von Docker beläuft sich hier dann auf:
 
Der Start von Docker beläuft sich hier dann auf:
  
```
+
<code>
mkdir /home/data/Ghost
+
mkdir /home/data/Ghost
docker run --name blog -p 2368:2368 -v /home/data/Ghost/:/var/lib/ghost:z -d --link ghost-mysql:mysql ghost
+
docker run --name blog -p 2368:2368 -v /home/data/Ghost/:/var/lib/ghost:z -d --link ghost-mysql:mysql ghost
```
+
</code>
  
 
Auf die gesamte Konfiguration werde ich in diesem Artikel nicht eingehen, da dies ein eigener Artikel wert wäre. Ich beschränke mich hier nur auf das wesentliche, nämlich das Ghost intern auf die SQL Datenbank umgestellt werden muss, statt die interne zu verwenden:
 
Auf die gesamte Konfiguration werde ich in diesem Artikel nicht eingehen, da dies ein eigener Artikel wert wäre. Ich beschränke mich hier nur auf das wesentliche, nämlich das Ghost intern auf die SQL Datenbank umgestellt werden muss, statt die interne zu verwenden:
  
 
Hier muss die Datei „config.js“ angepasst werden. Am einfachsten geht dies über WinSCP. Man kann natürlich auch „vi“ verwenden auf den Server, wenn man sich damit sicher genug fühlt:(https://scotch.io/tutorials/getting-started-with-vim-an-interactive-guide)
 
Hier muss die Datei „config.js“ angepasst werden. Am einfachsten geht dies über WinSCP. Man kann natürlich auch „vi“ verwenden auf den Server, wenn man sich damit sicher genug fühlt:(https://scotch.io/tutorials/getting-started-with-vim-an-interactive-guide)
[[Datei:Configjs.png]]
+
 
 +
[[Datei:Configjs.png|450px]]
  
 
Hier ist die Datenbank konfiguration entsprechend einzutragen. Als Hostnamen verwendet man „mysql“ da dies auch so im Docker definiert wurde. Als User habe ich „blog_user“ verwendet und ein password vergeben: (ACHTUNG: Die Konfiguration muss in "development" gemacht werden)
 
Hier ist die Datenbank konfiguration entsprechend einzutragen. Als Hostnamen verwendet man „mysql“ da dies auch so im Docker definiert wurde. Als User habe ich „blog_user“ verwendet und ein password vergeben: (ACHTUNG: Die Konfiguration muss in "development" gemacht werden)
[[Datei:Editconfigjs.png]]
+
 
 +
[[Datei:Editconfigjs.png|450px]]
  
 
Jetzt muss noch in der MariaDb die Datenbank angelegt und der User eingerichtet werden.
 
Jetzt muss noch in der MariaDb die Datenbank angelegt und der User eingerichtet werden.
  
 
Zunächst wird die Datenbank erstellt über HeidiSQL:
 
Zunächst wird die Datenbank erstellt über HeidiSQL:
[[Datei:Createdbblog.png]]
+
 
 +
[[Datei:Createdbblog.png|450px]]
  
 
Und in diesem Dialog folgendes eingeben:
 
Und in diesem Dialog folgendes eingeben:
[[Datei:Dbcreateheidi.png]]
+
 
 +
[[Datei:Dbcreateheidi.png|450px]]
  
 
Anschließend ist der User noch zu berechtigen auf der Datenbank:
 
Anschließend ist der User noch zu berechtigen auf der Datenbank:
[[adduser1.png]]
+
 
 +
[[Datei:adduser1.png|450px]]
  
 
Und für diesen das Passwort vergeben und alle notwendigen Rechte:
 
Und für diesen das Passwort vergeben und alle notwendigen Rechte:
[[Datei:Userrights2.png]]
+
 
 +
[[Datei:Userrights2.png|450px]]
  
 
Anschließend muss der Blog neu gestartet werden, damit die neuen Konfigurationen aus der config.js gezogen werden:
 
Anschließend muss der Blog neu gestartet werden, damit die neuen Konfigurationen aus der config.js gezogen werden:
  
[[Datei:Restart.png]]
+
[[Datei:Restart.png|450px]]
  
 
Hat alles geklappt, dann ist der Blog wieder über „http“ verfügbar und in der MariaDb sind jetzt zahlreiche Tabellen verfügbar: (Neu laden mit F5, damit dies auch in der HeidiSQL sichtbar wird!)
 
Hat alles geklappt, dann ist der Blog wieder über „http“ verfügbar und in der MariaDb sind jetzt zahlreiche Tabellen verfügbar: (Neu laden mit F5, damit dies auch in der HeidiSQL sichtbar wird!)
[[Datei:Displaydbheidi.png]]
 
  
'''ownCloud und GitLab einrichten'''
+
[[Datei:Displaydbheidi.png|450px]]
 +
 
 +
== ownCloud und GitLab einrichten ==
  
 
Prinzipiell ist für diese beiden Dienste ähnlich vorzugehen, wie bereits für Ghost beschrieben.
 
Prinzipiell ist für diese beiden Dienste ähnlich vorzugehen, wie bereits für Ghost beschrieben.
Zeile 226: Zeile 244:
 
Eine entsprechende Datenbank in der MariaDB anlegen:
 
Eine entsprechende Datenbank in der MariaDB anlegen:
  
[[Datei:showdb.png]]
+
[[Datei:showdb.png|450px]]
  
Für die ownCloud habe ich folgendes Kommando verwendet:
+
Für die ownCloud habe ich folgendes Kommando verwendet:
  
```
+
<code>
docker run --name owncloud -v /home/data/owncloud:/var/www/html:z -p 8082:80 --link ghost-mysql:mysql -d owncloud:8.1
+
docker run --name owncloud -v /home/data/owncloud:/var/www/html:z -p 8082:80 --link ghost-mysql:mysql -d owncloud:8.1
```
+
</code>
  
 
Die entsprechenden Konfigurationen für die ownCloud MariaDB auch einstellen:
 
Die entsprechenden Konfigurationen für die ownCloud MariaDB auch einstellen:
  
[[Datei:configown.png]]
+
[[Datei:configown.png|450px]]
  
 
Anschließend sind in der MariaDB auch die entsprechenden Tabellen:
 
Anschließend sind in der MariaDB auch die entsprechenden Tabellen:
  
[[Datei:dbtables.png]]
+
[[Datei:dbtables.png|450px]]
  
 
Für Gitlab habe ich folgendes Kommando verwendet:
 
Für Gitlab habe ich folgendes Kommando verwendet:
  
```
+
<code>
docker run --detach --name gitlab --hostname git.vr-worlds.de --sysctl net.core.somaxconn=1024 --ulimit sigpending=62793 --ulimit nproc=131072 --ulimit nofile=60000 --ulimit core=0 --publish 8443:443 --publish 8083:80 --publish 8022:22 --publish 8060:8060 --restart always --volume /home/data/gitlab/config:/etc/gitlab:z --volume /home/data/gitlab/logs:/var/log/gitlab:z --volume /home/data/gitlab/data:/var/opt/gitlab:z --volume /etc/localtime:/etc/localtime gitlab/gitlab-ce
+
docker run --detach --name gitlab --hostname git.vr-worlds.de --sysctl net.core.somaxconn=1024 --ulimit sigpending=62793 --ulimit nproc=131072 --ulimit nofile=60000 --ulimit core=0 --publish 8443:443 --publish 8083:80 --publish 8022:22 --publish 8060:8060 --restart always --volume /home/data/gitlab/config:/etc/gitlab:z --volume /home/data/gitlab/logs:/var/log/gitlab:z --volume /home/data/gitlab/data:/var/opt/gitlab:z --volume /etc/localtime:/etc/localtime gitlab/gitlab-ce
```
+
</code>
  
'''NGINX Einrichten'''
+
== NGINX Einrichten ==
  
 
Nun kommt der spannende Teil des Artikels. Die NGINX soll so konfiguriert werden, dass Anfragen an den Port 80 an die entsprechenden Docker-Container durchgereicht werden.
 
Nun kommt der spannende Teil des Artikels. Die NGINX soll so konfiguriert werden, dass Anfragen an den Port 80 an die entsprechenden Docker-Container durchgereicht werden.
Zeile 259: Zeile 277:
 
Hierzu müssen zunächst alle diese Sub-Domains zur gleichen IP Adresse des Servers eingerichtet werden: (hier verwende ich leider noch Route53 (https://aws.amazon.com/route53) von AWS Amazon, da GoDaddy leider keine DE Domänen übernehmen kann (https://de.godaddy.com/help/about-de-domains-5825)).
 
Hierzu müssen zunächst alle diese Sub-Domains zur gleichen IP Adresse des Servers eingerichtet werden: (hier verwende ich leider noch Route53 (https://aws.amazon.com/route53) von AWS Amazon, da GoDaddy leider keine DE Domänen übernehmen kann (https://de.godaddy.com/help/about-de-domains-5825)).
  
[[Datei:awsdns.png]]
+
[[Datei:awsdns.png|450px]]
  
 
Es kann einige Zeit dauern, bis die neuen Adressen entsprechend über DNS verfügbar sind. Man kann dies vom eigenen PC regelmäßig mit „nslookup“ prüfen:
 
Es kann einige Zeit dauern, bis die neuen Adressen entsprechend über DNS verfügbar sind. Man kann dies vom eigenen PC regelmäßig mit „nslookup“ prüfen:
  
[[Datei:nslookup.png]]
+
[[Datei:nslookup.png|450px]]
  
 
Für die NGINX benötigen wir folgende Vorüberlegungen:
 
Für die NGINX benötigen wir folgende Vorüberlegungen:
Zeile 274: Zeile 292:
 
Entsprechend könnte man folgendes Kommando verwenden (das wir aber nicht verwenden werden):
 
Entsprechend könnte man folgendes Kommando verwenden (das wir aber nicht verwenden werden):
  
```
+
<code>
docker run -v /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d/ -v /home/data/Nginx/certs/:/etc/nginx/certs -v /home/data/Nginx/logs/:/var/log/nginx --name nginxserver -p 80:80 -p 443:443 -d --link blog:blog --link gitlab:gitlab --link owncloud:owncloud
+
docker run -v /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d/ -v /home/data/Nginx/certs/:/etc/nginx/certs -v /home/data/Nginx/logs/:/var/log/nginx --name nginxserver -p 80:80 -p 443:443 -d --link blog:blog --link gitlab:gitlab --link owncloud:owncloud
```
+
</code>
  
 
Da man diese Konfiguration öfters ändern muss, bspw. wenn neue Hosts hinzukommen empfiehlt es sich die Konfiguration des Docker-Containers in einer Datei abzulegen und „docker-compose“ zu verwenden. (https://docs.docker.com/compose/install/)
 
Da man diese Konfiguration öfters ändern muss, bspw. wenn neue Hosts hinzukommen empfiehlt es sich die Konfiguration des Docker-Containers in einer Datei abzulegen und „docker-compose“ zu verwenden. (https://docs.docker.com/compose/install/)
Zeile 282: Zeile 300:
 
Die Installation erfolgt so direkt über „curl“:
 
Die Installation erfolgt so direkt über „curl“:
  
```
+
<code>
curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
+
curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
```
+
</code>
  
 
Docker Compose hat anschließend noch keine Ausführungsberechtigung, diese müssen mit chmod noch hinzugefügt werden:
 
Docker Compose hat anschließend noch keine Ausführungsberechtigung, diese müssen mit chmod noch hinzugefügt werden:
[[Datei:chmodax.png]]
+
[[Datei:chmodax.png|450px]]
  
 
Nun können wir testen, ob „docker-compose“ korrekt funktioniert:
 
Nun können wir testen, ob „docker-compose“ korrekt funktioniert:
  
[[Datei:testdockercompose.png]]
+
[[Datei:testdockercompose.png|450px]]
  
 
Hierzu legen wir ein Verzeichnis im Root Homeverzeichnis an und dort ein „docker-compose.yml“:
 
Hierzu legen wir ein Verzeichnis im Root Homeverzeichnis an und dort ein „docker-compose.yml“:
  
[[Datei:compose2.png]]
+
[[Datei:compose2.png|450px]]
  
 
Die Datei sollte wie folgt aussehen:
 
Die Datei sollte wie folgt aussehen:
  
```
+
<code>
version: '2'
+
version: '2'
services:
+
services:
 
   nginxserver:
 
   nginxserver:
 
     container_name: nginxserver
 
     container_name: nginxserver
Zeile 317: Zeile 335:
 
       - /home/data/Nginx/certs/:/etc/nginx/certs:z
 
       - /home/data/Nginx/certs/:/etc/nginx/certs:z
 
       - /home/data/Nginx/logs/:/var/log/nginx:z
 
       - /home/data/Nginx/logs/:/var/log/nginx:z
```
+
</code>
  
 
Anschließend kann man mit „docker-compose“ die „nginx“ starten:
 
Anschließend kann man mit „docker-compose“ die „nginx“ starten:
  
[[Datei:startcompose.png]]
+
[[Datei:startcompose.png|450px]]
  
 
Nachdem Nginx gestartet ist muss die Konfiguration erstellt werden. Für jede Subdomain ist das durchreichen zum entsprechenden gemappten Docker Container einzutragen:
 
Nachdem Nginx gestartet ist muss die Konfiguration erstellt werden. Für jede Subdomain ist das durchreichen zum entsprechenden gemappten Docker Container einzutragen:
  
[[Datei:map.png]]
+
[[Datei:map.png|450px]]
  
 
Nachdem die Konfiguration durchgeführt wurde, kann die „nginx“ neu gestartet werden:
 
Nachdem die Konfiguration durchgeführt wurde, kann die „nginx“ neu gestartet werden:
  
[[Datei:Restartnginx.png]]
+
[[Datei:Restartnginx.png|450px]]
  
 
Sollte es nicht funktionieren, kann „docker logs“ hier weiterhelfen:
 
Sollte es nicht funktionieren, kann „docker logs“ hier weiterhelfen:
[[Datei:Loghelp.png]]
+
[[Datei:Loghelp.png|450px]]
  
'''Konfiguration von Shipyard'''
+
== Konfiguration von Shipyard ==
  
 
Als letztes Element habe ich noch Shipyard hinzugefügt, damit auch remote eine Verwaltung der Docker Container möglich ist.
 
Als letztes Element habe ich noch Shipyard hinzugefügt, damit auch remote eine Verwaltung der Docker Container möglich ist.
Zeile 344: Zeile 362:
 
Das Deployment erfolgt hier nicht über "docker run" sondern über curl:
 
Das Deployment erfolgt hier nicht über "docker run" sondern über curl:
  
```
+
<code>
curl -sSL https://shipyard-project.com/deploy | bash -s
+
curl -sSL https://shipyard-project.com/deploy | bash -s
```
+
</code>
  
 
Anschließend ist shipyard über Port 8080 verfügbar und es wurde einige Container installiert:
 
Anschließend ist shipyard über Port 8080 verfügbar und es wurde einige Container installiert:
  
```
+
<code>
 
[root@CentOS-73-64-minimal ~]# docker ps
 
[root@CentOS-73-64-minimal ~]# docker ps
 
CONTAINER ID        IMAGE                          COMMAND                  CREATED            STATUS                PORTS                                                                                      NAMES
 
CONTAINER ID        IMAGE                          COMMAND                  CREATED            STATUS                PORTS                                                                                      NAMES
Zeile 360: Zeile 378:
 
d710310dae40        microbox/etcd:latest          "/bin/etcd -addr 176."  2 weeks ago        Up 2 weeks            0.0.0.0:4001->4001/tcp, 0.0.0.0:7001->7001/tcp                                              shipyard-discovery
 
d710310dae40        microbox/etcd:latest          "/bin/etcd -addr 176."  2 weeks ago        Up 2 weeks            0.0.0.0:4001->4001/tcp, 0.0.0.0:7001->7001/tcp                                              shipyard-discovery
 
0fe8eb95b8fb        rethinkdb                      "rethinkdb --bind all"  2 weeks ago        Up 2 weeks            8080/tcp, 28015/tcp, 29015/tcp                                                              shipyard-rethinkdb
 
0fe8eb95b8fb        rethinkdb                      "rethinkdb --bind all"  2 weeks ago        Up 2 weeks            8080/tcp, 28015/tcp, 29015/tcp                                                              shipyard-rethinkdb
```
+
</code>
  
 
Nun muss “Shipyard” nur noch in die nginx eingebunden werden und konfiguiert.
 
Nun muss “Shipyard” nur noch in die nginx eingebunden werden und konfiguiert.
 
In die nginx Konfiguration ist folgendes zu ergänzen: (/home/data/Nginx/sites_enabled)
 
In die nginx Konfiguration ist folgendes zu ergänzen: (/home/data/Nginx/sites_enabled)
  
[[Datei:SiteEnabled.png]]
+
[[Datei:SiteEnabled.png|450px]]
  
 
Jetzt zahlt es sich erstmals aus über „docker-compose“ die Konfiguration für Nginx gemacht zu haben, dann diese ist nun einfach zu erweitern:
 
Jetzt zahlt es sich erstmals aus über „docker-compose“ die Konfiguration für Nginx gemacht zu haben, dann diese ist nun einfach zu erweitern:
  
[[Datei:Addshipyard.png]]
+
[[Datei:Addshipyard.png|450px]]
  
 
Anschließend kann der Container neu gebaut werden mittels „docker-compose up -d“:
 
Anschließend kann der Container neu gebaut werden mittels „docker-compose up -d“:
  
[[Datei:Compose3.png]]
+
[[Datei:Compose3.png|450px]]
  
 
'''Konfiguration über Docker-Compose zentral steuern'''
 
'''Konfiguration über Docker-Compose zentral steuern'''
Zeile 379: Zeile 397:
 
Damit die Automatisierung von Docker wirklich zum tragen kommt, werde ich nun die komplette Konfiguration in einem neuen Docker-Compose File zusammen führen:
 
Damit die Automatisierung von Docker wirklich zum tragen kommt, werde ich nun die komplette Konfiguration in einem neuen Docker-Compose File zusammen führen:
  
[[Datei:Compose4.png]]
+
[[Datei:Compose4.png|450px]]
  
 
Die Datei hat folgendes aussehen:
 
Die Datei hat folgendes aussehen:
  
```
+
<code>
version: '2.1'
+
version: '2.1'
services:
+
services:
 
   ghost-mysql:
 
   ghost-mysql:
 
     container_name: ghost-mysql
 
     container_name: ghost-mysql
Zeile 453: Zeile 471:
 
       - /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d:z
 
       - /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d:z
 
       - /home/data/Nginx/certs/:/etc/nginx/certs:z
 
       - /home/data/Nginx/certs/:/etc/nginx/certs:z
```
+
</code>
  
 
Nun können wir alle Container wieder löschen und dann mit „docker-compose“ neu anlegen:
 
Nun können wir alle Container wieder löschen und dann mit „docker-compose“ neu anlegen:
  
[[Datei:test2.png]]
+
[[Datei:test2.png|450px]]
  
'''Konfiguration der Firewall bei Hetzner'''
+
== Konfiguration der Firewall bei Hetzner ==
  
 
Meine Firewall Konfiguration bei Hetzner, sieht wie folgt aus:
 
Meine Firewall Konfiguration bei Hetzner, sieht wie folgt aus:
[[Datei:Hetzner.png]]
+
[[Datei:Hetzner.png|450px]]
  
 
Die Regel #1 ermögicht es, dass ICMP Packete, bspw. Ping aber auch Requests bezüglich ermitteln der Netzwerkbandbreite (MTU-Size etc.) ermittelt werden können. Es empfiehlt sich daher dies auf „accept“ stehen zu lassen.
 
Die Regel #1 ermögicht es, dass ICMP Packete, bspw. Ping aber auch Requests bezüglich ermitteln der Netzwerkbandbreite (MTU-Size etc.) ermittelt werden können. Es empfiehlt sich daher dies auf „accept“ stehen zu lassen.
Zeile 468: Zeile 486:
 
Die Regel #2 ermöglicht es, sich auf dem Server mit ssh zu verbinden. Man muss diesen Port nicht immer auf lassen und kann diesen, wenn keine Wartung ansteht auf „discard“ stellen. Anschließend ist eine Verbindung mittels „ssh“ nicht mehr möglich und daher können „putty“ und „winscp“ sich dann nicht mehr verbinden:
 
Die Regel #2 ermöglicht es, sich auf dem Server mit ssh zu verbinden. Man muss diesen Port nicht immer auf lassen und kann diesen, wenn keine Wartung ansteht auf „discard“ stellen. Anschließend ist eine Verbindung mittels „ssh“ nicht mehr möglich und daher können „putty“ und „winscp“ sich dann nicht mehr verbinden:
  
[[Datei:Firewall2.png]]
+
[[Datei:Firewall2.png|450px]]
  
 
Die Regel #3 ist dafür zuständige damit mittels „http“ (port 80) und „https“ (Port 443) auf das System zugegriffen werden kann.
 
Die Regel #3 ist dafür zuständige damit mittels „http“ (port 80) und „https“ (Port 443) auf das System zugegriffen werden kann.
Zeile 475: Zeile 493:
 
Selbstverständlich kann man die Regeln noch weiter optimieren.
 
Selbstverständlich kann man die Regeln noch weiter optimieren.
  
'''Zusammenfassung'''
+
== Zusammenfassung ==
  
 
In diesem Artikel habe ich gezeigt welche Dinge im einzelnen zu tun sind, damit eine Konfiguration mit einem NGINX Proxy und ein paar anderen Container miteinander zusammen spielen. Ich hoffe das dieses recht Praxisnahe Beschreibung hilfreich ist.
 
In diesem Artikel habe ich gezeigt welche Dinge im einzelnen zu tun sind, damit eine Konfiguration mit einem NGINX Proxy und ein paar anderen Container miteinander zusammen spielen. Ich hoffe das dieses recht Praxisnahe Beschreibung hilfreich ist.
  
 
Wenn Sie Unterstützung bei einer Docker Umgebung benötigen, dann kommen Sie genre auf mich zu und kontaktieren Sie mich unter christian.mueller@vr-worlds.de
 
Wenn Sie Unterstützung bei einer Docker Umgebung benötigen, dann kommen Sie genre auf mich zu und kontaktieren Sie mich unter christian.mueller@vr-worlds.de

Aktuelle Version vom 31. Mai 2017, 13:52 Uhr

Inhaltsverzeichnis

Einführung

Ich wurde von einem bekannten gefragt, wie ich die Konfiguration bei [Hetzner](https://www.hetzner.de/) mit Docker genau durchgeführt. Aus dieser Diskussion ist dieser Blog Artikel entstanden, in dem ich detailliert beschreibe, wie ich diese Lösung aufgebaut habe.

Einen groben High-Überblick hatte ich ja bereits unter den folgenden Artikel zu meinen Überlegungen wurde im letzten Monat bereits unter gegeben:

http://www.vr-worlds.de/vr-worlds-de-jetzt-live-auf-shipyard-docker-und-hetzner-infrastruktur/

Auswahl eines Anbieters

Ich wollte weg von dem aktuellen Amazon Konfiguration und hin zu einer selbstgehosteten Lösung. Nach einigen prüfen verschiedener Angebote habe ich mich entschlossen es mit Hetzner(https://www.hetzner.de/) als Anbieter zu probieren, da dieser in Deutschland basiert ist und einen guten Eindruck gemacht hatte. Eine ansprechende Alternative mit ähnlichen Angeboten gab es aber natürlich auch bei 1&1 (https://www.1und1.de/). Ausschlaggebend war, das man relativ neue aber gebrauchte Server bei Hetzner mieten kann: https://serverboerse.de/index.php?country=DE

Hetznerserverboerse.png


Hier fand ich ein günstiges Angebot, dass für meine Ansprüche ausreichend war. Aus meiner bisherigen Erfahrung kann ich sagen, dass ich von Hetzner bisher nicht enttäuscht wurde.

Allerdings möchte ich nicht behaupten eine komplette Marktanalyse gemacht zu haben und kann mir durchaus vorstellen, dass es andere Anbieter mit besseren Angeboten gibt. Der Markt auch wenn man sich nur auf deutsche Anbieter beschränkt ist unüberschaubar groß.

Architektur Überlegungen Basis Betriebsystem

Als nächstes stand für mich an, welches Betriebssystem. Windows fiel dabei sehr schnell raus, da dies hohe Lizenzkosten im Monat verursacht hätte, zudem bin ich seit 1992 mit Unix (AIX) und Linux Systemen vertraut und hatte daher keine Berührungsängste.

Am Ende habe ich mich für CentOS 7.3 entschieden, da es in folgenden Punkten mich überzeugte: [1]

  • Von Hetzner unterstützt
  • Freie Verfügbarkeit
  • Hohe Stabilität
  • Aktive Community
  • Guten Enterprise Support (durch die nähe zu Red Hat Linux [2])

Die einzige ernsthafte Alternative wäre für mich noch „Debian [3] gewesen.

Auswahl.png

Überlegung Basisaufbau von Docker

Für meine Webseite habe ich folgende Basisfunktionen mir vorgestellt.

Als Dienste soll folgendes zur Verfügung stehen:

  • Ghost [4] als Blog-Service
  • ownCloud [5] als Dateispeicher, vor allem um mit Partnern und Kunden Dateien auszutauschen
  • GITLab [6] um zusammen mit Partnern an Software gemeinsam zu Entwickeln. Zudem hat es minimale Wiki und TaskPlanung, um die Projektentwicklung zu koordinieren
  • Shipyard [7] damit auch Remote eine Verwaltung der Docker Container über eine Oberfläche möglich ist.

Damit diese Dienste über einen Port (80 für HTTP bzw. 443 für HTTPS) ansprechbar sein sollen, wird NGINX [8] als Proxy verwendet.

Als Datenbank für Ghost und ownCloud soll MariaDb [9] verwendet werden. Im Schaubild stellt sich dies dann folgendermaßen dar:

Schaubild1.png

Damit das alles korrekt zusammen spielt, müssen die Komponenten in folgender Reihenfolge aufgesetzt werden:

  • Basiskonfiguration von CentOS und Installation von Docker
  • Installation von MariaDb
  • Installation von Ghost als Blog Dienst und anbinden an MariaDb
  • Installation der OwnCloud und anbinden an MariaDb
  • Installation GitLab
  • Installation der NGINX und einrichten des Proxy Routings
  • Shipyard und Einbindung in NGINX
  • Zu guter letzt natürlich noch die Firewall einschränken, damit möglichst wenig Ports offen sind.

Damit man mit der Konfiguration beginnen kann, benötigt man die folgenden beiden Tools, sofern man auf Windows arbeitet. (Wird Linux als Client verwendet müssen keine zusätzlichen Tools installiert werden, da ssh und scp bereits vorhanden sind)

  • Putty als Kommandozeile [10]
  • Und WinScp zum Hoch und Runter laden von Dateien [11]

Basiskonfiguration von CentOS und Installation von Docker

Nach der Installation von CentOS sollte zunächst ein Update durchgeführt werden:

yum -y update

Anschließend kommt die Installation von Docker

yum -y install docker docker-registry

Damit Docker auch automatisch beim neustart läuft, muss der Docker Service noch eingerichtet werden:

systemctl enable docker.service
systemctl start docker.service

Anschließend kann man prüfen, ob alles ordentlich konfiugriert ist in dem man den Status abfragt:

root@CentOS-73-64-minimal ~]# systemctl status docker.service
docker.service - Docker Application Container Engine
  Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor   preset: disabled)
  Active: active (running) since Fri 2017-03-31 22:14:56 CEST; 1 months 0 days ago
    Docs: http://docs.docker.com
Main PID: 13307 (dockerd-current)
  Memory: 107.5M
  CGroup: /system.slice/docker.service

Konfiguration der MariaDB und Einführung in Grundlegende Docker Befehle

Damit Ghost und die ownCloud auf eine zentrale Datenbank zugreifen können, muss diese als erster Container installiert werden.

Auch wenn Docker viel Arbeit abnimmt sind ein paar Vorüberlegungen zu treffen: (Es ist hilfreich sich auch die Dokumentation vom Docker Hub hierzu anzusehen [12] )

  • Welchen Namen soll die MariaDb verwenden? Ich habe „nicht perfekt leider ghost-mysql verwendet“.
  • Über welchen Port möchte man gehen? Ich habe mich entschlossen, den Standard Port 3306 zu verwenden.
  • An welcher Stelle soll die Daten abgelegt werden?
  • Wie lautet das Root Passwort?

Die Daten werden im Home abgelegt. Ein entsprechendes Data Verzeichnis wurde erzeugt:

mkdir /home/data
mkdir /home/data/MariaDb

Auf Basis dieser Überlegungen habe ich folgende Konfiguration gewählt:

  • Name: ghost-mysql
  • Datenverzeichnis nach: /home/data/MariaDb/ mappen
  • SQL Password: XXXXXXX
  • Docker Image das zu verwenden ist: mariadb

docker run --name ghost-mysql -v /home/data/MariaDb/:/var/lib/mysql:z -e MYSQL_ROOT_PASSWORD=XXXXXXX -d -p 3306:3306 mariadb

Mit „docker ps“ kann man sich nun ansehen, ob die Datenbank korrekt läuft:

[root@CentOS-73-64-minimal ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d952d2b55a4e mariadb "docker-entrypoint.sh" 3 weeks ago Up 3 weeks 0.0.0.0:3306->3306/tcp ghost-mysql

Das Verzeichnis hat auch die entsprechenden Daten der MariaDB:

Mariadb.png

Möchten Sie einen laufende Container löschen, dann können Sie das mit „docker rm“ durchführen. Sollte der Container noch laufen, kann man mit „-f“ das löschen erzwingen:

Dockerrm.png

Mit den Kommando „docker start“ kann man einen stehenden Container wieder neu starten. Mit „restart“ beenden und neu starten und mit „docker stop“ natürlich den Container beenden:

Dockerrestart.png

Sollte das Docker-Image nicht starten, kann man ggf. ohne die Detach Option „-d“ den Fehler erkennen:

Detach.png

In diesem Fall „chown“ error, hat die Option „:z“ gefehlt, damit das Verzeichnis auch korrekt gemounted wird, so wäre es korrekt:

Mount.png

Die installierten Images (also die Basisplattform für jeden Container) kann man mit „docker images“ angezeigt bekommen:

Images.png

Mit dieser Konfiguration ist es anschließend möglich auch mit bspw. HeidiSQL (https://www.heidisql.com/download.php) auf die Datenbank zugreifen zu können.

Allerdings muss man in diesen Fall (ich würde es immer nur temporär machen) die Firewall des Servers um eine Regeln bei Hetzner erweitern und die IP auf die eigene Einschränken:

Firewall1.png

Anschließend sollte es möglich sein, sich mit der mySQL/MariaDb Datenbank zu verbinden:

Mysqlconnect.png

Mit dem Kommando „docker logs ghost-mysql“ ist es möglich das Log des Container anzusehen:

Dockerlogs.png

Konfiguration von Ghost als Blog

Als nächstes ist Ghost auf der Maschine zu installieren.

Hier sind auch ein paar Grundüberlegungen durchzuführen:

  • Welcher Port ist zu verwenden? Ich habe hier auch den Standard port 2368 verwendet, der vom Internet nicht erreichbar ist (Zum testen kann man diesen öffnen, wie bei der MariaDb)
  • Der Name soll einfach „blog“ sein.
  • Und die Ablage soll natürlich auch in einem Verzeichnis für die Daten liegen. In diesen Fall haben ich „/home/data/Ghost“ gewählt.
  • Die mySQL Datenbank wird zu ghost-mysql gemapped.

Der Start von Docker beläuft sich hier dann auf:

mkdir /home/data/Ghost
docker run --name blog -p 2368:2368 -v /home/data/Ghost/:/var/lib/ghost:z -d --link ghost-mysql:mysql ghost

Auf die gesamte Konfiguration werde ich in diesem Artikel nicht eingehen, da dies ein eigener Artikel wert wäre. Ich beschränke mich hier nur auf das wesentliche, nämlich das Ghost intern auf die SQL Datenbank umgestellt werden muss, statt die interne zu verwenden:

Hier muss die Datei „config.js“ angepasst werden. Am einfachsten geht dies über WinSCP. Man kann natürlich auch „vi“ verwenden auf den Server, wenn man sich damit sicher genug fühlt:(https://scotch.io/tutorials/getting-started-with-vim-an-interactive-guide)

Configjs.png

Hier ist die Datenbank konfiguration entsprechend einzutragen. Als Hostnamen verwendet man „mysql“ da dies auch so im Docker definiert wurde. Als User habe ich „blog_user“ verwendet und ein password vergeben: (ACHTUNG: Die Konfiguration muss in "development" gemacht werden)

Editconfigjs.png

Jetzt muss noch in der MariaDb die Datenbank angelegt und der User eingerichtet werden.

Zunächst wird die Datenbank erstellt über HeidiSQL:

Createdbblog.png

Und in diesem Dialog folgendes eingeben:

Dbcreateheidi.png

Anschließend ist der User noch zu berechtigen auf der Datenbank:

Adduser1.png

Und für diesen das Passwort vergeben und alle notwendigen Rechte:

Userrights2.png

Anschließend muss der Blog neu gestartet werden, damit die neuen Konfigurationen aus der config.js gezogen werden:

Restart.png

Hat alles geklappt, dann ist der Blog wieder über „http“ verfügbar und in der MariaDb sind jetzt zahlreiche Tabellen verfügbar: (Neu laden mit F5, damit dies auch in der HeidiSQL sichtbar wird!)

Displaydbheidi.png

ownCloud und GitLab einrichten

Prinzipiell ist für diese beiden Dienste ähnlich vorzugehen, wie bereits für Ghost beschrieben.

Für die ownCloud ist auch ein User einzurichten in MariaDb, während sich das bei GitLab einfacher gestaltet. Ich fasse daher nur die wichtigsten Punkte zusammen.

Eine entsprechende Datenbank in der MariaDB anlegen:

Showdb.png

Für die ownCloud habe ich folgendes Kommando verwendet:

docker run --name owncloud -v /home/data/owncloud:/var/www/html:z -p 8082:80 --link ghost-mysql:mysql -d owncloud:8.1

Die entsprechenden Konfigurationen für die ownCloud MariaDB auch einstellen:

Configown.png

Anschließend sind in der MariaDB auch die entsprechenden Tabellen:

Dbtables.png

Für Gitlab habe ich folgendes Kommando verwendet:

docker run --detach --name gitlab --hostname git.vr-worlds.de --sysctl net.core.somaxconn=1024 --ulimit sigpending=62793 --ulimit nproc=131072 --ulimit nofile=60000 --ulimit core=0 --publish 8443:443 --publish 8083:80 --publish 8022:22 --publish 8060:8060 --restart always --volume /home/data/gitlab/config:/etc/gitlab:z --volume /home/data/gitlab/logs:/var/log/gitlab:z --volume /home/data/gitlab/data:/var/opt/gitlab:z --volume /etc/localtime:/etc/localtime gitlab/gitlab-ce

NGINX Einrichten

Nun kommt der spannende Teil des Artikels. Die NGINX soll so konfiguriert werden, dass Anfragen an den Port 80 an die entsprechenden Docker-Container durchgereicht werden. Erfolgen soll dies aufgrund der angegebenen Sub-Domain:

  • www.vr-worlds.de -> Weiterleitung zum Blog
  • cloud.vr-worlds.de -> Weiterleitung an die ownCloud
  • git.vr-worlds.de -> Weiterleitung an GitLab

Hierzu müssen zunächst alle diese Sub-Domains zur gleichen IP Adresse des Servers eingerichtet werden: (hier verwende ich leider noch Route53 (https://aws.amazon.com/route53) von AWS Amazon, da GoDaddy leider keine DE Domänen übernehmen kann (https://de.godaddy.com/help/about-de-domains-5825)).

Awsdns.png

Es kann einige Zeit dauern, bis die neuen Adressen entsprechend über DNS verfügbar sind. Man kann dies vom eigenen PC regelmäßig mit „nslookup“ prüfen:

Nslookup.png

Für die NGINX benötigen wir folgende Vorüberlegungen:

  • Welche Ports werden nach aussen gegben? Natürlich 80 (HTTP) und 443 (HTTPS) in diesen Fall
  • Wir benötigen Links zu den anderen Docker Containern: blog, gitlab, owncloud
  • Der Name soll „nginxserver“ lauten
  • Datenablage für sites-enabled, certs, logs soll im /home/data/Nginx Verzeichnissen erfolgen

Entsprechend könnte man folgendes Kommando verwenden (das wir aber nicht verwenden werden):

docker run -v /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d/ -v /home/data/Nginx/certs/:/etc/nginx/certs -v /home/data/Nginx/logs/:/var/log/nginx --name nginxserver -p 80:80 -p 443:443 -d --link blog:blog --link gitlab:gitlab --link owncloud:owncloud

Da man diese Konfiguration öfters ändern muss, bspw. wenn neue Hosts hinzukommen empfiehlt es sich die Konfiguration des Docker-Containers in einer Datei abzulegen und „docker-compose“ zu verwenden. (https://docs.docker.com/compose/install/)

Die Installation erfolgt so direkt über „curl“:

curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

Docker Compose hat anschließend noch keine Ausführungsberechtigung, diese müssen mit chmod noch hinzugefügt werden: Chmodax.png

Nun können wir testen, ob „docker-compose“ korrekt funktioniert:

Testdockercompose.png

Hierzu legen wir ein Verzeichnis im Root Homeverzeichnis an und dort ein „docker-compose.yml“:

Compose2.png

Die Datei sollte wie folgt aussehen:

version: '2'
services:
 nginxserver:
   container_name: nginxserver
   image: nginx
   network_mode: bridge
   external_links:
      - blog:blog
      - gitlab:gitlab
      - owncloud:owncloud
   ports:
      - "80:80"
      - "443:443"
   volumes:
      - /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d:z
      - /home/data/Nginx/certs/:/etc/nginx/certs:z
      - /home/data/Nginx/logs/:/var/log/nginx:z

Anschließend kann man mit „docker-compose“ die „nginx“ starten:

Startcompose.png

Nachdem Nginx gestartet ist muss die Konfiguration erstellt werden. Für jede Subdomain ist das durchreichen zum entsprechenden gemappten Docker Container einzutragen:

Map.png

Nachdem die Konfiguration durchgeführt wurde, kann die „nginx“ neu gestartet werden:

Restartnginx.png

Sollte es nicht funktionieren, kann „docker logs“ hier weiterhelfen: Loghelp.png

Konfiguration von Shipyard

Als letztes Element habe ich noch Shipyard hinzugefügt, damit auch remote eine Verwaltung der Docker Container möglich ist.

Die Installation ist sehr einfach und benöigt kaum überlegungen:

  • DNS soll ship.vr-worlds.de werden (Nginx Configuration ist hierfür anzupassen)

Das Deployment erfolgt hier nicht über "docker run" sondern über curl:

curl -sSL https://shipyard-project.com/deploy | bash -s

Anschließend ist shipyard über Port 8080 verfügbar und es wurde einige Container installiert:

[root@CentOS-73-64-minimal ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 48f5cd2ce123 shipyard/shipyard:latest "/bin/controller --de" 2 weeks ago Up 2 weeks 0.0.0.0:8080->8080/tcp shipyard-controller ec4955037d0f swarm:latest "/swarm j --addr 176." 2 weeks ago Up 2 weeks 2375/tcp shipyard-swarm-agent 48487fb7223c swarm:latest "/swarm m --replicati" 2 weeks ago Up 2 weeks 2375/tcp shipyard-swarm-manager fee6b7fcc71e shipyard/docker-proxy:latest "/usr/local/bin/run" 2 weeks ago Up 2 weeks 0.0.0.0:2375->2375/tcp shipyard-proxy 2058c074314b alpine "sh" 2 weeks ago Up 2 weeks shipyard-certs d710310dae40 microbox/etcd:latest "/bin/etcd -addr 176." 2 weeks ago Up 2 weeks 0.0.0.0:4001->4001/tcp, 0.0.0.0:7001->7001/tcp shipyard-discovery 0fe8eb95b8fb rethinkdb "rethinkdb --bind all" 2 weeks ago Up 2 weeks 8080/tcp, 28015/tcp, 29015/tcp shipyard-rethinkdb

Nun muss “Shipyard” nur noch in die nginx eingebunden werden und konfiguiert. In die nginx Konfiguration ist folgendes zu ergänzen: (/home/data/Nginx/sites_enabled)

SiteEnabled.png

Jetzt zahlt es sich erstmals aus über „docker-compose“ die Konfiguration für Nginx gemacht zu haben, dann diese ist nun einfach zu erweitern:

Addshipyard.png

Anschließend kann der Container neu gebaut werden mittels „docker-compose up -d“:

Compose3.png

Konfiguration über Docker-Compose zentral steuern

Damit die Automatisierung von Docker wirklich zum tragen kommt, werde ich nun die komplette Konfiguration in einem neuen Docker-Compose File zusammen führen:

Compose4.png

Die Datei hat folgendes aussehen:

version: '2.1'
services:
 ghost-mysql:
   container_name: ghost-mysql
   image: mariadb
   network_mode: bridge
   ports:
      - "3306:3306"
   volumes:
      - /home/data/MariaDb/:/var/lib/mysql:z
   environment:
      - MYSQL_ROOT_PASSWORD=rosi2511
 blog:
   container_name: blog
   image: ghost
   network_mode: bridge
   links:
      - ghost-mysql:mysql
   ports:
      - "2368:2368"
   volumes:
      - /home/data/Ghost/:/var/lib/ghost:z
 owncloud:
   container_name: owncloud
   image: owncloud:8.1
   network_mode: bridge
   links:
      - ghost-mysql:mysql
   ports:
      - "8082:80"
   volumes:
      - /home/data/owncloud:/var/www/html:z
 gitlab:
   container_name: gitlab
   image: gitlab/gitlab-ce
   network_mode: bridge
   ports:
      - "8443:443"
      - "8083:80"
      - "8022:22"
      - "8060:8060"
   volumes:
      - /home/data/gitlab/config:/etc/gitlab:z
      - /home/data/gitlab/logs:/var/log/gitlab:z
      - /home/data/gitlab/data:/var/opt/gitlab:z
      - /etc/localtime:/etc/localtime
   sysctls:
      - net.core.somaxconn=1024
   ulimits:
      sigpending: 62793
      nproc: 131072
      nofile: 60000
      core: 0
 nginxserver:
   container_name: nginxserver
   image: nginx
   network_mode: bridge
   links:
      - blog:blog
      - gitlab:gitlab
      - owncloud:owncloud
   external_links:
      - shipyard-controller:shipyard-controller
   ports:
      - "80:80"
      - "443:443"
   volumes:
      - /home/data/Nginx/sites-enabled/:/etc/nginx/conf.d:z
      - /home/data/Nginx/certs/:/etc/nginx/certs:z

Nun können wir alle Container wieder löschen und dann mit „docker-compose“ neu anlegen:

Test2.png

Konfiguration der Firewall bei Hetzner

Meine Firewall Konfiguration bei Hetzner, sieht wie folgt aus: Hetzner.png

Die Regel #1 ermögicht es, dass ICMP Packete, bspw. Ping aber auch Requests bezüglich ermitteln der Netzwerkbandbreite (MTU-Size etc.) ermittelt werden können. Es empfiehlt sich daher dies auf „accept“ stehen zu lassen.

Die Regel #2 ermöglicht es, sich auf dem Server mit ssh zu verbinden. Man muss diesen Port nicht immer auf lassen und kann diesen, wenn keine Wartung ansteht auf „discard“ stellen. Anschließend ist eine Verbindung mittels „ssh“ nicht mehr möglich und daher können „putty“ und „winscp“ sich dann nicht mehr verbinden:

Firewall2.png

Die Regel #3 ist dafür zuständige damit mittels „http“ (port 80) und „https“ (Port 443) auf das System zugegriffen werden kann.

Die Regel #4 ist notwendig, damit der Linux Host auch antworten kann. Selbstverständlich kann man die Regeln noch weiter optimieren.

Zusammenfassung

In diesem Artikel habe ich gezeigt welche Dinge im einzelnen zu tun sind, damit eine Konfiguration mit einem NGINX Proxy und ein paar anderen Container miteinander zusammen spielen. Ich hoffe das dieses recht Praxisnahe Beschreibung hilfreich ist.

Wenn Sie Unterstützung bei einer Docker Umgebung benötigen, dann kommen Sie genre auf mich zu und kontaktieren Sie mich unter christian.mueller@vr-worlds.de



© 2020. Hetzner Online GmbH. Alle Rechte vorbehalten.