Docker für Serveranwendungen

Tockra

Lt. Commander
Registriert
Dez. 2008
Beiträge
1.058
Hallo Leute,

ich beschäftige mich seit kurzem mit Docker und finde die Idee dahinter eigentlich recht interessant.
Da ich meinen Server bald neu einrichten werde, denke ich momentan darüber nach alle Anwendungen, die auf dem Server laufen in eigene Dockercontainer auszugliedern.

Eigentlich bin ich davon ausgegangen, dass ich jede Anwendung in einen eigenen Debian-Container werfen muss und darin laufen lassen muss. Jetzt bin ich allerdings auf solche Seiten gestoßen:
nextcloud: https://github.com/nextcloud/docker
apache: https://hub.docker.com/_/httpd/
teamspeak3: https://docs.docker.com/samples/library/teamspeak/#ts3server_query_timeout
minecraft: https://hub.docker.com/r/bbriggs/bukkit/

Jetzt stelle ich mir die Frage, ob das wirklich nur die Anwendungen in den Containern sind oder ob das immer eine minimalinstallation von einem Betriebssystem + die Anwendung ist.
Erschwere ich mir die Wartung durch diese Container? Wie sieht es mit Updates aus?
Und was mache ich, wenn ich z.B. apache mit einem letsencrypt client verwenden möchte? Normalerweise würde ich ein Debian nehmen, da apache installieren und nen crontab mit der Letsencrypt-Anwendung anlegen. Wie würde soetwas mit dem httpd-docker-container funktionieren ?
Wie würde ich außerdem auf das Verzeichnis des Minecraft-Servers zugreifen? Normalerweise würde ich das via sftp machen !?

Viele Grüße
T
 
da is immer eine Minimalversion von einem OS dabei, oft Debian oder Alpine Linux
Du kannst dich mit der Dockerfile entlanghangeln und rausfinden was es ist, wenn sie es selbst nicht erwähnen
Das coole is ja, wenn mehrere deiner Container auf Alpine basieren hast du das Basis-OS nur einmal auf der Platte (getartet werden muss es trotzdem öfters)

du kannst ja ein Shared Verzeichnis (in Docker Sprache Volume genannt) machen und dort Dateien (konkret gehts da dann um Config Files, HTTP Directory und SSL Zertifikate) zwischen den Containern austauschen.

Aktualisieren tust du dann einfach indem du den Container löschst, eine neue Version pullst und ihn neu erstellst.

Es gibt auch zig Tutorials wie hier: https://www.humankode.com/ssl/how-t...ates-from-lets-encrypt-using-docker-and-nginx

oder du machst die deluxe Lösung indem du einen nginx als Proxy vor deinen Webserver schaltest, und das dann mit nginx, docker-gen und letsencrypt-nginx-proxy-companion automatisierst. Hatte ich auch mal ne Weile laufen :)

curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > /container/webproxy/nginx.tmpl

docker run -d -p 80:80 -p 443:443 \
--name nginx \
-v /container/webproxy/conf.d:/etc/nginx/conf.d \
-v /container/webproxy/vhost.d:/etc/nginx/vhost.d \
-v /container/webproxy/htpasswd:/etc/nginx/htpasswd \
-v /usr/share/nginx/html \
-v /container/webproxy/certs:/etc/nginx/certs:ro \
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true \
nginx:latest

docker run -d \
--name nginx-gen \
--volumes-from nginx \
-v /container/webproxy/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen \
jwilder/docker-gen:latest \
-notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf

docker run -d \
--name nginx-letsencrypt \
-e "NGINX_DOCKER_GEN_CONTAINER=nginx-gen" \
-e "ACME_TOS_HASH=cc88d8d9517f490191401e7b54e9ffd12a2b9082ec7a1d4cec6101" \
--volumes-from nginx \
-v /container/webproxy/certs:/etc/nginx/certs:rw \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
jrcs/letsencrypt-nginx-proxy-companion:latest


sudo docker run -d \
--name webserver \
-e VIRTUAL_HOST=www.domain.tld \
-e LETSENCRYPT_HOST=www.domain.tld \
-e LETSENCRYPT_EMAIL=info@domain.tld \
-e VIRTUAL_PORT=1597 \
-v /container/webserver:/usr/share/nginx/html:ro \
-p 1597:80 \
nginx:latest
 
Zuletzt bearbeitet:
Wenn du nur jeweils eine Anwendung 1:1 in jeweils einen Docker-Container ausgliedern willst lautet mein Rat: Lass es.

Docker ist für zwei Dinge gut: Skalierung (zusammen mit Kubernetes) und Rapid Prototyping.

Einfach die Dienste eines Servers 1:1 in Docker reinzuwerfen macht keinen Sinn, wenn man nicht skalieren will.

Für Rapid Prototyping und für Entwicklungsumgebungen, in denen man mal so eine DB-Instanz mal so einen Webserver haben möchte ist das jedoch eine Klasse Angelegenheit, da man so nicht so vergümpelte Systeme und verbrannte Erde hinterlässt.
 
ayngush schrieb:
Einfach die Dienste eines Servers 1:1 in Docker reinzuwerfen macht keinen Sinn, wenn man nicht skalieren will.
Doch, spätestens wenn man seinen Host nicht mit hundert Diensten vollknallen will. Eine Anwendung benötigt MySQL 5.5, die Nächste 5.8, Anwendung 1 läuft nur unter PHP 7.0, die Nächste will 7.2. Eine Anwendung brauch Apache, die Nächste Nginx. Sich damit das System vollknallen macht absolut keinen Spaß. Irgendwann hast du 100 Dienste laufen und Drölf Anwendungen und jede benötigt andere Abhängigkeiten. Viel Spaß beim nächsten Update... Schon allein zur Trennung und Isolation der Systeme macht Docker Sinn. Horizontale Skalierung ist doch nur ein Schmankerl.

Ich hab meinen Teamspeak Server letztens auch auf Docker umgestellt. Macht mir die Arbeit deutlich einfacher, als wenn ich mich selbst um den Kram auf den Host kümmern muss. Update? Container stoppen, Version hochsetzen, Container neu starten, fertig.

Gitlab kommt dann beim nächsten Umzug auch in einen eigenen Container, statt jetzt einer eigenen VM.

Alle restlichen Anwendungen (bspw. Nextcloud und eine Docker Registry) laufen so weit bereits als Container. Die Webseiten/Domains muss ich teilweise auch noch umziehen, aber dazu hab ich momentan keine Lust. Dann kann ich den Host nämlich weiter entschlacken und Apache, MySQL und PHP (+ FPM) runter hauen, weil die in den Containern laufen und ich sie auf dem Host so eigentlich gar nicht benötige.

Einfach nur nen Reverse Proxy als HTTP davorschalten und gut ist. Da kann man sich dann aussuchen welcher, ob nun Apache, Nginx, HAProxy oder sonst was...
 
  • Gefällt mir
Reaktionen: Ebrithil, memmex, derBobby und eine weitere Person
Zwecks LetsEncrypt kann ich Traefik als Container empfehlen. Funktioniert als LE-Client und Proxy zu anderen Containern. Aufwand quasi 0. :-)

Docker nur zur Skalierung und Prototyping? Nope. Verhindert super zumüllen des OS!

Redmine Ruby Krams -> Container
Nextcloud PHP Krams -> Container
And so on.

Nachtrag: Anfangs wollte ich auch meine Images selber bauen zwecks fehlendem Vertrauen. Bei den als Official gekennzeichneten bin ich aber mittlerweile auch auf diese umgestiegen. (NC zB) Weniger Aufwand war für mich das Ziel.
 
Zuletzt bearbeitet von einem Moderator: (Addit)
Yuuri schrieb:
pdate? Container stoppen, Version hochsetzen, Container neu starten, fertig.
Dann musst du aber alle Channel und Rechte neu einrichten, oder nicht?

Kann mir jemand einen Tipp geben, wie genau ich die Container starte? Sollten ja per Autostart starten. Sollte jeder Container von einem eigenen Nutzer gestartet werden, oder alle vom selben Nutzer ?
 
steht meistens in der Anleitung :) i.d.R. speichert man die Nutzdaten die "überleben" sollen entweder in einem Volume oder einem Ordner außerhalb des Containers.

Hier für einen TS3 Container

mkdir /opt/container/ts3

docker run -d --restart unless-stopped \
--name meints3container \
-v /opt/container/ts3/:/var/ts3server/ \
-p 9987:9987/udp -p 10011:10011 -p 30033:30033 \
-e TS3SERVER_LICENSE=accept \
teamspeak:latest

und am Besten eine licensekey.dat vorab in den Ordner /opt/container/ts3/ legen

zum aktualisieren dann

docker stop meints3container
docker rm meints3container
docker pull teamspeak:latest

und starten dann wieder mit dem run-Kommando von oben.

(edit: hatte Ports und das Lizenzakzeptieren vergessen)
 
Tockra schrieb:
Dann musst du aber alle Channel und Rechte neu einrichten, oder nicht?
Deswegen gibts Volumes, dessen Daten persistent bleiben.

Meine docker-compose.yml:
Code:
version: "2"
services:
  teamspeak:
    user: "1000"
    restart: always
    image: teamspeak:3.3
    container_name: ts
    network_mode: host
    ports:
      - "9987:9987/udp"
      - "10011:10011"
      - "30033:30033"
    environment:
      - TS3SERVER_LICENSE=accept
    volumes:
      - ./data/teamspeak:/var/ts3server
Nach dem ersten Start wird dann alles initial eingerichtet. Anschließend legst du deine licensekey.dat unter /data/teamspeak ab und schon hast du nen lizenzierten TS-Server im Container laufen.
Tockra schrieb:
Kann mir jemand einen Tipp geben, wie genau ich die Container starte?
Am Besten per docker-compose.yml. Das manuelle Ausführen wie @LieberNetterFlo schreibt, ist extrem... bescheiden. Gestartet wird dann einfach via docker-compose up.
Tockra schrieb:
Sollten ja per Autostart starten.
Dafür gibts die Restarty Policy.
Tockra schrieb:
Sollte jeder Container von einem eigenen Nutzer gestartet werden, oder alle vom selben Nutzer ?
Der Container arbeitet eh für sich, von daher ist es vollkommen egal, wer ihn startet. Standardmäßig kann auch nur root die Container beeinflussen. Es gibt aber ne Gruppe docker, wo auch normale User diese starten/beenden/... können, ähnlich der sudo Gruppe.
 
Alles klar, vielen Dank! Ihr habt mir auf jeden Fall weitergeholfen und sobald mit 3. Raid-Platte ankommt, werde ich wohl die Dockervarianten nutzen.

Allerdings bleiben mir 1,5 Fragen offen:
1. Wie handhabe ich das, wenn ich 2 Container habe, die den selben Port nutzen? z.B. wenn ich in einem Container Gitlab installieren möchte und in den anderen Container Nextcloud!?
Letztendlich bleibt mir nichts anderes übrig, als alles in einem Container laufen zu lassen, oder?

2. Wo genau würdet Ihr mir empfehlen die Volumen im Hostsystem hinzumounten ? Ich würde das gerne schön haben und bin mir gerade nicht sicher, ob /home/dockernutzer, /var/, /data/ oder /opt/ die richtigen Verzeichnisse sind!?
 
Tockra schrieb:
1. Wie handhabe ich das, wenn ich 2 Container habe, die den selben Port nutzen? z.B. wenn ich in einem Container Gitlab installieren möchte und in den anderen Container Nextcloud!?
Letztendlich bleibt mir nichts anderes übrig, als alles in einem Container laufen zu lassen, oder?
Die Container laufen getrennt, d.h. in beiden Containern läuft ein HTTP auf 80. Die Sache ist, was du nun draus machst.
  • Container1:80 kannst du auf Host:60080 laufen lassen
  • Container2:80 auf Host:61080
Damit kannst du dann im Reverse Proxy auf dem Host bei
  • nextcloud.domain.tld auf 127.0.0.1:60080 weiterleiten und
  • gitlab.domain.tld auf 127.0.0.1:61080
Auf den Host mappen musst du die, weil das Netzwerk auch getrennt läuft, sonst hast du noch den Host Mode, aber dann gibst du alle Ports des Containers an den Host weiter.
Tockra schrieb:
2. Wo genau würdet Ihr mir empfehlen die Volumen im Hostsystem hinzumounten ?
Genau da, wo auch die docker-compose.yml liegt. Dann ist auch ne Versionisierung komplett einfach oder Backups.
 
Yuuri schrieb:
Damit kannst du dann im Reverse Proxy auf dem Host bei
  • nextcloud.domain.tld auf 127.0.0.1:60080 weiterleiten und
  • gitlab.domain.tld auf 127.0.0.1:61080

Muss zugegeben, dass ich bis heute noch nicht von einen Reverse Proxy gehört habe. Kannst du mir ein gutes Dockerimage dafür empfehlen?

Yuuri schrieb:
Genau da, wo auch die docker-compose.yml liegt. Dann ist auch ne Versionisierung komplett einfach oder Backups.
Wo liegt die denn? Vermutlich kann ich das ja selbst entscheiden und somit stehe ich wieder vorm vorherigen Problem.
 
Zuletzt bearbeitet:
@LieberNetterFlo Ja ich weiß, aber anders wird immer nur genattet, was ich ein bisschen daneben finde. 172.20.0.1 ist halt ein wenig blöd. Wäre mir neu, wenn man das irgendwie außer mit dem Host Mode hinbekommen könnte. Das ist halt ein Nachteil vom Proxy, den man zumindest bei HTTP umgehen kann durch zusätzliche Header.
Tockra schrieb:
Wo liegt die denn?
Irgendwo im Dateisystem. Die legst du einfach in irgendeinen Ordner und kannst dann mit docker-compose arbeiten. So sind die Daten schön projektbezogen gruppiert.
 
@Yuuri na, dafür gibts doch die Einträge mit den Ports die weitergeleitet werden. Geht das bei dir nicht? Ich hab bei keinem meiner Container ein host als Netzwerk gemacht.

Code:
version: "3.5"
services:
  teamspeak:
    user: "1000"
    restart: always
    image: teamspeak:latest
    container_name: docker-teamspeak3
    ports:
      - "9987:9987/udp"
      - "10011:10011"
      - "30033:30033"
    environment:
      - TS3SERVER_LICENSE=accept
    volumes:
      - ./config-teamspeak3:/var/ts3server
 
(...und das soll dann alles noch übersichtlicher und leichter zu Warten und verständlicher im Fehlerfall sein im Vergleich zu einer klassischen Installation, wenn man auf die Skalierung nicht angewiesen ist?)

Nichts gegen den New-Age-Shit aber ich habe da immer noch so meine Zweifel, dass das für eine "normale Serverumgebung" (Linux, Headless, Bare Metal Virtualisierung) sinnvoll ist :)

Für Rapid Prototyping und zum Skalieren von Services / für eine Community-Cloud: Ja, auf jeden Fall (zusammen mit Kubernetes).
Für Webserver (Monitoring, Gitlab, Intranet, Extranet, REST-API, uvm.) im Unternehmen sehe ich da immer noch keine Vorteile außer zusätzliche Komplexität und Code-Entropie.
 
ayngush schrieb:
(...und das soll dann alles noch übersichtlicher und leichter zu Warten und verständlicher im Fehlerfall sein im Vergleich zu einer klassischen Installation, wenn man auf die Skalierung nicht angewiesen ist?)
Auf jeden Fall. Seit ich (fast) nur noch Docker Container verwende, ist der Wartungsaufwand für meinen Server extrem zurück gegangen.

Aktualisieren von containern ist nur ein einfaches
Code:
docker-compose down
docker-compose pull
docker-compose up -d
Danach sind alle container auf dem neusten Stand.

Abgesehen davon, gibt es gefühlt für jede Anwendung inwzischen fertige Container. Einfach docker-compose file fertig machen, starten, fertig.

Genauso leicht kriegt man Services die man nicht mehr haben will wieder sauber vom System.
Container löschen, gemountete Volumes löschen, fertig.
 
Zurück
Oben