Membuat container yang lebih ramping

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

Membuat container yang lebih ramping

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

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

Cloud Build menyediakan serangkaian container 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 lainnya 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"]

Pada contoh di atas, Gradle, yang digunakan untuk mem-build paket, mendownload sejumlah besar library agar dapat berfungsi. Library ini sangat penting untuk pembuatan paket, tetapi tidak diperlukan saat runtime. Semua dependensi runtime digabungkan dalam paket.

Setiap perintah di Dockerfile membuat lapisan baru dalam container. Jika data dibuat dalam 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 menjalankan build, tetapi library tersebut tidak dihapus.

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

Contoh berikut memisahkan langkah membangun aplikasi Java dari langkah menyusun penampung runtime:

YAML

  1. Build the application: Di cloudbuild.yaml, tambahkan langkah untuk membangun aplikasi.

    Kode berikut menambahkan langkah yang membuat 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. Merakit penampung runtime: Di cloudbuild.yaml, tambahkan langkah untuk menyusun 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, aplikasi ini juga mencakup JRE, bukan JDK berukuran 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. Build aplikasi: Di cloudbuild.json, tambahkan langkah untuk mem-build aplikasi.

    Kode berikut menambahkan langkah bernama java:8 untuk membangun kode Java.

    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
    }
    
  2. Merakit container runtime: Di cloudbuild.json, tambahkan langkah untuk menyusun container 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, aplikasi ini juga mencakup JRE, bukan JDK berukuran 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"
        ]
    }