Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
Questa pagina descrive come creare immagini Docker più snelle.
Creazione di container più snelli
Quando esegui il containerizzazione di un'applicazione, i file non necessari in fase di esecuzione, come le dipendenze di compilazione e i file intermedi, possono essere inclusi inavvertitamente nell'immagine del contenitore. Questi file non necessari possono aumentare le dimensioni dell'immagine del contenitore e, di conseguenza, aggiungere tempo e costi aggiuntivi durante il trasferimento dell'immagine tra il registry Docker e il runtime del contenitore.
Per contribuire a ridurre le dimensioni dell'immagine del container, separa la compilazione dell'applicazione, insieme agli strumenti utilizzati per compilarla, dall'assemblaggio del container di runtime.
Cloud Build fornisce una serie di container Docker con strumenti comuni per gli sviluppatori come Git, Docker e l'interfaccia a riga di comando Google Cloud. Utilizza questi strumenti per definire un file di configurazione della build con un passaggio per compilare l'applicazione e un altro per assemblare il relativo ambiente di runtime finale.
Ad esempio, se stai creando un'applicazione Java, che richiede file come il codice sorgente, le librerie dell'applicazione, i sistemi di compilazione, le dipendenze del sistema di compilazione e il JDK, potresti avere un Dockerfile simile al seguente:
FROM java:8
COPY . workdir/
WORKDIR workdir
RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test
RUN dpkg -i ./gate-web/build/distributions/*.deb
CMD ["/opt/gate/bin/gate"]
Nell'esempio riportato sopra, Gradle, che viene utilizzato per compilare il pacchetto, scarica un gran numero di librerie per funzionare. Queste librerie sono essenziali per la compilazione del pacchetto, ma non sono necessarie in fase di esecuzione. Tutte le dipendenze di runtime sono raggruppate nel pacchetto.
Ogni comando in Dockerfile crea un nuovo livello nel contenitore. Se i dati vengono generati in quel livello e non vengono eliminati nello stesso comando, lo spazio non può essere recuperato. In questo caso, Gradle scarica centinaia di megabyte di librerie nella directory cache per eseguire la compilazione, ma le librerie non vengono eliminate.
Un modo più efficiente per eseguire la compilazione è utilizzare Cloud Build per separare la compilazione dell'applicazione dalla compilazione del relativo livello di runtime.
L'esempio seguente separa il passaggio per la compilazione dell'applicazione Java dal passaggio per l'assemblaggio del contenitore del runtime:
YAML
Crea l'applicazione: in cloudbuild.yaml, aggiungi un passaggio per compilare l'applicazione.
Il codice seguente aggiunge un passaggio che genera l'immagine java:8, che contiene il codice Java.
Assembla il contenitore del runtime: in cloudbuild.yaml,
aggiungi un passaggio per assemblare il contenitore del runtime.
Il codice seguente aggiunge un passaggio denominato
gcr.io/cloud-builders/docker che assembla il contenitore
del runtime. Definisce il contenitore di runtime in un file separato denominato
Dockerfile.slim.
L'esempio utilizza il livello di base di Alpine Linux
openjdk:8u111-jre-alpine, che è incredibilmente snello. Inoltre, include il JRE anziché il JDK più ingombrante necessario per compilare l'applicazione.
Assembla il contenitore di runtime: in cloudbuild.json, aggiungi un
passaggio per assemblare il contenitore di runtime.
Il codice seguente aggiunge un passaggio denominato
gcr.io/cloud-builders/docker che assembla il contenitore
del runtime. Definisce il contenitore di runtime in un file separato denominato
Dockerfile.slim.
L'esempio utilizza il livello di base di Alpine Linux
openjdk:8u111-jre-alpine, che è incredibilmente snello. Inoltre, include il JRE anziché il JDK più ingombrante necessario per compilare l'applicazione.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Difficile da capire","hardToUnderstand","thumb-down"],["Informazioni o codice di esempio errati","incorrectInformationOrSampleCode","thumb-down"],["Mancano le informazioni o gli esempi di cui ho bisogno","missingTheInformationSamplesINeed","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-09-04 UTC."],[[["\u003cp\u003eBuilding leaner Docker images involves separating the application build process from the assembly of the runtime environment.\u003c/p\u003e\n"],["\u003cp\u003eUnnecessary files, such as build-time dependencies and intermediate files, can bloat container image sizes, adding extra time and cost.\u003c/p\u003e\n"],["\u003cp\u003eCloud Build can be used to define separate steps for building the application and assembling its runtime environment, leveraging tools like Git, Docker, and the Google Cloud CLI.\u003c/p\u003e\n"],["\u003cp\u003eUsing a separate, lean base layer like Alpine Linux (e.g., \u003ccode\u003eopenjdk:8u111-jre-alpine\u003c/code\u003e) in a \u003ccode\u003eDockerfile.slim\u003c/code\u003e can significantly reduce the final image size by only using the JRE instead of the JDK.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003ecloudbuild.yaml\u003c/code\u003e or \u003ccode\u003ecloudbuild.json\u003c/code\u003e files define the build steps to build and assemble the runtime container, using a separate \u003ccode\u003eDockerfile.slim\u003c/code\u003e and creating the final Docker image.\u003c/p\u003e\n"]]],[],null,["# Building leaner containers\n\nThis page describes how to build leaner Docker images.\n\nBuilding leaner containers\n--------------------------\n\nWhen you containerize an application, files that are not needed at runtime, such\nas build-time dependencies and intermediate files, can be inadvertently included\nin the container image. These unneeded files can increase the size of the\ncontainer image and thus add extra time and cost as the image moves between your\nDocker registry and your container runtime.\n\nTo help reduce the size of your container image, separate the building of the\napplication, along with the tools used to build it, from the assembly of the\nruntime container.\n\nCloud Build provides a [series of Docker\ncontainers](https://github.com/GoogleCloudPlatform/cloud-builders) with common\ndeveloper tools such as Git, Docker, and the Google Cloud CLI. Use\nthese tools to define a build config file with one step to build the\napplication, and another step to assemble its final runtime environment.\n\nFor example, if you're building a Java application, which requires files such as\nthe source code, application libraries, build systems, build system\ndependencies, and the JDK, you might have a Dockerfile that looks like the\nfollowing: \n\n FROM java:8\n\n COPY . workdir/\n\n WORKDIR workdir\n\n RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test\n\n RUN dpkg -i ./gate-web/build/distributions/*.deb\n\n CMD [\"/opt/gate/bin/gate\"]\n\nIn the above example, Gradle, which is used to build the package, downloads a\nlarge number of libraries in order to function. These libraries are essential to\nthe building of the package, but are not needed at runtime. All of the runtime\ndependencies are bundled up in the package.\n\nEach command in the `Dockerfile` creates a new layer in the container. If data\nis generated in that layer and is not deleted in the same command, that space\ncannot be recovered. In this case Gradle is downloading hundreds of megabytes of\nlibraries to the `cache` directory in order to perform the build, but the\nlibraries are not deleted.\n\nA more efficient way to perform the build is to use Cloud Build to\nseparate building the application from building its runtime layer.\n\nThe following example separates the step for building the Java application from\nthe step for assembling the runtime container: \n\n### YAML\n\n1. **Build the application** : In `cloudbuild.yaml`, add\n a step to build the application.\n\n The following code adds a step that builds the `java:8` image,\n which contains the Java code. \n\n ```\n steps:\n\n - name: 'java:8'\n env: ['GRADLE_USER_HOME=cache']\n entrypoint: 'bash'\n args: ['-c', './gradlew gate-web:installDist -x test']\n\n ```\n2. **Assemble the runtime container** : In `cloudbuild.yaml`, add a step to assemble the runtime container.\n\n \u003cbr /\u003e\n\n The following code adds a step named\n `gcr.io/cloud-builders/docker` that assembles the runtime\n container. It defines the runtime container in a separate file named\n `Dockerfile.slim`.\n\n The example uses the Alpine Linux base layer\n `openjdk:8u111-jre-alpine`, which is incredibly lean. Also, it\n includes the JRE, instead of the bulkier JDK that was necessary to build the\n application. \n\n ```\n cloudbuild.yaml\n\n steps:\n - name: 'java:8'\n env: ['GRADLE_USER_HOME=cache']\n entrypoint: 'bash'\n args: ['-c',\n './gradlew gate-web:installDist -x test']\n\n - name: 'gcr.io/cloud-builders/docker'\n args: ['build',\n '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',\n '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',\n '-f', 'Dockerfile.slim',\n '.'\n ]\n\n\n Dockerfile.slim\n\n FROM openjdk:8-jre-alpine\n\n COPY ./gate-web/build/install/gate /opt/gate\n\n CMD [\"/opt/gate/bin/gate\"]\n ```\n3. **Create the Docker images** : In `cloudbuild.yaml`, add a step to create the images. \n\n ```\n steps:\n - name: 'java:8'\n env: ['GRADLE_USER_HOME=cache']\n entrypoint: 'bash'\n args: ['-c', './gradlew gate-web:installDist -x test']\n - name: 'gcr.io/cloud-builders/docker'\n args: ['build',\n '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',\n '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',\n '-f', 'Dockerfile.slim', '.']\n images:\n - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA'\n - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'\n ```\n\n### JSON\n\n1. **Build the application** : In `cloudbuild.json`, add a step to\n build the application.\n\n The following code adds a step named `java:8` for\n building the Java code. \n\n ```\n {\n \"steps\": [\n {\n \"name\": \"java:8\",\n \"env\": [\n \"GRADLE_USER_HOME=cache\"\n ],\n \"entrypoint\": \"bash\",\n \"args\": [\n \"-c\",\n \"./gradlew gate-web:installDist -x test\"\n ]\n },\n }\n ```\n2. **Assemble the runtime container** : In `cloudbuild.json`, add a\n step to assemble the runtime container.\n\n The following code adds a step named\n `gcr.io/cloud-builders/docker` that assembles the runtime\n container. It defines the runtime container in a separate file named\n `Dockerfile.slim`.\n\n The example uses the Alpine Linux base layer\n `openjdk:8u111-jre-alpine`, which is incredibly lean. Also, it\n includes the JRE, instead of the bulkier JDK that was necessary to build the\n application. \n\n ```\n cloudbuild.json:\n\n {\n \"steps\": [\n {\n \"name\": \"java:8\",\n \"env\": [\n \"GRADLE_USER_HOME=cache\"\n ],\n \"entrypoint\": \"bash\",\n \"args\": [\n \"-c\",\n \"./gradlew gate-web:installDist -x test\"\n ]\n },\n {\n \"name\": \"gcr.io/cloud-builders/docker\",\n \"args\": [\n \"build\",\n \"-t\",\n \"gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA\",\n \"-t\",\n \"gcr.io/$PROJECT_ID/$REPO_NAME:latest\",\n \"-f\",\n \"Dockerfile.slim\",\n \".\"\n ]\n }\n ],\n }\n\n Dockerfile.slim:\n\n FROM openjdk:8u111-jre-alpine\n\n COPY ./gate-web/build/install/gate /opt/gate\n\n CMD [\"/opt/gate/bin/gate\"]\n ```\n3. **Create the Docker images** : In `cloudbuild.json`, add a step to create the images. \n\n ```\n {\n \"steps\": [\n {\n \"name\": \"java:8\",\n \"env\": [\n \"GRADLE_USER_HOME=cache\"\n ],\n \"entrypoint\": \"bash\",\n \"args\": [\n \"-c\",\n \"./gradlew gate-web:installDist -x test\"\n ]\n },\n {\n \"name\": \"gcr.io/cloud-builders/docker\",\n \"args\": [\n \"build\",\n \"-t\",\n \"gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA\",\n \"-t\",\n \"gcr.io/$PROJECT_ID/$REPO_NAME:latest\",\n \"-f\",\n \"Dockerfile.slim\",\n \".\"\n ]\n }\n ],\n \"images\": [\n \"gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA\",\n \"gcr.io/$PROJECT_ID/$REPO_NAME:latest\"\n ]\n }\n ```"]]