BAB 53: Go Vendoring — Dependensi Tanpa Internet

Pelajari cara menggunakan go mod vendor untuk menyimpan semua dependensi secara lokal, memastikan build yang konsisten tanpa bergantung pada ketersediaan jaringan atau registry eksternal.

KontenKu sudah menggunakan beberapa dependensi eksternal — mongo-go-driver untuk MongoDB, testify untuk unit test, driver MySQL, dan kemungkinan akan bertambah seiring fitur yang berkembang. Semua dependensi ini tersimpan di cache Go lokal dan dicatat di go.mod beserta go.sum. Saat pertama kali build di mesin baru atau di CI/CD, Go akan mengunduh ulang semuanya dari internet.

Ini bekerja dengan baik — sampai jaringan tidak tersedia, registry mengalami gangguan, atau versi yang dibutuhkan dihapus dari sumber aslinya. Vendoring adalah solusinya: semua kode dependensi disimpan langsung di dalam repository, di folder vendor/, sehingga build bisa berjalan sepenuhnya offline dan hasilnya identik di semua mesin.

Apa Itu Vendor Folder

Ketika kamu menjalankan go mod vendor, Go menyalin semua kode dependensi dari cache lokal ke folder vendor/ di root project. Struktur di dalamnya mengikuti path import masing-masing package, sehingga mudah ditelusuri secara manual jika diperlukan.

Setelah folder vendor/ ada, Go secara otomatis memprioritaskannya sebagai sumber dependensi — kode tidak lagi diunduh dari internet saat build. Ini berbeda dari go get yang memperbarui versi; vendoring hanya membekukan apa yang sudah ada di go.mod ke dalam file fisik.

Folder vendor/ biasanya di-commit ke repository bersama kode sumber. Ini menambah ukuran repository, tapi memberikan jaminan reprodusibilitas build yang tidak bisa diberikan oleh go.sum sendirian.

Menyiapkan Vendor

Asumsikan KontenKu sudah punya go.mod dengan beberapa dependensi yang sudah di-go get. Jalankan satu perintah untuk membuat folder vendor:

go mod vendor

Setelah selesai, struktur project akan bertambah seperti ini:

kontenku/
├── go.mod
├── go.sum
├── vendor/
│   ├── modules.txt          ← daftar module yang di-vendor
│   ├── github.com/
│   │   ├── mongodb/
│   │   │   └── mongo-go-driver/
│   │   └── stretchr/
│   │       └── testify/
│   └── go.mongodb.org/
│       └── mongo-driver/
├── main.go
└── statistik.go

File vendor/modules.txt adalah manifest internal yang digunakan Go untuk memvalidasi konsistensi antara go.mod dan isi folder vendor/. Jangan edit file ini secara manual.

Build dan Run dengan Vendor

Setelah vendor tersedia, tambahkan flag -mod=vendor saat menjalankan atau membangun program:

# Menjalankan program menggunakan vendor
go run -mod=vendor main.go

# Build binary menggunakan vendor
go build -mod=vendor -o kontenku-server ./...

# Menjalankan test menggunakan vendor
go test -mod=vendor ./...

Tanpa flag ini, Go mungkin mencoba mengunduh dependensi dari internet meskipun folder vendor/ ada — terutama pada Go versi lama. Pada Go 1.14 ke atas, jika folder vendor/ terdeteksi dan go.mod ada, Go secara otomatis menggunakan -mod=vendor. Tapi menambahkannya secara eksplisit di skrip CI/CD adalah praktik yang lebih aman dan eksplisit.

Memperbarui Vendor

Vendor bukan salinan yang beku selamanya. Ketika kamu memperbarui dependensi atau menambahkan yang baru, jalankan lagi:

# Tambah dependensi baru
go get github.com/some/package@v1.2.3

# Perbarui vendor agar sesuai dengan go.mod yang baru
go mod vendor

Setelah go mod vendor dijalankan ulang, isi folder vendor/ akan diperbarui sesuai dengan go.mod terbaru. Perubahan di folder vendor/ ini kemudian bisa di-commit ke repository.

Untuk memverifikasi bahwa isi vendor konsisten dengan go.mod tanpa harus menjalankan build penuh:

go mod verify

Perintah ini memeriksa bahwa checksum dependensi di go.sum cocok dengan isi vendor/. Jika ada yang tidak cocok, Go akan melaporkan inkonsistensi.

Kapan Pakai Vendor, Kapan Tidak

Vendoring bukan keharusan — ini adalah pilihan yang tergantung kebutuhan project. Tabel berikut membantu menentukan kapan vendoring memberikan nilai nyata:

SituasiRekomendasi
Project yang di-deploy ke environment tanpa internetGunakan vendor
CI/CD yang membutuhkan reproducible buildGunakan vendor
Library publik yang dikonsumsi orang lainTidak perlu vendor
Project kecil dengan dependensi sedikitOpsional
Monorepo dengan banyak sub-modulePertimbangkan per-module
Team yang memprioritaskan ukuran repository kecilAndalkan go.sum saja

Untuk KontenKu yang akan di-deploy ke server produksi, vendoring memberikan jaminan bahwa binary yang dibangun di laptop developer identik dengan yang dibangun di server — tidak ada variabel dari jaringan atau ketersediaan registry.

Tambahkan baris berikut ke .gitignore jika kamu memutuskan untuk tidak menggunakan vendor (supaya folder vendor tidak ter-commit secara tidak sengaja jika seseorang menjalankan go mod vendor secara lokal):

vendor/

Sebaliknya, jika memutuskan menggunakan vendor, hapus baris tersebut dari .gitignore.

Vendor di Pipeline CI/CD

Contoh konfigurasi GitHub Actions yang memanfaatkan vendor untuk mempercepat pipeline:

# .github/workflows/build.yml
name: Build KontenKu

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.26'

      - name: Build
        run: go build -mod=vendor -o kontenku-server ./...

      - name: Test
        run: go test -mod=vendor ./...

Dengan vendor sudah ter-commit, step “Build” dan “Test” tidak perlu lagi mengunduh dependensi — semuanya sudah ada di repository. Ini membuat pipeline lebih cepat dan tidak bergantung pada ketersediaan jaringan saat CI berjalan.

Latihan

Latihan 1 — Setup vendor lokal: Buat project Go sederhana baru, tambahkan satu dependensi eksternal menggunakan go get, lalu jalankan go mod vendor. Verifikasi isi folder vendor/ dan pastikan go run -mod=vendor main.go berjalan tanpa error.

Latihan 2 — Simulasi offline build: Setelah vendor tersedia, nonaktifkan koneksi internet (atau set GONOSUMCHECK=* dan GOFLAGS=-mod=vendor), lalu coba build ulang project. Konfirmasi bahwa build berhasil sepenuhnya dari vendor tanpa mengakses jaringan.

Latihan 3 — Update vendor secara selektif: Tambahkan dependensi baru ke project yang sudah punya vendor, jalankan go mod vendor ulang, lalu periksa perubahan di folder vendor/modules.txt. Apa yang berubah dibandingkan sebelumnya?


Vendor menjawab pertanyaan yang sering muncul di lingkungan produksi: bagaimana menjamin bahwa build hari ini menghasilkan binary yang sama dengan build seminggu lalu, meskipun ada perubahan di registry atau jaringan sedang bermasalah. Jawaban itu kini sudah ada di folder vendor/ yang ter-commit bersama kode.

Perjalanan KontenKu dari program “Hello, World!” pertama di Bab 4 sampai sistem yang bisa melayani request HTTP, menyimpan data ke database, menjalankan operasi concurrent, menulis test otomatis, dan mengelola dependensinya sendiri — semuanya dibangun di atas prinsip yang sama: Go dirancang agar mudah di-reason, mudah di-test, dan mudah di-deploy. Fondasi yang sudah kamu bangun di ebook ini adalah titik awal yang solid untuk membangun sistem Go yang sesungguhnya.

Referensi

  1. 1go mod vendor — Go Modules Reference, go.dev
  2. 2Using Go Modules — The Go Blog, go.dev
  3. 3Vendor Directories — cmd/go, pkg.go.dev