Docket basketFür mich privat betreibe ich momentan 3 eigene Server, für WordPress, ownCloud, GitLab, E-Mail und lauter anderer Kleinkram der mich privat interessiert, oder einfach nicht in die Cloud legen möchte.

Früher habe ich von Hand einen Apache Server kompiliert, dann Pakete verstanden und genutzt, und jetzt gibt es da diese Docker… – Magie für viele.

Ich habe mich längere Zeit gefragt, wie ich, oder eine kleinere Firma effektiv mit Containern arbeiten kann. Ganz ohne eine große Cloud, und komplexe Prozesse die man erst aufbauen muss.

Eigentlich ist es ganz einfach, nur ein paar Grundregeln muss man verstehen:

  • Eine Anwendung pro Container
  • Mehrere Container zusammen geben eine große Anwendung
  • Ggf. sorgt ein Webserver davor für Bereitstellung ans Internet, und SSL
  • Der Server auf dem die Container laufen sollte eingeschränkt werden

Im folgenden möchte ich erklären wie ich meine eigene private ownCloud betreibe, vielleicht hilft es jemandem.

Mein Basis System, auf dem möglichst wenig Anderes laufen sollte:

  • Debian Jessie, mit Apache und Firewall Regeln
  • Docker 1.7.1
  • systemd (hilft immens!)
  • Partition für /var/lib/docker und /data/docker

Docker Images: mariadb (Quellen) und owncloud (Quellen)

Datenbank

Als erstes legen wir ein Datenverzeichnis an.

mkdir -p /data/docker/mariadb/data
chmod 700 /data/docker/mariadb

So kann man jetzt den Docker container einfach per Hand starten:

docker pull mariadb:10
docker run \
  --name mariadb  # persitenter name \
  -p 3306:3306    # den port oeffentlich machen (aussen:innen) (Firewall!) \
  -v /data/docker/mariadb/data:/var/lib/mysql  # Datenverzeichnis fuer den Tablespace \
  -e MYSQL_ROOT_PASSWORD=seeehrgeheim  # das feste Rootpasswort \
  -it  # interaktiv mit tty \
  mariadb:10      # das image \
  mysqld --log-bin= --binlog-format=MIXED  # Startbefehl mit Optionen

Der Datenbankserver läuft jetzt im Vordergrund, man kann das Log sehen, und kann jetzt in einer 2. Sitzung selbigen einrichten:

mysql -h 127.0.0.1 -pseeehrgeheim
mysql> CREATE DATABASE clouddingens;
mysql> GRANT ALL ON clouddingens.* TO clouddingens@'172.17.%' IDENTIFIED BY 'auchgeheim';

Nun haben wir zwar die Datenbank, ich möchte die aber eigentlich von systemd starten lassen, also beenden wir den Server mit CTRL-C und legen ein Unitfile an:

/etc/systemd/system/mariadb.service

[Unit]
Description=MariaDB database
BindsTo=docker.service  # Abhängigkeit und Neustart mit dem Docker Service

[Service]
ExecStartPre=-/usr/bin/docker kill mariadb     # sicherstellen dass der Container gestoppt ist
ExecStartPre=-/usr/bin/docker rm mariadb       # den alten Container löschen
ExecStartPre=-/usr/bin/docker pull mariadb:10  # das Image auf den neusten Stand bringen
# und den Container starten
ExecStart=/usr/bin/docker run --name mariadb -p 3306:3306 -v /data/docker/mariadb/data:/var/lib/mysql mariadb:10 mysqld --log-bin= --binlog-format=MIXED
# den Container sanft beenden
ExecStop=/usr/bin/docker stop mariadb

[Install]
WantedBy=multi-user.target

Mit diesem Unitfile kann systemd alles andere übernehmen:

systemctl daemon-reload
systemctl start mariadb.service
systemctl enable mariadb.service
systemctl status mariadb.service
mysql -h 127.0.0.1 -pseeehrgeheim

ownCloud

Im Prinzip funktioniert owncloud fast genau so.

mkdir -p /data/docker/owncloud/data
chmod 700 /data/docker/owncloud

Die Besonderheit hier ist, dass der mariadb Container in den ownCloud Container verlinkt ist. Das sorgt für einen Hosteintrag in “owncloud“, nämlich “mysql“, damit der Container auch weiß wo seine Datenbank ist.

/etc/systemd/system/owncloud.service

[Unit]
Description=ownCloud
BindsTo=docker.service
BindsTo=mariadb.service

[Service]
ExecStartPre=-/usr/bin/docker kill owncloud
ExecStartPre=-/usr/bin/docker rm owncloud
ExecStartPre=-/usr/bin/docker pull owncloud:8.1
ExecStart=/usr/bin/docker run \
  --name owncloud \
  -p 8013:80 \
  --link mariadb:mysql \
  -v /data/docker/owncloud/data:/var/www/html \
  owncloud:8.1
ExecStop=/usr/bin/docker stop owncloud

[Install]
WantedBy=multi-user.target

Und wieder kann der Dienst einfach mit systemd gestartet werden:

systemctl daemon-reload
systemctl start owncloud.service
systemctl enable owncloud.service

Wenn man direkten Zugriff auf den Server hat kann man schon auf die ownCloud http://server:8013, dort kann mit dem Datenbank Host “mysql”, und den Zugangsdaten von oben, die Cloud schon fertig eingerichtet werden.

Apache

Auf meinem Hostsystem ist nun ein Apache eingerichtet, der die ownCloud an das Internet freigibt und mit TLS abgesichert ist.

So sieht meine Konfiguration aus:

<VirtualHost *:80>
 ServerAdmin webmaster@lazyfrosch.de
 ServerName cloud.lazyfrosch.de

 Redirect / https://cloud.lazyfrosch.de/

 ErrorLog ${APACHE_LOG_DIR}/cloud.lazyfrosch.de_error.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/cloud.lazyfrosch.de_access.log combined
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
 ServerAdmin webmaster@lazyfrosch.de
 ServerName cloud.lazyfrosch.de

 ProxyPreserveHost On
 ProxyPass / http://localhost:8013/
 ProxyPassReverse / http://localhost:8013/

 ErrorLog ${APACHE_LOG_DIR}/cloud.lazyfrosch.de_error_ssl.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/cloud.lazyfrosch.de_access_ssl.log combined

 SSLEngine on
 SSLCertificateFile /etc/ssl/cloud.lazyfrosch.de.crt
 SSLCertificateKeyFile /etc/ssl/private/cloud.lazyfrosch.de.key
 SSLCACertificatePath /etc/ssl/certs/
 SSLCertificateChainFile /etc/ssl/startssl-sub.class1.server.ca.pem
</VirtualHost>
</IfModule>

Updates

Bei diesem Setup sind Updates relativ leicht, es reicht ein Neustart des Containers, um das aktuelle Image zu laden und zu benutzen.

Ich arbeite gerade an einem Skript um sauber festzustellen ob es ein neues Image gibt.

Hinweise zur Sicherheit

  • Benutzer auf dem Hostsystem können mit Prozessen der Container integrieren, wenn die UID identisch ist, z.B. kill
  • Geben sie möglichst keinem Nutzer Zugriff auf die docker Gruppe – diese Gruppe ist mit root-Rechten gleich zu setzen, besser sudo verwenden
Markus Frosch

Autor: Markus Frosch

Markus arbeitet bei NETWAYS als Principal Consultant und unterstützt Kunden bei der Implementierung von Nagios, Icinga und anderen Open Source Systems Management Tools. Neben seiner beruflichen Tätigkeit ist Markus aktiver Mitarbeiter im Debian Projekt.