Erweiterung der Antwort von Peter Grainger Ich konnte den seit Docker 17.05 verfügbaren mehrstufigen Build verwenden . Offizielle Seite besagt:
Bei mehrstufigen Builds verwenden Sie mehrere FROM
Anweisungen in Ihrer Docker-Datei. Jeder FROM
Befehl kann eine andere Basis verwenden, und jeder von ihnen beginnt eine neue Phase des Builds. Sie können Artefakte selektiv von einer Stufe in eine andere kopieren und alles, was Sie nicht wollen, im endgültigen Bild zurücklassen.
Wenn ich dies hier berücksichtige, ist dies mein Beispiel für die Aufnahme von Dockerfile
drei Erstellungsphasen. Es soll ein Produktionsabbild der Client-Webanwendung erstellen.
# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
chmod 0700 /root/.ssh && \
ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
yarn --pure-lockfile --mutex file --network-concurrency 1 && \
rm -rf /root/.ssh/
# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod
# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]
.dockerignore
wiederholt den Inhalt der .gitignore
Datei (verhindert, dass die node_modules
resultierenden dist
Verzeichnisse des Projekts kopiert werden):
.idea
dist
node_modules
*.log
Befehlsbeispiel zum Erstellen eines Images:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
Wenn Ihr privater SSH-Schlüssel keine Passphrase hat, geben Sie einfach ein leeres SSH_KEY_PASSPHRASE
Argument an.
So funktioniert es:
1). Nur in der ersten Phase package.json
werden yarn.lock
Dateien und der private SSH-Schlüssel in das erste benannte Zwischenbild kopiert sources
. Um weitere Eingabeaufforderungen für SSH-Schlüssel zu vermeiden, wird diese automatisch hinzugefügt ssh-agent
. Schließlich yarn
installiert der Befehl alle erforderlichen Abhängigkeiten von NPM und klont private Git-Repositorys von Bitbucket über SSH.
2). In der zweiten Phase wird der Quellcode der Webanwendung erstellt, minimiert und im dist
Verzeichnis des nächsten benannten Zwischenabbilds abgelegt production
. Beachten Sie, dass der Quellcode der installierten node_modules
Datei aus dem sources
in der ersten Phase erstellten Image mit der folgenden Zeile kopiert wird:
COPY --from=sources /app/ /app/
Wahrscheinlich könnte es auch die folgende Zeile sein:
COPY --from=sources /app/node_modules/ /app/node_modules/
Wir haben hier nur noch das node_modules
Verzeichnis vom ersten Zwischenbild, nein SSH_KEY
und SSH_KEY_PASSPHRASE
Argumente mehr. Der gesamte Rest, der für die Erstellung benötigt wird, wird aus unserem Projektverzeichnis kopiert.
3). In der dritten Stufe reduzieren wir die Größe des endgültigen Images, das als gekennzeichnet wird, ezze/geoport:0.6.0
indem wir nur das dist
Verzeichnis des zweiten Zwischenabbilds mit dem Namen einschließen production
und Node Express zum Starten eines Webservers installieren.
Das Auflisten von Bildern ergibt eine Ausgabe wie folgt:
REPOSITORY TAG IMAGE ID CREATED SIZE
ezze/geoport 0.6.0 8e8809c4e996 3 hours ago 717MB
<none> <none> 1f6518644324 3 hours ago 1.1GB
<none> <none> fa00f1182917 4 hours ago 1.63GB
node carbon b87c2ad8344d 4 weeks ago 676MB
Dabei entsprechen nicht markierte Bilder der ersten und der zweiten Zwischenstufe.
Wenn du läufst
$ docker history ezze/geoport:0.6.0 --no-trunc
Sie werden keine Erwähnungen von SSH_KEY
und SSH_KEY_PASSPHRASE
im endgültigen Bild sehen.