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 FROMAnweisungen in Ihrer Docker-Datei. Jeder FROMBefehl 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 Dockerfiledrei 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"]
.dockerignorewiederholt den Inhalt der .gitignoreDatei (verhindert, dass die node_modulesresultierenden distVerzeichnisse 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_PASSPHRASEArgument an.
So funktioniert es:
1). Nur in der ersten Phase package.jsonwerden yarn.lockDateien 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 yarninstalliert 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 distVerzeichnis des nächsten benannten Zwischenabbilds abgelegt production. Beachten Sie, dass der Quellcode der installierten node_modulesDatei aus dem sourcesin 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_modulesVerzeichnis vom ersten Zwischenbild, nein SSH_KEYund SSH_KEY_PASSPHRASEArgumente 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.0indem wir nur das distVerzeichnis des zweiten Zwischenabbilds mit dem Namen einschließen productionund 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_KEYund SSH_KEY_PASSPHRASEim endgültigen Bild sehen.