{"id":4942,"date":"2026-08-18T08:00:00","date_gmt":"2026-08-18T08:00:00","guid":{"rendered":"https:\/\/netguide.io\/linux\/?p=4942"},"modified":"2026-08-10T23:41:00","modified_gmt":"2026-08-10T23:41:00","slug":"dockerfile-eigenes-docker-image-bauen","status":"publish","type":"post","link":"https:\/\/netguide.io\/linux\/de\/dockerfile-eigenes-docker-image-bauen\/","title":{"rendered":"Eigenes Docker-Image bauen: Dockerfile-Grundlagen"},"content":{"rendered":"<script type=\"text\/plain\" data-tcf=\"waiting-for-consent\" data-id=\"4797\" data-bid=\"2\" data-placement=\"4798\">PGRpdiBpZD0ibmV0Z3VpZGVhLTI5OTYxOTE0NTAiIGNsYXNzPSJuZXRndWlkZWEtYmVmb3JlLWNvbnRlbnQgbmV0Z3VpZGVhLWVudGl0eS1wbGFjZW1lbnQiPjxkaXYgY2xhc3M9Im5ldGd1aWRlYS1hZGxhYmVsIj5BZHZlcnRpc2VtZW50czwvZGl2PjxzY3JpcHQgYXN5bmMgc3JjPSIvL3BhZ2VhZDIuZ29vZ2xlc3luZGljYXRpb24uY29tL3BhZ2VhZC9qcy9hZHNieWdvb2dsZS5qcz9jbGllbnQ9Y2EtcHViLTYyNTg1NTYyNTcyNDU5OTgiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxpbnMgY2xhc3M9ImFkc2J5Z29vZ2xlIiBzdHlsZT0iZGlzcGxheTpibG9jazsiIGRhdGEtYWQtY2xpZW50PSJjYS1wdWItNjI1ODU1NjI1NzI0NTk5OCIgCmRhdGEtYWQtc2xvdD0iMzQ5NDExNTM0MiIgCmRhdGEtYWQtZm9ybWF0PSJhdXRvIj48L2lucz4KPHNjcmlwdD4gCihhZHNieWdvb2dsZSA9IHdpbmRvdy5hZHNieWdvb2dsZSB8fCBbXSkucHVzaCh7fSk7IAo8L3NjcmlwdD4KPC9kaXY+<\/script>\n<p class=\"wp-block-paragraph\">Fertige Images vom Docker Hub reichen oft nicht \u2013 sobald du eigenen Code oder eine spezielle Konfiguration mitliefern willst, brauchst du ein eigenes Image. Daf\u00fcr gibt es das <strong>Dockerfile<\/strong>. In dieser Anleitung lernst du die Grundlagen: die wichtigsten Anweisungen, wie du ein <strong>eigenes Docker-Image baust<\/strong> und startest \u2013 und wie du es schlank h\u00e4ltst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein <strong>eigenes Docker-Image<\/strong> zu bauen ist der Moment, in dem du von einem reinen Docker-Nutzer zum Entwickler eigener Container wirst. Statt fertige Container-Images vom Docker Hub zu \u00fcbernehmen, beschreibst du im <strong>Dockerfile<\/strong> reproduzierbar, wie deine Anwendung samt Abh\u00e4ngigkeiten, Konfiguration und Startbefehl aussehen soll. Das Ergebnis l\u00e4uft auf deinem Laptop genauso wie auf dem Server \u2013 ein gro\u00dfer Vorteil gegen\u00fcber manueller Installation. In diesem Guide gehen wir \u00fcber die reinen Grundlagen hinaus und schauen uns auch <strong>Build-Kontext<\/strong>, <strong>Layer-Caching<\/strong> und <strong>Multi-Stage-Builds<\/strong> an, damit deine Images klein, sicher und schnell gebaut sind.<\/p>\n\n\n\t\t\t\t<div class=\"wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-1ffd1ad5      \"\n\t\t\t\t\tdata-scroll= \"1\"\n\t\t\t\t\tdata-offset= \"30\"\n\t\t\t\t\tstyle=\"\"\n\t\t\t\t>\n\t\t\t\t<div class=\"uagb-toc__wrap\">\n\t\t\t\t\t\t<div class=\"uagb-toc__title\">\n\t\t\t\t\t\t\tInhaltsverzeichnis\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"uagb-toc__list-wrap \">\n\t\t\t\t\t\t<ol class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#was-ist-ein-dockerfile\" class=\"uagb-toc-link__trigger\">Was ist ein Dockerfile?<\/a><li class=\"uagb-toc__list\"><a href=\"#die-wichtigsten-anweisungen\" class=\"uagb-toc-link__trigger\">Die wichtigsten Anweisungen<\/a><li class=\"uagb-toc__list\"><a href=\"#ein-einfaches-dockerfile\" class=\"uagb-toc-link__trigger\">Ein einfaches Dockerfile<\/a><li class=\"uagb-toc__list\"><a href=\"#image-bauen-und-starten\" class=\"uagb-toc-link__trigger\">Image bauen und starten<\/a><li class=\"uagb-toc__list\"><a href=\"#tipp-images-schlank-halten\" class=\"uagb-toc-link__trigger\">Tipp: Images schlank halten<\/a><li class=\"uagb-toc__list\"><a href=\"#build-kontext-und-dockerignore-verstehen\" class=\"uagb-toc-link__trigger\">Build-Kontext und .dockerignore verstehen<\/a><li class=\"uagb-toc__list\"><a href=\"#layer-caching-clever-nutzen\" class=\"uagb-toc-link__trigger\">Layer-Caching clever nutzen<\/a><li class=\"uagb-toc__list\"><a href=\"#multi-stage-builds-f\u00fcr-schlanke-images\" class=\"uagb-toc-link__trigger\">Multi-Stage-Builds f\u00fcr schlanke Images<\/a><li class=\"uagb-toc__list\"><a href=\"#h\u00e4ufige-fragen\" class=\"uagb-toc-link__trigger\">H\u00e4ufige Fragen<\/a><li class=\"uagb-toc__list\"><a href=\"#was-ist-der-unterschied-zwischen-cmd-und-entrypoint\" class=\"uagb-toc-link__trigger\">Was ist der Unterschied zwischen CMD und ENTRYPOINT?<\/a><li class=\"uagb-toc__list\"><a href=\"#warum-ist-mein-docker-image-so-gro\u00df\" class=\"uagb-toc-link__trigger\">Warum ist mein Docker-Image so gro\u00df?<\/a><li class=\"uagb-toc__list\"><a href=\"#wie-aktualisiere-ich-ein-image-nach-code\u00e4nderungen\" class=\"uagb-toc-link__trigger\">Wie aktualisiere ich ein Image nach Code\u00e4nderungen?<\/a><li class=\"uagb-toc__list\"><a href=\"#fazit\" class=\"uagb-toc-link__trigger\">Fazit<\/a><\/ol>\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Was ist ein Dockerfile?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Dockerfile ist eine Textdatei mit einer Bauanleitung. Docker liest sie Zeile f\u00fcr Zeile und erzeugt daraus ein Image \u2013 eine unver\u00e4nderliche Vorlage, aus der du beliebig viele Container startest. Wenn dir die Begriffe noch fremd sind, hilft <a href=\"https:\/\/netguide.io\/linux\/de\/was-ist-docker\/\">Was ist Docker?<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Die wichtigsten Anweisungen<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Anweisung<\/th><th>Bedeutung<\/th><\/tr><\/thead><tbody><tr><td><code>FROM<\/code><\/td><td>Basis-Image, auf dem aufgebaut wird<\/td><\/tr><tr><td><code>WORKDIR<\/code><\/td><td>Arbeitsverzeichnis im Image<\/td><\/tr><tr><td><code>COPY<\/code><\/td><td>Dateien vom Host ins Image kopieren<\/td><\/tr><tr><td><code>RUN<\/code><\/td><td>Befehl beim Bauen ausf\u00fchren (z. B. Pakete installieren)<\/td><\/tr><tr><td><code>EXPOSE<\/code><\/td><td>Dokumentiert den genutzten Port<\/td><\/tr><tr><td><code>CMD<\/code><\/td><td>Standardbefehl beim Start des Containers<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Ein einfaches Dockerfile<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Das folgende Beispiel baut ein Image f\u00fcr eine kleine Python-Anwendung:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>FROM python:3.12-slim\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\nEXPOSE 8000\nCMD [\"python\", \"app.py\"]<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color: #24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F97583\">FROM<\/span><span style=\"color: #E1E4E8\"> python:3.12-slim<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">WORKDIR<\/span><span style=\"color: #E1E4E8\"> \/app<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">COPY<\/span><span style=\"color: #E1E4E8\"> requirements.txt .<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">RUN<\/span><span style=\"color: #E1E4E8\"> pip install --no-cache-dir -r requirements.txt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">COPY<\/span><span style=\"color: #E1E4E8\"> . .<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">EXPOSE<\/span><span style=\"color: #E1E4E8\"> 8000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F97583\">CMD<\/span><span style=\"color: #E1E4E8\"> [<\/span><span style=\"color: #9ECBFF\">\"python\"<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #9ECBFF\">\"app.py\"<\/span><span style=\"color: #E1E4E8\">]<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Image bauen und starten<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Im Verzeichnis mit dem Dockerfile baust du das Image mit <code>docker build<\/code>. Der Parameter <code>-t<\/code> vergibt einen Namen (Tag):<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>docker build -t meine-app:1.0 .<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color: #24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #B392F0\">docker<\/span><span style=\"color: #9ECBFF\"> build<\/span><span style=\"color: #79B8FF\"> -t<\/span><span style=\"color: #9ECBFF\"> meine-app:1.0<\/span><span style=\"color: #9ECBFF\"> .<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Anschlie\u00dfend startest du einen Container daraus:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>docker run -d -p 8000:8000 --name app meine-app:1.0<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color: #24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #B392F0\">docker<\/span><span style=\"color: #9ECBFF\"> run<\/span><span style=\"color: #79B8FF\"> -d<\/span><span style=\"color: #79B8FF\"> -p<\/span><span style=\"color: #9ECBFF\"> 8000:8000<\/span><span style=\"color: #79B8FF\"> --name<\/span><span style=\"color: #9ECBFF\"> app<\/span><span style=\"color: #9ECBFF\"> meine-app:1.0<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Tipp: Images schlank halten<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Schlanke Basis w\u00e4hlen:<\/strong> Varianten wie <code>-slim<\/code> oder <code>alpine<\/code> sparen viel Platz.<\/li>\n\n\n\n<li><strong>.dockerignore nutzen:<\/strong> Schlie\u00dfe unn\u00f6tige Dateien (z. B. <code>.git<\/code>) vom Build aus.<\/li>\n\n\n\n<li><strong>Layer zusammenfassen:<\/strong> Fasse zusammengeh\u00f6rige <code>RUN<\/code>-Befehle mit <code>&amp;&amp;<\/code> zusammen.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Gro\u00dfe, ungenutzte Build-Reste entfernst du sp\u00e4ter beim <a href=\"https:\/\/netguide.io\/linux\/de\/docker-aufraeumen-speicherplatz-freigeben\/\">Aufr\u00e4umen<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Build-Kontext und .dockerignore verstehen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn du <code>docker build -t meine-app:1.0 .<\/code> ausf\u00fchrst, ist der Punkt am Ende der sogenannte <strong>Build-Kontext<\/strong>: das gesamte Verzeichnis, das Docker an den Daemon \u00fcbertr\u00e4gt. Alles, was dort liegt, kann per <code>COPY<\/code> ins Image gelangen \u2013 aber alles wird auch erst einmal \u00fcbertragen. Bei gro\u00dfen Projektordnern verlangsamt das den Build sp\u00fcrbar und schleust im schlimmsten Fall Geheimnisse ein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die L\u00f6sung ist eine <code>.dockerignore<\/code>-Datei neben dem Dockerfile. Sie funktioniert wie eine <code>.gitignore<\/code> und h\u00e4lt unn\u00f6tige oder sensible Dateien aus dem Kontext heraus:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>.git<\/strong> \u2013 die komplette Versionshistorie geh\u00f6rt nicht ins Image.<\/li>\n\n\n\n<li><strong>node_modules<\/strong> oder <strong>venv<\/strong> \u2013 Abh\u00e4ngigkeiten installierst du im Build ohnehin neu.<\/li>\n\n\n\n<li><strong>.env<\/strong> und Schl\u00fcsseldateien \u2013 Secrets haben in einem Image nichts verloren.<\/li>\n\n\n\n<li><strong>*.log, tmp\/, Testdaten<\/strong> \u2013 aufbl\u00e4hen ohne Nutzen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Layer-Caching clever nutzen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Jede Anweisung im Dockerfile erzeugt einen <strong>Layer<\/strong>. Docker speichert diese Layer und verwendet sie beim n\u00e4chsten Build wieder, solange sich Eingaben nicht ge\u00e4ndert haben. Genau deshalb steht im Beispiel oben <code>COPY requirements.txt .<\/code> und der <code>RUN pip install<\/code> <em>vor<\/em> dem <code>COPY . .<\/code> des restlichen Codes: Solange sich deine Abh\u00e4ngigkeiten nicht \u00e4ndern, bleibt der teure Installationsschritt im Cache und der Build dauert Sekunden statt Minuten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Als Faustregel gilt: Ordne die Anweisungen von <strong>selten ge\u00e4ndert<\/strong> (Basis-Image, System-Pakete, Abh\u00e4ngigkeiten) nach <strong>h\u00e4ufig ge\u00e4ndert<\/strong> (dein Quellcode). Sobald ein Layer neu gebaut werden muss, werden auch alle nachfolgenden Layer verworfen \u2013 deshalb kostet eine ung\u00fcnstige Reihenfolge bei jedem kleinen Code\u00e4nderung unn\u00f6tig Zeit.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Multi-Stage-Builds f\u00fcr schlanke Images<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Compiler, Build-Tools und Entwicklungs-Bibliotheken brauchst du zum Bauen, aber nicht zur Laufzeit. Mit einem <strong>Multi-Stage-Build<\/strong> nutzt du eine erste Stufe zum Kompilieren und kopierst nur das fertige Artefakt in ein schlankes finales Image. Dazu definierst du mehrere <code>FROM<\/code>-Anweisungen und kopierst mit <code>COPY --from=builder<\/code> gezielt Dateien aus der Build-Stufe.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ergebnis ist ein Image, das oft nur einen Bruchteil der urspr\u00fcnglichen Gr\u00f6\u00dfe hat \u2013 ein Go- oder Node-Build schrumpft so schnell von mehreren Hundert MB auf wenige Dutzend. Kleinere Images bedeuten schnelleres Deployment, weniger Angriffsfl\u00e4che und geringeren Speicherverbrauch in deiner <a href=\"https:\/\/netguide.io\/linux\/de\/docker-compose-installieren-ubuntu-debian\/\">Docker-Compose<\/a>-Umgebung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor du dein Image auf einen Server bringst, lohnt sich ein kurzer Blick auf ein paar bew\u00e4hrte Praktiken, die Sicherheit und Wartbarkeit deutlich verbessern:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Feste Versionen taggen:<\/strong> Nutze <code>python:3.12-slim<\/code> statt <code>latest<\/code>, damit Builds reproduzierbar bleiben.<\/li>\n\n\n\n<li><strong>Nicht als root laufen:<\/strong> Lege mit <code>RUN useradd<\/code> einen eigenen Benutzer an und wechsle per <code>USER<\/code>-Anweisung dorthin.<\/li>\n\n\n\n<li><strong>Nur n\u00f6tige Ports \u00f6ffnen:<\/strong> <code>EXPOSE<\/code> dokumentiert klar, wor\u00fcber dein Dienst erreichbar ist.<\/li>\n\n\n\n<li><strong>Regelm\u00e4\u00dfig neu bauen:<\/strong> So landen Sicherheitsupdates des Basis-Images automatisch in deinem Container-Image.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">H\u00e4ufige Fragen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rund um das Bauen eigener Images tauchen immer wieder dieselben Fragen auf. Hier die wichtigsten kurz beantwortet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Was ist der Unterschied zwischen CMD und ENTRYPOINT?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>CMD<\/code> legt den Standardbefehl fest, den du beim <code>docker run<\/code> leicht \u00fcberschreiben kannst. <code>ENTRYPOINT<\/code> definiert einen festen Startbefehl, an den zus\u00e4tzliche Argumente angeh\u00e4ngt werden. F\u00fcr einfache Anwendungen reicht <code>CMD<\/code>; brauchst du ein Image, das sich wie ein einzelnes Kommando verh\u00e4lt, kombinierst du beide.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Warum ist mein Docker-Image so gro\u00df?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Meist liegt es am Basis-Image oder an zwischengespeicherten Paketlisten. W\u00e4hle eine <code>-slim<\/code>&#8211; oder <code>alpine<\/code>-Variante, r\u00e4ume im selben <code>RUN<\/code>-Layer auf (etwa <code>rm -rf \/var\/lib\/apt\/lists\/*<\/code>) und pr\u00fcfe mit <code>docker image ls<\/code> sowie <code>docker history meine-app:1.0<\/code>, welche Layer den Platz belegen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wie aktualisiere ich ein Image nach Code\u00e4nderungen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Du baust es einfach neu mit <code>docker build -t meine-app:1.1 .<\/code>. Dank Layer-Caching werden nur die ge\u00e4nderten Schritte neu ausgef\u00fchrt. Anschlie\u00dfend startest du einen frischen Container aus dem neuen Tag \u2013 der alte Container \u00fcbernimmt \u00c4nderungen nicht automatisch.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Fazit<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Mit <code>FROM<\/code>, <code>COPY<\/code>, <code>RUN<\/code> und <code>CMD<\/code> hast du die vier wichtigsten Bausteine eines Dockerfiles beisammen. <code>docker build<\/code> macht daraus ein Image, aus dem du Container startest. Achte auf eine schlanke Basis, dann bleiben deine Images klein und schnell. Im n\u00e4chsten Schritt kombinierst du dein Image mit <a href=\"https:\/\/netguide.io\/linux\/de\/docker-compose-installieren-ubuntu-debian\/\">Docker Compose<\/a> und einem <a href=\"https:\/\/netguide.io\/linux\/de\/docker-healthcheck-einrichten\/\">Healthcheck<\/a>.<\/p>\n<script type=\"text\/plain\" data-tcf=\"waiting-for-consent\" data-id=\"4799\" data-bid=\"2\" data-placement=\"4800\">PGRpdiBpZD0ibmV0Z3VpZGVhLTIxNzcxNjA4MjIiIGNsYXNzPSJuZXRndWlkZWEtYWZ0ZXItY29udGVudCBuZXRndWlkZWEtZW50aXR5LXBsYWNlbWVudCI+PGRpdiBjbGFzcz0ibmV0Z3VpZGVhLWFkbGFiZWwiPkFkdmVydGlzZW1lbnRzPC9kaXY+PHNjcmlwdCBhc3luYyBzcmM9Ii8vcGFnZWFkMi5nb29nbGVzeW5kaWNhdGlvbi5jb20vcGFnZWFkL2pzL2Fkc2J5Z29vZ2xlLmpzP2NsaWVudD1jYS1wdWItNjI1ODU1NjI1NzI0NTk5OCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PGlucyBjbGFzcz0iYWRzYnlnb29nbGUiIHN0eWxlPSJkaXNwbGF5OmJsb2NrOyIgZGF0YS1hZC1jbGllbnQ9ImNhLXB1Yi02MjU4NTU2MjU3MjQ1OTk4IiAKZGF0YS1hZC1zbG90PSI0NTU5Nzg1MDAyIiAKZGF0YS1hZC1mb3JtYXQ9ImF1dG8iPjwvaW5zPgo8c2NyaXB0PiAKKGFkc2J5Z29vZ2xlID0gd2luZG93LmFkc2J5Z29vZ2xlIHx8IFtdKS5wdXNoKHt9KTsgCjwvc2NyaXB0Pgo8L2Rpdj4=<\/script>","protected":false},"excerpt":{"rendered":"<p>Ein eigenes Docker-Image mit einem Dockerfile bauen: die wichtigsten Anweisungen (FROM, COPY, RUN, CMD), Image bauen, starten und schlanke Images erstellen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[231,9],"tags":[],"class_list":["post-4942","post","type-post","status-publish","format-standard","hentry","category-docker","category-linux"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Tobias Pries","author_link":"https:\/\/netguide.io\/linux\/author\/tobias-pries\/"},"uagb_comment_info":0,"uagb_excerpt":"Ein eigenes Docker-Image mit einem Dockerfile bauen: die wichtigsten Anweisungen (FROM, COPY, RUN, CMD), Image bauen, starten und schlanke Images erstellen.","brizy_media":[],"_links":{"self":[{"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/posts\/4942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/comments?post=4942"}],"version-history":[{"count":1,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/posts\/4942\/revisions"}],"predecessor-version":[{"id":4965,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/posts\/4942\/revisions\/4965"}],"wp:attachment":[{"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/media?parent=4942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/categories?post=4942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/netguide.io\/linux\/wp-json\/wp\/v2\/tags?post=4942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}