Membuat container yang lebih ramping

Halaman ini menjelaskan cara mem-build image Docker yang lebih ramping.

Membuat container yang lebih ramping

Saat Anda membuat penampung aplikasi, file yang tidak diperlukan saat runtime, seperti dependensi waktu build dan file perantara, dapat secara tidak sengaja disertakan dalam image penampung. File yang tidak diperlukan ini dapat meningkatkan ukuran image container sehingga menambah waktu dan biaya ekstra saat image berpindah di antara registry Docker dan runtime container Anda.

Untuk membantu mengurangi ukuran image container, pisahkan pembuatan aplikasi, beserta alat yang digunakan untuk mem-build-nya, dari assembly container runtime.

Cloud Build menyediakan serangkaian penampung Docker dengan alat developer umum seperti Git, Docker, dan Google Cloud CLI. Gunakan alat ini untuk menentukan file konfigurasi build dengan satu langkah untuk mem-build aplikasi, dan langkah lain untuk menyusun lingkungan runtime akhirnya.

Misalnya, jika Anda mem-build aplikasi Java, yang memerlukan file seperti kode sumber, library aplikasi, sistem build, dependensi sistem build, dan JDK, Anda mungkin memiliki Dockerfile yang terlihat seperti berikut:

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"]

Dalam contoh di atas, Gradle, yang digunakan untuk mem-build paket, mendownload library dalam jumlah besar agar dapat berfungsi. Library ini penting untuk mem-build paket, tetapi tidak diperlukan saat runtime. Semua dependensi runtime dipaketkan dalam paket.

Setiap perintah di Dockerfile akan membuat lapisan baru di penampung. Jika data dibuat di lapisan tersebut dan tidak dihapus dalam perintah yang sama, ruang tersebut tidak dapat dipulihkan. Dalam hal ini, Gradle mendownload ratusan megabyte library ke direktori cache untuk melakukan build, tetapi library tidak dihapus.

Cara yang lebih efisien untuk melakukan build adalah menggunakan Cloud Build untuk memisahkan build aplikasi dari build lapisan runtime-nya.

Contoh berikut memisahkan langkah untuk mem-build aplikasi Java dari langkah untuk menyusun penampung runtime:

YAML

  1. Mem-build aplikasi: Di cloudbuild.yaml, tambahkan langkah untuk mem-build aplikasi.

    Kode berikut menambahkan langkah yang mem-build image java:8, yang berisi kode Java.

    steps:
    
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    
    
  2. Memasang penampung runtime: Di cloudbuild.yaml, tambahkan langkah untuk memasang penampung runtime.

    Kode berikut menambahkan langkah bernama gcr.io/cloud-builders/docker yang menyusun penampung runtime. File ini menentukan penampung runtime dalam file terpisah bernama Dockerfile.slim.

    Contoh ini menggunakan lapisan dasar Alpine Linux openjdk:8u111-jre-alpine, yang sangat ramping. Selain itu, IDE ini menyertakan JRE, bukan JDK yang lebih besar yang diperlukan untuk mem-build aplikasi.

    cloudbuild.yaml
    
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c',
             './gradlew gate-web:installDist -x test']
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim',
             '.'
      ]
    
    
    Dockerfile.slim
    
    FROM openjdk:8-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. Buat image Docker: Di cloudbuild.yaml, tambahkan langkah untuk membuat image.
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim', '.']
    images:
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA'
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
    

JSON

  1. Mem-build aplikasi: Di cloudbuild.json, tambahkan langkah untuk mem-build aplikasi.

    Kode berikut menambahkan langkah bernama java:8 untuk mem-build kode Java.

    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
    }
    
  2. Memasang penampung runtime: Di cloudbuild.json, tambahkan langkah untuk memasang penampung runtime.

    Kode berikut menambahkan langkah bernama gcr.io/cloud-builders/docker yang menyusun penampung runtime. File ini menentukan penampung runtime dalam file terpisah bernama Dockerfile.slim.

    Contoh ini menggunakan lapisan dasar Alpine Linux openjdk:8u111-jre-alpine, yang sangat ramping. Selain itu, IDE ini menyertakan JRE, bukan JDK yang lebih besar yang diperlukan untuk mem-build aplikasi.

    cloudbuild.json:
    
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
    }
    
    Dockerfile.slim:
    
    FROM openjdk:8u111-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. Buat image Docker: Di cloudbuild.json, tambahkan langkah untuk membuat image.
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
        "images": [
            "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
            "gcr.io/$PROJECT_ID/$REPO_NAME:latest"
        ]
    }