Membangun Container Registry Privat dengan Harbor: Penyimpanan Image dan Vulnerability Scanning
Mengapa Registry Privat Dibutuhkan untuk Distribusi Image
Docker Hub sering menjadi titik awal distribusi image. Namun layanan publik ini menerapkan batas pull rate yang ketat untuk permintaan anonim. Ketika pipeline CI/CD menarik banyak image dasar secara paralel, batas tersebut cepat tercapai dan build gagal tanpa pesan yang jelas. Repository privat di Docker Hub juga dibatasi pada satu repository gratis, sedangkan paket berbayar menambah biaya bulanan yang sulit diprediksi saat jumlah image terus bertambah.
Ada pula alasan keamanan dan tata kelola. Image internal yang memuat konfigurasi organisasi tidak seharusnya tersimpan di registry publik. Tim juga membutuhkan satu sumber distribusi agar environment dev, staging, dan production memakai artifact yang identik. Registry privat menutup kebutuhan itu melalui endpoint sendiri yang hanya dapat diakses dari jaringan internal.
Harbor hadir sebagai project open-source di bawah naungan CNCF dengan beberapa kemampuan sekaligus. Di dalamnya tersedia penyimpanan image, kontrol akses berbasis role, replication antar registry, dan vulnerability scanning. Dengan pendekatan ini, kita tidak perlu merangkai banyak tool terpisah untuk menjalankan registry yang aman.
Arsitektur Komponen Harbor dan Alur Request Image
Harbor berjalan sebagai kumpulan container yang saling terhubung. Komponen core menangani API, autentikasi token, dan orkestrasi request. Komponen registry adalah implementasi Distribution yang menyimpan blob dan manifest image. Komponen portal menyediakan antarmuka web untuk mengelola project serta user. Komponen jobservice mengeksekusi tugas latar seperti replication dan retensi image, sedangkan proxy menjadi pintu masuk seluruh trafik.

Gambar: Diagram arsitektur komponen Harbor dari layer consumer hingga data access — Sumber: Dokumentasi Harbor
Untuk menyimpan state, Harbor memakai PostgreSQL sebagai database utama dan Redis untuk cache serta antrian job. Keduanya menyimpan metadata project, user, dan status tugas, bukan konten image. Konten image sendiri tetap berada di volume penyimpanan melalui komponen registry.
Pemindaian kerentanan ditangani oleh Trivy yang dikemas sebagai komponen terpisah. Trivy menerima sinyal dari core dan jobservice setiap kali ada artifact baru. Laporan hasil pemindaian dikembalikan sebagai daftar CVE beserta tingkat severity-nya.
Alur request dimulai saat kita menjalankan docker login. Klien mengirim kredensial ke core, lalu menerima token akses. Pada docker push, klien mengunggah blob layer lebih dulu, kemudian mengirim manifest yang mereferensikan blob tersebut. Saat docker pull, urutannya terbalik: klien mengambil manifest, memverifikasi token, lalu mengunduh blob yang belum ada di cache lokal. core memvalidasi izin di setiap langkah, sehingga user tanpa role yang tepat tidak dapat menulis ke project tertentu.
Menyiapkan Konfigurasi harbor.yml dan Menjalankan Instalasi
Harbor menyediakan offline installer berbentuk arsip yang sudah memuat seluruh image. Kita mengunduhnya, mengekstraknya, lalu menyesuaikan satu file konfigurasi utama bernama harbor.yml. File ini menentukan identitas server, mode akses, kredensial admin, lokasi penyimpanan, dan komponen yang diaktifkan.
Beberapa field wajib harus diisi sebelum instalasi dijalankan. Field hostname menentukan alamat registry, blok http atau https menentukan protokol dan port, harbor_admin_password menetapkan password admin awal, dan data_volume menunjuk direktori penyimpanan persisten. Blok database memuat password PostgreSQL yang dipakai secara internal.
Jika server belum memiliki TLS, kita menghapus blok https dan memakai blok http. Untuk mengaktifkan pemindaian image, tambahkan blok trivy. Konfigurasi minimum berikut sudah cukup untuk menjalankan registry internal.
hostname: registry.rumahcoding.internal
http:
port: 80
harbor_admin_password: ChangeThisAdminPassword
data_volume: /data/harbor
database:
password: ChangeThisDbPassword
max_idle_conns: 100
trivy:
ignore_unfixed: false
skip_update: false
severity: critical,high,mediumSetelah konfigurasi siap, kita menjalankan installer. Skrip ini membuat seluruh container, menyiapkan jaringan internal, dan menjalankan migrasi database. Flag --with-trivy memastikan komponen scanner ikut aktif.
tar xzvf harbor-offline-installer-v2.11.0.tgz
cd harbor
sudo ./install.sh --with-trivyProses instalasi memerlukan Docker Engine dan Docker Compose pada host. Dua blok di atas bersifat ilustratif karena membutuhkan server dengan Docker yang sedang berjalan.
Memvalidasi Konfigurasi harbor.yml Secara Programatik dengan Python
Deep Learning Bootcamp
A beginner-friendly, highly interactive bootcamp designed to take you from found...
Kesalahan kecil pada harbor.yml sering baru terlihat setelah instalasi berjalan separuh. Kita bisa mencegahnya dengan membaca file tersebut lebih dulu lalu memeriksa field wajib memakai PyYAML. Pendekatan ini mengubah YAML menjadi dictionary Python, sehingga validasi menjadi eksplisit dan mudah diperluas.
Kode berikut memuat konfigurasi sebagai string, memeriksa keberadaan field wajib, dan mencetak ringkasan. Jika ada field yang hilang, program berhenti dengan pesan yang jelas sebelum menyentuh installer.
!pip install pyyaml
import yaml
REQUIRED_FIELDS = ["hostname", "data_volume", "database", "harbor_admin_password"]
config_text = """
hostname: registry.rumahcoding.internal
http:
port: 80
harbor_admin_password: ChangeThisAdminPassword
data_volume: /data/harbor
database:
password: ChangeThisDbPassword
max_idle_conns: 100
trivy:
ignore_unfixed: false
skip_update: false
severity: critical,high,medium
"""
config = yaml.safe_load(config_text)
missing = [field for field in REQUIRED_FIELDS if field not in config]
if missing:
raise SystemExit(f"Konfigurasi tidak lengkap: {', '.join(missing)}")
protocol = "https" if "https" in config else "http"
trivy_enabled = "trivy" in config
print("Validasi harbor.yml berhasil")
print(f"hostname : {config['hostname']}")
print(f"data_volume : {config['data_volume']}")
print(f"protocol : {protocol}")
print(f"trivy : {'aktif' if trivy_enabled else 'nonaktif'}")
print(f"severity : {config.get('trivy', {}).get('severity', '-')}")Output:
Validasi harbor.yml berhasil
hostname : registry.rumahcoding.internal
data_volume : /data/harbor
protocol : http
trivy : aktif
severity : critical,high,mediumRingkasan ini memastikan seluruh field wajib sudah terisi dan protokol yang dipilih sesuai dengan konfigurasi server. Setelah validasi lolos, kita dapat menjalankan installer dengan lebih tenang.
Mengelola Autentikasi Project dengan htpasswd dan bcrypt
Harbor mendukung mode autentikasi htpasswd_auth untuk kredensial project. Pada mode ini, setiap baris di file auth berisi user:hash dengan format yang sama seperti htpasswd. Password tidak boleh disimpan sebagai plaintext, sehingga kita perlu menghasilkan hash terlebih dahulu.
bcrypt adalah algoritma hashing yang sengaja dibuat lambat. Sifat ini membuat serangan brute-force jauh lebih mahal secara komputasi. Kode berikut menghasilkan hash dari sebuah password lalu menyusun baris htpasswd yang valid.
!pip install bcrypt
import bcrypt
username = "devops-engineer"
password = b"StrongProjectSecret2026"
password_hash = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12)).decode()
htpasswd_line = f"{username}:{password_hash}"
print("Baris htpasswd untuk project Harbor:")
print(htpasswd_line[:60] + "...")
print(f"Panjang hash bcrypt: {len(password_hash)} karakter")Output:
Baris htpasswd untuk project Harbor:
devops-engineer:$2b$12$NhtlVGZkYeulYxwWY7yNduDJcdrDX7ajNKdPS...
Panjang hash bcrypt: 60 karakterHash yang dihasilkan berbeda pada setiap eksekusi karena salt yang dipakai acak. Namun panjang dan format user:hash tetap konsisten, sehingga baris tersebut bisa langsung ditempel ke file auth.
Selain kredensial, Harbor mengatur hak akses melalui RBAC di tingkat project. Role project admin mengelola seluruh pengaturan project, maintainer mengelola image dan scanner, developer boleh push dan pull, sedangkan guest hanya bisa pull. Kita sebaiknya memisahkan project per tim agar batas akses tetap jelas. Dengan pemisahan ini, tim backend tidak dapat menulis image ke project frontend.
Vulnerability Scanning dengan Trivy serta Push dan Pull Image
Trivy memindai image tepat setelah artifact diunggah ke registry. Scanner ini membaca daftar package di dalam layer, membandingkannya dengan database kerentanan, lalu melaporkan setiap CVE beserta severity-nya. Hasil pemindaian tersimpan sebagai addition pada artifact dan dapat dibaca melalui Harbor API.

Gambar: Ringkasan laporan kerentanan Harbor dengan rincian severity dan jumlah CVE yang fixable — Sumber: Dokumentasi Harbor
Kode berikut bersifat ilustratif dan memerlukan server Harbor yang sedang berjalan. Contoh ini membaca laporan kerentanan dari endpoint additions memakai library requests.
import requests
harbor = "https://registry.rumahcoding.internal"
response = requests.get(
f"{harbor}/api/v2.0/projects/backend/repositories/api-service/artifacts/v2.4.1/additions/vulnerabilities",
auth=("admin", "ChangeThisAdminPassword"),
)
report = response.json()
for item in report.get("vulnerabilities", []):
print(item["severity"], item["id"], item["package"])Setelah laporan tersedia, kita dapat menetapkan kebijakan blocking. Image dengan CVE Critical sebaiknya tidak dipakai di production. Harbor dapat dikonfigurasi untuk mencegah pull artifact yang melanggar kebijakan tersebut.
Untuk mempublikasikan image, kita login, menambahkan tag, lalu push. Tiga perintah berikut adalah alur dasarnya dan membutuhkan Docker serta koneksi ke registry.
docker login registry.rumahcoding.internal
docker tag api-service:v2.4.1 registry.rumahcoding.internal/backend/api-service:v2.4.1
docker push registry.rumahcoding.internal/backend/api-service:v2.4.1Format image reference mengikuti pola registry/project/repo:tag. Memvalidasi pola ini penting agar push tidak diarahkan ke project yang salah. Kita bisa mem-parsing reference memakai regex.
import re
IMAGE_PATTERN = re.compile(
r"^(?P<registry>[^/]+)/(?P<project>[^/]+)/(?P<repository>[^:]+):(?P<tag>[\w.-]+)$"
)
references = [
"registry.rumahcoding.internal/backend/api-service:v2.4.1",
"registry.rumahcoding.internal/frontend/web-dashboard:2026.10.19",
]
for reference in references:
match = IMAGE_PATTERN.match(reference)
if match:
parts = match.groupdict()
print(f"registry : {parts['registry']}")
print(f"project : {parts['project']}")
print(f"repository : {parts['repository']}")
print(f"tag : {parts['tag']}")
print("-" * 44)Output:
registry : registry.rumahcoding.internal
project : backend
repository : api-service
tag : v2.4.1
--------------------------------------------
registry : registry.rumahcoding.internal
project : frontend
repository : web-dashboard
tag : 2026.10.19
--------------------------------------------Setiap komponen reference berhasil dipisahkan, sehingga kita dapat memakai nilai project dan repository untuk kebutuhan otomasi. Sebelum push, kita bisa memastikan project tujuan sudah benar dan token memiliki izin developer pada project tersebut.
Mulai Bangun Alur Distribusi Image yang Terkontrol
Harbor menggabungkan penyimpanan image, kontrol akses, dan vulnerability scanning dalam satu platform, sehingga tim dapat mendistribusikan artifact internal dengan aman. Jika kita ingin memperdalam Docker dan DevOps untuk deployment container, Rumah Coding menyediakan course yang membahas pipeline build, registry, dan praktik keamanan container secara terarah.
Kursus Terkait
Deep Learning Bootcamp
A beginner-friendly, highly interactive bootcamp designed to take you from foundational concepts to deploying real-world Artificial Intelligence applications. Through a completely project-based approach, you will master the core of Deep Learning, Artificial Neural Networks, and Computer Vision using Python and TensorFlow, ultimately building a professional-grade AI web application for your portfolio.
GreenGuard: Intelligent Plant Disease Diagnosis Web App
- Interactive Image Upload UI: A clean, user-friendly interface built with Streamlit that supports drag-and-drop image uploads directly from a computer or mobile phone.
- Real-Time AI Inference: Utilizes a lightweight, optimized CNN model (like MobileNetV2) to process the image and return a diagnosis in seconds without heavy server load.
- Confidence Scoring Dashboard: Visually displays the model's prediction probability (e.g., "95% confident this is Tomato Late Blight") using interactive progress bars or charts.
LLM Bootcamp
This project-based bootcamp is designed for beginners to dive practically into the world of Large Language Models (LLMs). Through hands-on building, you will learn how to interact with top-tier AI APIs, master prompt engineering, orchestrate complex workflows using LangChain, and implement Retrieval-Augmented Generation (RAG) to query your own documents. By the end of this course, you will have the skills to build, test, and deploy a fully functional, custom AI web application.
Domain-Specific AI Knowledge Assistant
- Dynamic Document Processing: A sidebar interface allowing users to upload new PDF or TXT files, which the app automatically chunks, embeds, and stores in the vector database.
- Context-Aware Chat UI: A modern chat interface built with Streamlit that maintains conversation history, allowing users to ask follow-up questions naturally.
- Strict Guardrails (Anti-Hallucination): System instructions designed so the AI politely declines to answer questions that fall outside the context of the uploaded documents.
Machine Learning Bootcamp
A beginner-friendly, 7-week project-based bootcamp designed to take you from Python basics to deploying your first Machine Learning model. Through hands-on practice, you will master essential data manipulation, build predictive algorithms, and develop an end-to-end, industry-ready application to kickstart your career in data science.
End-to-End Student Success Predictor
- Automated Data Pipeline: A preprocessing script that automatically cleans missing values, encodes categorical data (like course type or student background), and scales numerical inputs.
- Predictive Engine: A tuned machine learning classification model (e.g., Random Forest) specifically optimized for high Recall, ensuring that "at-risk" students are not missed.
- Interactive Web Dashboard: A user-friendly Streamlit interface featuring a sidebar where instructors can manually input a student's study hours, quiz scores, and login frequency to get an instant pass/fail probability.