phil-de
Goto Top

Docker Compose Webserver-Container fährt nach UP herunter

Schönen guten Abend zusammen,

ich sitze momentan dabei einen Apache2 & PHP Webserver aufzusetzen. Ich habe nun folgendes Problem: Ich hab eine Dockerfile und eine docker-compose.yml geschrieben.

Nachdem ich den Befehl
sudo docker-compose up -d
eingebe werden die Dienste zwar gestartet, kriege auch die Meldung "done" aber die fahren direkt herunter da unter
sudo docker ps
keine aktiven container zu finden sind *

Ich kann die Website auch nicht über http://IP-ADRESSE erreichen...

Dockerfile
FROM debian
RUN apt update
RUN apt install apache2

docker-compose.yml
version: "3.8"  
services:
  webserver:
    image: httpd:latest
    build: .
    ports:
      - "80:80"  
      - "443:443"  
    volumes: 
    - /var/www/html:.
  php:
    image: php:latest
    build: .
    volumes:
    - /var/www/html:.

Vielleicht kann mir da jemand helfen, Danke!

*Kann auch sein das ich es einfach falsch anwende, hab heute erst versucht mich mit docker auseinanderzusetzen

Content-ID: 636528

Url: https://administrator.de/forum/docker-compose-webserver-container-faehrt-nach-up-herunter-636528.html

Ausgedruckt am: 27.12.2024 um 06:12 Uhr

Dani
Dani 31.12.2020 aktualisiert um 12:47:09 Uhr
Goto Top
Moin,
was steht den in Logsfiles drin?
docker logs webserver
docker logs php

Nicht vergessen die Konfiguration einmal zu prüfen. face-smile
docker-compose config

Gruß,
Dani
GNULinux
Lösung GNULinux 31.12.2020 um 12:52:22 Uhr
Goto Top
docker-compose.yml
services:
  webserver:
    image: httpd:latest
    build: .

Du gibst ein fertiges Image (httpd) an UND willst zeitgleich eines über das Dockerfile bauen. Das macht keinen Sinn: Entweder nutzt du das Fertige oder baust ein eigenes, aber nicht beides.

Zitat von @Phil-DE:
Dockerfile
FROM debian
RUN apt update
RUN apt install apache2
Das kann so auch nicht funktionieren: Damit installierst du zwar den Apache im Image aber hast keinen Einstiegspunkt. Auf die klassische Linux VM übertragen ist das vergleichbar damit, das Paket zu installieren, aber den (Systemd) Dienst nicht anzulegen bzw nicht zu aktivieren. Heißt dein Webserver ist da, aber das OS hat keine Anweisung ihn zu starten. Daher hast du auch keine laufenden Container, was den Apache angeht. Bei PHP liegts daran dass du halt auch da das latest Image genommen hast und das ist nur die CLI, s.u.

Du könntest jetzt nen ENTRYPOINT definieren, aber:
1. Es macht keinen Sinn, das Apache-Paket händisch über ein Debian zu installieren, wenn es ein offizielles httpd Image gibt. Damit machst du viele der Docker-Vorteile kaputt und verkomplizierst die Wartung. Nimm das httpd Image als Basis.
2. Ein abgeleitetes Image macht nur Sinn, wenn du es modifizeren willst. Bisher machst du das nicht, also würde ich auch kein eigenes Bauen.
3. Der latest Tag ist schlechte Praxis und zerstört auch einige der Vorteile des Konzeptes. Ich würde den nicht mal zu Testzwecken nutzen, man gewöhnt sich nur daran und am Ende vergisst man es vor dem prod Deployment vernünftig zu setzen. Je nachdem wie stabil du das haben willst würde ich Major oder Major+Minor Tag nehmen. Regelmäßiges pullen und neu bauen (z.B: mittels Pipeline) ist natürlich Voraussetzung, damit du die Updates auch bekommst

Praktisch heißt das: Dockerfile weg, in deinem Composefile "build: ." rausnehmen und halt den latest tag beim httpd Image entsprechend ersetzen, z.B. durch 2.4.

Zitat von @Phil-DE:
*Kann auch sein das ich es einfach falsch anwende, hab heute erst versucht mich mit docker auseinanderzusetzen
Sind ein paar Anfängerfehler drin, siehe oben, aber besser spät in aktuelle Technologien einsteigen als nie face-wink
Aber kennst du dich denn mit Apache und PHP aus? Wie willst du PHP anbinden, per mod_php? fastcgi? PHP-FPM? Dafür müsstest du dich ganz unabhängig von Docker entscheiden und das passende Basis Image nehmen + entsprechende Config. Wie oben schon gesagt hast du bei PHP den latest Tag und der entspricht der aktuellen CLI. Der Tag ist dafür da wenn du z.B. per Cron ein PHP Skript per CLI ausführen willst aber als Container bringt dir das nix.

Je nachdem was du wählst brauchst du den 2. Container ggf auch gar nicht. Bei mod_php startet Apache ja einfach den Prozess. Wenn du keine Erfahrung mit Apache + PHP hast ist das am einfachsten, aber halt auch performancetechnisch am schlechsten (Overhead). Kommt aber natürlich drauf an was du vor hast. Für z.B. ne kleine Intranet/Testseite oder was anderes mit einer hand voll Anfragen spielt das keine Rolle.
Phil-DE
Phil-DE 01.01.2021 um 03:23:43 Uhr
Goto Top
@Dani ich hab die Logs später nochmal gründlich analysiert und da hat sich heraus gestellt das wie jetzt @asp.net.core erwähnt hat das der Server nicht im foreground lief. Hab diesen durch den entsprechenden Befehl in den Vordergrund geschoben. Es lief dann!

Bin jetzt aber erstmal auf nginx umgestiegen weil alle meinten das Apache2 veraltete Technik sei, ich probiere mich da mal aus. Bin halt mit Apache2 groß geworden. Erste ServerWebsite versuche für einen damaligen Minecraft Server vor Jahren und dort lief phpMyAdmin beispielweise nur über Apache meines wissens nach damals. Aber bin offen für neues face-smile

@asp.net.core
Zu dem Build "Befehl", also nur um das zu verstehen. Ich beziehe das Image. Beispielweise z.B. von Debian. Dieses ist dann ja infolgedessen ja schon fertig gebaut. Und mit dem Build Command baue ich ein neues Image was ich beispielweise auf Docker Hub hochladen kann um diese Maschine 1:1 auf einem anderen Rechner nachzubauen? Quasi für einen Webserver der alles eingestellt hat und ich daraus dann ein eigenes Image erstellen will weil ich den Container auf einem anderen Rechner laufen lassen will? Ich dachte bisher das die Befehle beim bauen der lokalen Image Datei ausgeführt werden und dann quasi der Build Befehl generell nutzlos bleibt oder sehe ich das falsch? Aber ja, es klingt logisch. Entweder oder face-smile

Zu dem zweiten Absatz, okay das mit dem "tag" das man nicht den latest nehmen soll klingt logisch. Ich hatte mich nur bisschen durch das Internet geklickt und da stand zum großen Teil das dass latest Image nur bezogen wird wenn das lokale Image neu gebaut wird. Heißt wenn es erstmal läuft baut man das lokale Image im Normal Fall ja nicht neu auf. Heißt unterm Strich das ich es so verstanden hab das man immer die aktuellste Version nehmen sollte und wenn es läuft dann läuft es. Und ja, im Bezug auf die Docker Vorteile ist es mir glaub ich soweit klar das man in den Containern verschiedene Versionen von z.B. Php laufen lassen kann um Inkompitibilitätsprobleme auszuschließen.
Im Bezug auf die Pipeline, ist das quasi ein crontab der quasi bspw. jeden Monat einmal den Container stoppt, den Container löscht, das Image löscht, es dann neu baut und dann wieder von alleine startet?

Und ja, mein Problem war bisher immer das ich halt immer jegliche Software auf den Server geknallt hab die halt benötigt wird. Und wenn eine Software nicht mehr lief hab ich bspw. Mysql geupdatet und dann lief jegliche andere Software nicht mehr. Genauso das dann von Deeinstallationen irgendwelche Dateien überblieben. Aber naja, man lernt ja nie aus :D Ich versuche mich ja auch erst an Docker, aber ich sehe das "Tool" wenn man das so nennen kann als sinnvoll und will es nutzen aber mir fehlt nun mal leider etwas das Know-How um es gut nutzen können...

Ja das alles läuft auf einem kleinen Raspberry Pi 4 ModelB und will damit einfach nur eine kleine Intranet Seite abbilden wo ich mich an Webapps bisschen austesten kann, und sowie als DB Server für kleinere Projekte. Mal schauen ob das so klappt wie ich das vor habe, aber habe mir vorgenommen die Services alle mit Docker zu "virtualisieren" wenn man das so nennt? Ist leider nun mal echt eine Mammutsaufgabe wenn man keine wirkliche Ahnung hat wie das läuft :D

Aber ich hangel mich da schon irgendwie durch...

Und schonmal vielen Dank für eure Hilfe und ein schönes neues Jahr 2021 was diesmal hoffentlich besser wird als 2020 im Bezug auf Lockdown, etc.

Gruß Phil
GNULinux
GNULinux 21.01.2021 um 12:02:56 Uhr
Goto Top
Zitat von @Phil-DE:
Bin jetzt aber erstmal auf nginx umgestiegen weil alle meinten das Apache2 veraltete Technik sei, ich probiere mich da mal aus.

Naja veraltet würde ich pauschal nicht sagen, es kommt drauf an. Grundsätzlich ist Apache threadbsiert, Nginx Eventbasiert. Apache lädt Module dynamisch zur Laufzeit, bei Nginx werden sie einkompiliert. In einem Satz gesagt ist Nginx dadurch performanter, der Apache kann weniger Durchsatz leisten und verbraucht dabei mehr Ressourcen.

Dafür ist der Apache flexibler, es gibt mehr Module und viele können dynamisch genutzt werden. Grade bei kleineren oder auch komplexen Projekten kann das mehr wiegen, als ein paar hundert MB RAM zu sparen, die heutzutage ja sowieso kaum mehr was kosten. Bei großen Seiten mit viel Last wird Nginx dagegen schneller sein und man spart sich den einen oder anderen Server. Wie so oft würde ich daher sagen es kommt drauf an. Grundsätzlich schadet es aber nicht sich nginx mal anzuschauen, aus den genannten Gründen gewinnt der seit Jahren zunehmend an Verbreitung.

Zuletzt sei noch erwähnt, dass man die Vorteile beider Server auch kombinieren kann. Beispielsweise ein Nginx der sehr effizient die statischen Anfragen abarbeitet und dahinter ein Apache. So landet nur ein Bruchteil der Anfragen beim Apache und man kann dort auch Module deaktivieren. Da reden wir aber auch eher von größeren Umgebungen, wo das Sinn macht.

Zitat von @Phil-DE:
@asp.net.core
Zu dem Build "Befehl", also nur um das zu verstehen. Ich beziehe das Image. Beispielweise z.B. von Debian. Dieses ist dann ja infolgedessen ja schon fertig gebaut. Und mit dem Build Command baue ich ein neues Image was ich beispielweise auf Docker Hub hochladen kann um diese Maschine 1:1 auf einem anderen Rechner nachzubauen?

Am Beispiel eines Debian-Images müsste man das so machen, weil das Debian-Image ja noch keine Funktion/Rolle besitzt. Wie ich oben schon erwähnt habe, würde ich diesen Weg nur gehen, wenn es kein konkreteres Basis-Image gibt. Soll heißen: Statt in einem Dockerfile auf ein Debian-Image aufbauend Apache2 zu installieren, würde ich das offizielle httpd Image nehmen. Das ist einfacher und berechenbarer, da du mit einem apt-get install apache2 ja je nach Repo-Stand eine andere Version bekommst.

Damit würde man sich meiner Meinung nach einen der großen Vorteile von Docker zerstören, nämlich die Reproduzierbarkeit. Wenn ich Versiontag 1.2.3 nutze, hat jeder auf jedem Gerät die gleiche Version.

Zitat von @Phil-DE:
Quasi für einen Webserver der alles eingestellt hat und ich daraus dann ein eigenes Image erstellen will weil ich den Container auf einem anderen Rechner laufen lassen will?

Wenn du ein Image erweitern willst, kann man das machen. Ein gängiges Beispiel wäre, du hast einen Apache2 Container und musst da noch irgendwelche Module aktivieren/installieren. Was du schreibst klingt eher, als willst du eine komplette Anwendung ins Image laden. Also HTML/CSS/PHP oder so was. Das kann man machen, allerdings muss man hier dann auf dynamische Daten aufpassen. Kann man über die Webanwendung z.B. etwas was hochladen, brauchst du ein Volume.

Zitat von @Phil-DE:
Ich dachte bisher das die Befehle beim bauen der lokalen Image Datei ausgeführt werden und dann quasi der Build Befehl generell nutzlos bleibt oder sehe ich das falsch?

Bei einem fertigen Image vom Docker-Hub muss nichts gebaut werden, da bekommst du die Schichten vom fertigen Image. Stell es dir in der alten Welt so vor, wie wenn du eine VM Provisionierst (Z.B. Apache Installieren) und dann die VHD jemand anderem gibst. Wenn der andere die VM startet, muss er keinen Apache mehr installieren, weil das in deiner virtuellen Festplatte schon drin ist. Das macht man im Falle von Docker aus Performance/Zeitgründen. Selbst bauen kann lange dauern, vor allem bei komplexer Software die viele Abhängigkeiten installiert und ggf noch was kompiliert. Rein rheoretisch könntest du dir auch das Dockerfile vom Dockerhub holen und selbst bauen, funktionell kommts aufs Gleiche raus.

Zwingend gebaut werden muss erst, wenn du ein eigenes Dockerfile auf Basis eines Images vom Dockerhub erstellst. Alles was in deinem Dockerfile liegt kann ja logischerweise nicht schon im Hub gecached liegen. Daher werden die Befehle in diesem Fall lokal ausgeführt. Aber eben nur beim ersten Mal bzw danach nur, wenn du etwas änderst. Denn auch hier arbeitet Docker mit intelligentem Caching und spart dir Zeit, sodass ein bereits gebautes Image einfach für neue Container genutzt werden kann, ohne es bei jedem Container neu bauen zu müssen.

Zitat von @Phil-DE:
Zu dem zweiten Absatz, okay das mit dem "tag" das man nicht den latest nehmen soll klingt logisch. Ich hatte mich nur bisschen durch das Internet geklickt und da stand zum großen Teil das dass latest Image nur bezogen wird wenn das lokale Image neu gebaut wird.

Grundsätzlich prüft Docker vor dem Start/bauen, ob das Image lokal existiert. Falls nein wird es heruntergeladen. Wenn es existiert, prüft Docker NICHT auf Updates. Es sei denn, du machst einen pull von Hand. Und da lauern jetzt zwei große Gefahren:

1. Wenn du nie pullst bzw keinen automatischen Update-Mechanismus hast der das macht, nutzt du früher oder später veraltete Software
2. Der latest Tag hat dagegen i.d.R. immer das NEUSTE Image. Die Reproduzierbarkeit ist damit v.a. durch #1 im Eimer

Beispielszenario um das zu verdeutlichen: Du lädst dir httpd:latest und hast wegen mir Apache 2.4.46 bekommen. Damit arbeitest du, machst keine pulls. In 1, 2, X Jahren arbeitest du also immer noch mit 2.4.46 obwohl es längst zig Updates gab. Wenn du mir dein Dockerfile gibst und ich das Image nicht habe, lädt er das neuste runter. Ich habe dann das Neuste, z.B. bis dahin 2.5.100 überspitzt gesagt. Schon ist das ganze nicht mehr reproduzierbar und deine Software vehält sich bei mir ganz anders.

Wenn du CI/CD nutzt kann dir das gleiche übrigens auch auf dem Buildserver passieren, wenn du lokal immer schön brav pullst aber der Buildserver sich das latest Image zuletzt vor Monaten oder Jahren runtergeladen hat.

Das ist die allgemeine Funktionsweise. Es ist wichtig zu verstehen, dass "latest" keine Sonderfunktion hat. Es ist ein Tag wie jeder andere, der lediglich per Konvention bei einigen (nicht alle! gibt auch welche die das aus o.g. Gründen gar nicht machen) für die neuste Version steht. Das heißt: Wenn Apache von 2.4.46 auf 2.4.47 updaten, taggen die das neue Image einmal mit 2.4.47 und einmal mit latest. Das gleiche gilt auch für Major/Minor Versionstags. Im Beispiel von Apache gibt es auch noch einen 2.4 Tag. Beim Update auf 2.4.47 wird also ebenfalls 2.4 getaggt. Das gleiche gilt für alle anderen Tags wie "dev", "nightly" und sonstiges.

Zitat von @Phil-DE:
Heißt unterm Strich das ich es so verstanden hab das man immer die aktuellste Version nehmen sollte
Aktuellste stabile Version ist gut, auch das hat aber wenig mit Docker zutun. Auf einem klassischen Linux Server solltest du das ja genau so handhaben wegen Sicherheitsupdates und Bugfixes, ggf auch neue Funktionen. Aber eben nicht unkontrolliert. Im Regelfall will man zumindest größere Updates vorher testen.

Zitat von @Phil-DE:
und wenn es läuft dann läuft es.
Never change a running system? Würde ich grundsätzlich nicht machen, sonst hast du irgendwann uralte Software mit zahlreichen Bugs und vor allem Sicherheitslücken, siehe oben. Aber auch da sind wir wieder bei einem grundsätzlichen best practice. Es muss klar sein, dass JEDE Software aktuell gehalten werden sollte. Ob sie auf bare Metal, einer VM, plain Docker oder Kubernetes läuft, ist völlig egal.

Leider haben viele den Irrglaube, Docker würde da irgendwas magisches machen, dass man sich darum nicht mehr kümmern müsste. Das ist schlichtweg falsch. Beim Wechsel von Bare Metal zu VMs wurden Updates ja auch nicht von Zauberhand unnötig. Es ändert sich lediglich die Art etwas, weil ich die Updates auf die VM statt direkt aufs Blech schiebe. Bei Docker habe ich halt ein neues Image statt einem .deb Installer Packet oder etwas ähnlichem. Wenn ich meine Docker Images und die damit gestarteten Container nicht warte, werde ich viele der Probleme bekommen die entstehen, wenn ich eine VM nicht warte.

Zitat von @Phil-DE:
Und ja, im Bezug auf die Docker Vorteile ist es mir glaub ich soweit klar das man in den Containern verschiedene Versionen von z.B. Php laufen lassen kann um Inkompitibilitätsprobleme auszuschließen.

Das ist einer der Vorteile: Du hast eine isolierte Umgebung und kannst deinen Prozess inkl. Abhängigkeiten wie Libs quasi einsperren, sodass die sich in die Quere kommen. Gibt aber noch mehr. Ein Container ist z.B. viel leichtgewichtiger, da du keinen Kernel inkl. OS pro Instanz startest. Updaten ist einfacher und ein Container ist schneller gebaut als eine komplette VM.

Zitat von @Phil-DE:
Im Bezug auf die Pipeline, ist das quasi ein crontab der quasi bspw. jeden Monat einmal den Container stoppt, den Container löscht, das Image löscht, es dann neu baut und dann wieder von alleine startet?

Nein, das ist kein Cron. Eine Pipeline ist weit mehr. Grob gesagt automatisierst du dein komplettes Deployment inklusive Tests und läuft i.d.R. bei jeder Änderung. Gibt auch andere Modelle wie z.B. Nightly Builds, dadurch bist du wahrscheinlich auf die Crons gekommen. Ich empfehle dir dich mal in das Thema CI/CD einzulesen. Da gibts ganze Wälzer drüber.

Zitat von @Phil-DE:
Und ja, mein Problem war bisher immer das ich halt immer jegliche Software auf den Server geknallt hab die halt benötigt wird. Und wenn eine Software nicht mehr lief hab ich bspw. Mysql geupdatet und dann lief jegliche andere Software nicht mehr.

Das ist eines der Probleme, die Docker lösen kann. Um das zu verhindern, hat man in der Pre-Docker Zeit VMs eingesetzt. Wenn du auf einem Server zu viele Sachen parallel installierst, wird das früher oder später Probleme geben.

Zitat von @Phil-DE:
Ich versuche mich ja auch erst an Docker, aber ich sehe das "Tool" wenn man das so nennen kann als sinnvoll und will es nutzen aber mir fehlt nun mal leider etwas das Know-How um es gut nutzen können...

Das ist Übung. Ich nutze das schon seit Jahren und hab zur Anfangszeit auch naive Fragen auf SO gestellt. Aber da bist du definitiv nicht der Einzige, diese Fragen haben teilweise Upvotes im 3-Stelligen bereich, selbst Jahre später bekomme ich immer noch welche. Ist auch keine Schande, hab noch niemandem gesehen der als Vollprofi auf die Welt gekommen ist face-wink

Zitat von @Phil-DE:
Ja das alles läuft auf einem kleinen Raspberry Pi 4 ModelB und will damit einfach nur eine kleine Intranet Seite abbilden wo ich mich an Webapps bisschen austesten kann, und sowie als DB Server für kleinere Projekte.

Je nachdem von was wir da konkret reden solltest du tendenziell eher mehr RAM einplanen, den 4er gibts ja mittlerweile auch mit 8GB. Ansonsten musst du beim RPI immer bedenken, dass der eine ARM CPU hat und keine x86. Mittlerweile gibts einige Images auch für ARM (früher musste man das alles selbst bauen), aber je nachdem was du einsetzen willst ggf nicht überall. Sei dir auch im klaren darüber, dass die Software ARM unterstützen muss! Wenn es "nur" kein Docker Image gibt kannst du mit entsprechendem Aufwand und Zeitbedarf selbst eines erstellen.

Aber wenn die SW das nicht unterstützt, wird es schon schwieriger. Bei OS kannst du selbst komplilieren/migrieren, ist halt ggf wieder Aufwand. Bei was proprietärem keine Chance. An deiner Stelle würde ich mir daher Gedanken machen was da drauf laufen lassen soll. Große OS Projekte wie der Apache sind kein Thema, die haben mittlerweile ja offizielle ARM Images. Aber bei anderen Sachen kann es schon schwieriger werden.

Bedenke auch, dass du mit dem RPI keine Ausfallsicherheit hast und für den Dauerbetrieb ein paar Sachen beachten solltest, wie z.B. SD-Kartentot durch Schreiben. Versteh mich nicht falsch, ich bin ein RPI Fan, aber das was du beschreibst klingt für mich besser auf einer Linux-VM in eurem Netz aufgehoben. Falls ihr keine Server habt und euch bewusst ist, dass die Anwendungen weg sind wenn der RPI ausfällt, kann man das natürlich machen. Grade für sehr kleine Unternehmen kann das eine Alternative sein.

Ansonsten kannst du auch von einem 4er PI natürlich keine Wunder in Sachen Performance erwarten. Jeder alte Server hat mehr Power. Auch das sollte bedacht werden, wenn ich lese, dass du da anscheinend grade alle Anwendungen auf Docker portierst und die später auf dem RPI laufen sollen.

Zitat von @Phil-DE:
Und schonmal vielen Dank für eure Hilfe und ein schönes neues Jahr 2021 was diesmal hoffentlich besser wird als 2020 im Bezug auf Lockdown, etc.

Ich wünsche dir auch noch ein frohes neues, wenn auch etwas verspätet- sorry.