4. Dockerfile

Bis jetzt haben wir fertige Images (siehe hub.docker.com) genutzt und mit diesen Images die Container erstellt.

Hinweis

Später: mit docker-compose werden mehrere Container kombiniert eingerichtet!

Die meisten Images waren auch ordentliche Vorlagen, aber z.B. in Ubuntu würde man vielleicht gerne das Paket iproute2 nachinstallieren, … usw.

Also wollen wir jetzt unsere eigenen Images erstellen und bedienen uns eines Dockerfile, das alle nötigen Anweisungen enthält!

4.1. Kurzanleitung

  • Ordner für Image erstellen

  • ggf. Dateien im Ordner bereitstellen (z.B. Skripte, Webdateien/Ordner)

  • Datei Dockerfile im Ordner erzeugen und Inhalt/Konfiguration für Image festlegen

  • mit docker build ein neues Image lokal erzeugen

  • mit docker push (ggf.) im Docker-Hub veröffentlichen (wörtlich zu nehmen: public)

Alternative Veröffentlichungstechniken für eigene Images:

  • GitHub für Dockerfile bzw. Ordner/Dateien für automatisierte Builds

  • Private Image Repository auf Docker Hub ($)

  • Eigenes Docker Repository

Links:

4.2. Syntax

Schlüsselwörte für ein Dockerfile als Tabelle:

Schlüsselwort

Bedeutung

ADD

kopiert Dateien in das Dateisystem des Images

CMD

führt Kommando beim Start des Containers aus

COPY

kopiert Dateien aus Projekverzeichnis in das Image

ENTRYPOINT

führt Kommando beim Start des Containers aus

ENV

setzt eine Umgebungsvariable

EXPOSE

gibt die aktiven Ports an

FROM

gibt das Basis-Image an

LABEL

legt Zeichenkette fest

RUN

führt das Kommando aus

USER

Account für RUN, CMD und ENTRYPOINT

VOLUME

gibt Volume-Dirs an

WORKDIR

Arbeitsverzeichnis für RUN, CMD und ENTRYPOINT

Erläuterungen:

Kurze Analyse / Erläuterungen:

ADD v. COPY - scheinen ja dasselbe zu tun, aber ADD kann…

  • … auch mit URL umgehen

  • … auch (wie COPY) Verzeichnisinhalte komplett kopieren

  • … mit TAR-Archiven arbeiten/entpacken (gzip, bzip2, xz)

Beide können mit –chown=user:group Parameter umgehen.

In Kürze: COPY nur für einfaches Kopieren einer lokalen Datei.

CMD v. ENTRYPOINT - Startkommandos für Container

Wenn man Container mit mit docker run Komandos anfügt, dann …

  • … wird bei CMD das angefügte Kommando anstelle von CMD ausgeführt

  • … wird bei ENTRYPOINT das Kommando hinzugefügt

4.3. Image erstellen

Vorgehen für Beispiel 2 (s.u. einfacher Webserver)

mkdir -p /home/joeb/projektverzeichnis/samplesite
cd /home/joeb/Projekverzeichnis
touch samplesite/index.html samplesite/style.css   # HTML/CSS-Site nach Gusto
touch Dockerfile                                   # siehe Dockerfile Beispiel
docker build -t joebrandes/testwebserver .         # Image erzeugen / taggen
docker run -d -p 80:80 -p 443:443 -h webtest \     # Container erzeugen
    --name testwebserver joebrandes/testwebserver

Die normale (und https-gesicherte) Seite sollte sich jetzt im Browser öffnen lassen!

4.4. Beispiele

Ein paar Beispiele aus Öggl/Kofler…

4.4.1. Beispiel 1

Beispielhaftes erstes Dockerfile:

Dockerfile nach Öggl/Kofler (S. 63)
1
2
3
4
5
6
7
8
# Datei Dockerfile
FROM ubuntu:18.04
LABEL maintainer "kontakt@kofler.info"
RUN apt -get update && \
    apt-get install -y joe && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
CMD ["/bin/bash"]

Im Seminar analysieren - Wert legen auf Zusammenfassung für RUN mit && Konstruktion!

4.4.2. Beispiel 2

Beispiel für einfachen Webserver:

Dockerfile für Webserver nach Öggl/Kofler (S. 69)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Datei Dockerfile
FROM ubuntu:18.04

LABEL maintainer "kontakt@kofler.info"
LABEL description "Test"

# Apache installieren, und unnötige Dateien aus dem Paket - Cache
# gleich wieder entfernen
RUN apt-get update && \
    apt-get install -y apache2 && \
    apt-get -y clean && \
    rm -rf /var/cache/apt /var/lib/apt/lists/*

# HTTPS -Unterstützung aktivieren
RUN a2ensite default-ssl && a2enmod ssl

ENV APACHE_RUN_USER=www-data \
    APACHE_RUN_GROUP=www-data \
    APACHE_LOG_DIR=/var/log/apache2

EXPOSE 80 443

# gesamten Inhalt des Projektverzeichnisses
# samplesite nach /var/www/html kopieren
COPY samplesite/ /var/www/html

CMD ["/usr/sbin/apache2ctl" , "-D" , "FOREGROUND"]

4.4.3. Beispiel 3

Alpine Linux mit Apache2

Hier sind wir durch Recherchen zu Alpine Linux und diversen Dockerfile Analysen herausgefordert worden (Anm.: Apache als Prozess am Laufen halten im Container!)

Dockerfile für Alpine Linux mit Apache2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
FROM alpine

LABEL maintainer "dummy@aol.com"
LABEL description "Test Alpine und Apache"


RUN apk update && apk upgrade && \
    apk add apache2 libxml2-dev apache2-utils && \
    rm -rf /var/cache/apk/*

# war zwischendurch nötig: 
# RUN mkdir /run/apache2

ENV APACHE_RUN_USER=apache \
    APACHE_RUN_GROUP=www-data 

EXPOSE 80 443

COPY samplesite/ /var/www/localhost/htdocs

CMD ["/usr/sbin/httpd", "-DFOREGROUND"]

4.4.4. Beispiel 4

Als ausführlicheres Dockerfile-Beispiel liefern Öggl/Kofler für „Pandoc“:

Dockerfile pandoc Installationen nach Öggl/Kofler (S. 73ff.)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Datei Dockerfile
FROM haskell

# Pakete installieren
RUN apt-get update -y && \
    apt-get install -y -o Acquire::Retries=10 \
                     --no-install-recommends \
      texlive-latex-recommended \
      texlive-latex-extra \
      texlive-fonts-recommended \
      texlive-lang-german \
      texlive-pstricks \
      imagemagick \
      unzip \
      python3 \
      ghostscript \
      less && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Pandoc installieren
RUN cabal update && \
    cabal install pandoc-2.1.1 && \
    ln -s /root/.cabal/bin/pandoc /usr/bin/pandoc

# Mitteleuropäische Zeitzone
# (siehe https://serverfault.com/questions/683605)
RUN cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime

# Fonts für LaTeX installieren
# ADD rheinwerkfonts.tgz /usr/local/share/texmf
# RUN texhash

# Volume /data, bei docker run mit dem Arbeitsverzeichnis
# verbinden, also: docker run -v $(pwd):/data
WORKDIR /data
VOLUME  ["/data"]

ENTRYPOINT ["/bin/bash"]

Die Kollegen richten also - wie ich mit SphinxDoc - eine Umgebung ein, in der sie mit Hilfe von Markdown und dem Werkzeug pandoc dann HTML als auch LaTeX-Versionen für Print/PDF generieren können.