Tại sao team bạn cần một Internal Developer Portal
Hãy tưởng tượng: một developer mới gia nhập team. Ngay ngày đầu tiên, họ cần tìm tài liệu API của payment service, xác định team nào sở hữu notification microservice, tìm CI/CD pipeline cho frontend, và nắm quy trình deploy. Không có một nơi tập trung cho tất cả những thứ này, họ sẽ mất cả ngày nhắn tin hỏi han trên Slack và lục lọc qua hàng chục wiki rải rác.
Đó chính xác là vấn đề mà Internal Developer Portal (IDP) sinh ra để giải quyết. Trong các team vận hành nhiều service, khả năng tìm kiếm thông tin kém sẽ âm thầm bào mòn năng suất — một developer mất 30 phút để tìm chủ sở hữu của một API, nhân với 20 người, sẽ tích lũy thành hàng giờ engineering bị lãng phí mỗi tuần.
Backstage là một framework mã nguồn mở do Spotify xây dựng và trao tặng cho CNCF. Nó cung cấp cho developer một nơi duy nhất để duyệt service catalog, đọc tài liệu, kích hoạt pipeline, kiểm tra trạng thái hạ tầng và onboard với service mới — mà không cần phải nhảy qua lại giữa sáu công cụ khác nhau.
Hướng dẫn này tập trung cụ thể vào việc chạy Backstage trên máy local, kết nối các catalog entry đầu tiên và thiết lập monitoring cơ bản để bạn biết portal hoạt động ổn định. Không lan man về tầm quan trọng của platform engineering — chỉ tập trung vào phần cài đặt.
Cài đặt: Khởi chạy Backstage trên máy local
Trước tiên, hãy đảm bảo bạn đã cài đặt các công cụ sau:
- Node.js 18+ (kiểm tra bằng
node -v) - Yarn 1.22+ (kiểm tra bằng
yarn -v) - Git
- Docker (tùy chọn, nhưng bạn sẽ cần cho PostgreSQL sau này)
Tạo Backstage App mới
Backstage đi kèm một công cụ scaffolding qua CLI. Chạy lệnh này trong terminal:
npx @backstage/create-app@latest
Bạn sẽ được hỏi tên app — đặt tên kiểu my-developer-portal là ổn. CLI sẽ tạo một monorepo với hai package: packages/app (frontend React) và packages/backend (backend Node.js). Quá trình này sẽ tải xuống khoảng 800MB dependencies.
cd my-developer-portal
yarn install
yarn dev
Chờ một hai phút, rồi mở http://localhost:3000. Bạn sẽ thấy màn hình home của Backstage với một sample catalog đã được load sẵn.
Hiểu cấu trúc project
Đây là những phần thực sự quan trọng trong project vừa được scaffold:
my-developer-portal/
├── app-config.yaml # File config chính
├── app-config.local.yaml # Config ghi đè cho local (đã gitignore)
├── packages/
│ ├── app/ # Frontend (React)
│ └── backend/ # Backend (Node.js + Express)
└── catalog-info.yaml # Catalog entry đầu tiên (mẫu)
Hầu hết cấu hình đều nằm trong app-config.yaml — kết nối database, tích hợp bên ngoài, auth provider và vị trí catalog. Bạn sẽ chỉnh sửa file này rất nhiều.
Cấu hình: Thiết lập Service Catalog
Service catalog là tính năng cốt lõi của Backstage. Mỗi microservice, thư viện, website hoặc API mà team bạn sở hữu đều trở thành một component trong catalog. Dưới đây là cách đăng ký một service thực tế.
Viết catalog-info.yaml cho service của bạn
Trong repository của service thực tế (không phải repo Backstage), tạo file catalog-info.yaml ở thư mục gốc:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: Xử lý toàn bộ thanh toán cho luồng checkout
annotations:
github.com/project-slug: my-org/payment-service
backstage.io/techdocs-ref: dir:.
tags:
- nodejs
- payments
- api
spec:
type: service
lifecycle: production
owner: payments-team
system: checkout
providesApis:
- payment-api
File này cung cấp cho Backstage mọi thứ cần thiết: ai sở hữu service, service đang ở giai đoạn nào (production, experimental hay deprecated), API nào được expose, và tài liệu nằm ở đâu.
Đăng ký Component trong Backstage
Mở portal tại http://localhost:3000, vào Catalog → Register Existing Component, và dán URL raw GitHub trỏ đến file catalog-info.yaml của bạn:
https://github.com/my-org/payment-service/blob/main/catalog-info.yaml
Backstage import component ngay lập tức. Nó sẽ xuất hiện trong catalog trong vài giây.
Kết nối GitHub Integration (để Auto-Discovery)
Đăng ký thủ công từng service sẽ không thể mở rộng khi vượt quá khoảng 10 repo. Backstage có thể tự động phát hiện các file catalog-info.yaml trong toàn bộ GitHub org của bạn. Chỉnh sửa app-config.yaml:
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
catalog:
providers:
github:
my-org:
organization: 'my-org'
catalogPath: '/catalog-info.yaml'
filters:
branch: 'main'
schedule:
frequency: { minutes: 30 }
timeout: { minutes: 3 }
Đặt biến môi trường trước khi khởi động:
export GITHUB_TOKEN=ghp_your_personal_access_token
yarn dev
Backstage sẽ crawl toàn bộ GitHub org của bạn mỗi 30 phút, tự động nhận diện bất kỳ repo nào có file catalog-info.yaml trên branch main. Token của bạn cần có scope repo và read:org — thiếu một trong hai, bạn sẽ gặp lỗi 403 trong quá trình discovery.
Bật TechDocs (Tài liệu ngay trong Portal)
TechDocs cho phép các team viết tài liệu bằng Markdown ngay trong codebase và đọc trực tiếp trong Backstage — không cần wiki ngoài. Đầu tiên, cài công cụ CLI:
pip install mkdocs-techdocs-core
Trong repo service của bạn, tạo file mkdocs.yml:
site_name: Payment Service
docs_dir: docs
nav:
- Trang chủ: index.md
- Tham chiếu API: api.md
- Runbooks: runbooks.md
Tạo file docs/index.md với nội dung của bạn. Mở service trong Backstage và bạn sẽ thấy tab Docs hiển thị các file Markdown đó dưới dạng một trang tài liệu hoàn chỉnh. Các team áp dụng mô hình này thường thấy số câu hỏi “tài liệu ở đâu?” trên Slack giảm rõ rệt chỉ sau vài tuần.
Chuyển từ SQLite sang PostgreSQL (Sẵn sàng cho production)
Mặc định, Backstage dùng SQLite in-memory. Database này sẽ reset mỗi lần khởi động lại — ổn cho việc test local nhưng không dùng được cho bất cứ thứ gì nghiêm túc hơn. Chuyển sang PostgreSQL:
docker run -d \
--name backstage-db \
-e POSTGRES_USER=backstage \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=backstage \
-p 5432:5432 \
postgres:15
Cập nhật app-config.yaml:
backend:
database:
client: pg
connection:
host: localhost
port: 5432
user: backstage
password: secret
database: backstage
Cài PostgreSQL client cho backend:
yarn --cwd packages/backend add pg
Kiểm tra & Monitoring: Giữ cho Portal luôn hoạt động tốt
Deploy Backstage xong rồi bỏ mặc là cách chắc chắn nhất để có một portal cũ kỹ mà không ai tin tưởng. Dưới đây là cách xác minh hệ thống đang hoạt động và phát hiện sự cố sớm.
Kiểm tra Catalog API trực tiếp
Backstage expose REST API để bạn có thể query và xác nhận quá trình ingestion catalog đang hoạt động:
# Liệt kê tất cả component đã đăng ký
curl http://localhost:7007/api/catalog/entities?filter=kind=Component | jq '.[].metadata.name'
# Kiểm tra một component cụ thể
curl http://localhost:7007/api/catalog/entities/by-name/component/default/payment-service | jq '.metadata'
Service của bạn xuất hiện ở đây nghĩa là catalog backend đã ingestion thành công. Nếu không thấy, hãy kiểm tra lại GitHub token có đúng scope không.
Theo dõi log Catalog Refresh
Khi GitHub auto-discovery chạy, Backstage ghi log từng chu kỳ refresh. Theo dõi log backend để phát hiện vấn đề:
yarn dev 2>&1 | grep -E '(catalog|error|warn)' | tail -f
Output bình thường trông như [catalog] Processed 42 entities. Lỗi 403 lặp đi lặp lại có nghĩa token đã hết hạn hoặc thiếu scope repo hay read:org. Sửa token, khởi động lại, và chu kỳ refresh 30 phút tiếp theo sẽ tự cập nhật.
Health Check Endpoint
Backend Backstage expose một health endpoint mà bạn có thể tích hợp vào bất kỳ công cụ uptime monitor nào:
curl http://localhost:7007/healthcheck
# Kết quả mong đợi: {"status":"ok"}
Deploy lên Kubernetes? Dùng endpoint này làm readiness probe:
readinessProbe:
httpGet:
path: /healthcheck
port: 7007
initialDelaySeconds: 10
periodSeconds: 15
Xác minh TechDocs Rendering
Sau khi đăng ký một component với TechDocs được bật, click vào tab Docs. Trang trắng hoặc thông báo “Documentation not found” nghĩa là có sự cố trong quá trình build. Debug ngay trên máy local:
cd your-service-repo
techdocs-cli generate --no-docker --verbose
techdocs-cli serve
Lệnh này build và preview tài liệu trên local. Hầu hết lỗi đều do thiếu file mkdocs.yml, đường dẫn docs_dir sai, hoặc file Markdown bị lỗi. Hãy sửa ở đây trước khi lỗi xuất hiện trên portal.
Theo dõi Catalog Coverage
Catalog coverage — tỷ lệ phần trăm service thực tế của bạn đã có file catalog-info.yaml — là chỉ số thực sự cho biết portal có hữu ích hay không. Kiểm tra bằng GitHub CLI:
# Đếm số repo trong org
gh repo list my-org --limit 200 --json name | jq length
# Đếm repo có file catalog-info.yaml
gh search code 'catalog-info.yaml' --owner my-org --json repository | jq '[.[].repository.name] | unique | length'
Mục tiêu là đạt coverage 80%+. Với các team đang thấp hơn ngưỡng đó, cách nhanh nhất để thu hẹp khoảng cách là đưa việc thêm catalog entry vào definition-of-done của sprint — mỗi service mới ra đời đều phải có catalog-info.yaml ngay từ ngày đầu tiên.
Bước tiếp theo sau những điều cơ bản
Khi catalog đã có dữ liệu và tài liệu đã hiển thị, một số tính năng có giá trị cao đáng để triển khai tiếp:
- Software Templates — Cho phép developer scaffold service mới trực tiếp trong portal, với các quy ước và chuẩn bảo mật của team được tích hợp sẵn từ đầu
- Tích hợp Auth — Kết nối GitHub SSO hoặc identity provider của công ty để developer đăng nhập bằng thông tin có sẵn thay vì phải quản lý thêm một tài khoản Backstage riêng
- Custom plugins — Backstage có hệ sinh thái plugin bao gồm Kubernetes, PagerDuty, Grafana và Argo CD, hiển thị dữ liệu liên quan trực tiếp trên trang catalog của từng service
- Scorecards — Định nghĩa tiêu chuẩn chất lượng (có tài liệu, có runbook, vượt qua security scan) và theo dõi service nào đáp ứng được các tiêu chí đó trong toàn org
Mười service được tài liệu hóa tốt trong catalog đã có thể giúp team bạn tiết kiệm đáng kể thời gian trả lời câu hỏi trên Slack và chuyển đổi ngữ cảnh. Portal càng có giá trị khi coverage càng tăng — nhưng nó cần phải hữu ích ngay từ ngày đầu tiên để được đón nhận, vì vậy hãy ưu tiên chất lượng hơn số lượng khi mới bắt đầu.

