Đăng ký và quản lý Private Container Registry với Docker Hub hoặc GHCR
Hướng dẫn đăng ký và quản lý Private Container Registry với Docker Hub và GitHub Container Registry: token, push/pull, access control, GitHub Actions, multi-arch, bảo mật và cleanup.
ShanverseUpdated 9 min read— viewsLoading views
Docker
Deployment
Container Registry lưu trữ gì?
Các khái niệm dễ nhầm:
Registry: dịch vụ lưu Image, ví dụ Docker Hub hoặc ghcr.io.
Namespace/Owner: user hoặc organization sở hữu repository.
Repository: tập hợp các phiên bản của một Image, ví dụ acme/api.
Tag: tên có thể thay đổi trỏ tới một manifest, ví dụ 1.4.2, main, latest.
Comments
Digest: định danh bất biến theo nội dung, ví dụ sha256:....
Manifest list/Image index: tập hợp nhiều architecture như amd64 và arm64.
Mermaid
Loading diagram…
Một tên Image đầy đủ:
Ví dụ:
Docker Hub mặc định dùng docker.io, nên thường bỏ phần registry khi gõ lệnh.
Docker Hub hay GHCR?
Quota, retention, rate limit và tính năng organization thay đổi theo plan. Kiểm tra tài liệu và billing hiện tại trước khi chuẩn hóa cho production.
Đặt tên và chiến lược tag trước khi tạo Registry
Quy ước nên viết thường:
Chiến lược tag gợi ý:
Không deploy production chỉ bằng latest. Dùng version hoặc digest:
Tag tiện cho con người; digest đảm bảo đúng artifact đã được kiểm thử.
Phần 1: Private Repository trên Docker Hub
Tạo account và organization
Tạo Docker account và bật xác thực đa yếu tố.
Tạo organization nếu Image thuộc team/công ty.
Tạo repository, ví dụ acme/api.
Chọn visibility Private.
Gán team/user với quyền tối thiểu cần thiết.
Không dùng repository cá nhân cho workload công ty nếu cần ownership, audit và offboarding rõ ràng.
Tạo Access Token
Tạo token riêng cho từng mục đích:
Developer: read/write khi thực sự cần push.
CI publisher: chỉ quyền push repository liên quan.
Production server: read-only.
Không dùng password tài khoản trong script.
Đăng nhập an toàn
--password-stdin tránh token xuất hiện trong command history/process arguments. Trên máy cá nhân, cấu hình Docker credential helper thay vì lưu credential dạng dễ đọc trong ~/.docker/config.json.
Build, tag và push
Pull:
Logout trên runner hoặc máy tạm:
Phần 2: Private Package trên GitHub Container Registry
GHCR dùng hostname:
Tên Image:
Ví dụ:
Tạo token để dùng Docker CLI
Dùng loại GitHub token hiện được GHCR hỗ trợ trong account/organization. Các scope thường gặp:
read:packages: pull.
write:packages: push.
delete:packages: chỉ cấp cho automation cleanup thật sự cần xóa.
Nếu organization áp dụng SSO, token có thể cần được authorize cho organization. Tránh cấp scope repository rộng nếu không cần.
Login GHCR
Build và push lên GHCR
Repository/package name nên viết thường:
Package mới thường bắt đầu ở visibility private. Sau lần push đầu, vào package settings để:
Xác nhận owner đúng user/organization.
Giữ visibility private.
Kết nối package với source repository.
Cấu hình repository/team/user có quyền read/write/admin.
Kiểm tra permission inheritance có đúng mô hình organization hay không.
Gắn Image với GitHub repository bằng OCI label
Dockerfile:
Hoặc truyền label trong build:
Liên kết source giúp package dễ truy vết và có thể hỗ trợ mô hình permission inheritance. Vẫn phải kiểm tra package settings sau lần publish đầu tiên.
Push multi-architecture Image
Tạo builder:
Build và push amd64 + arm64:
Kiểm tra manifest:
Không dùng chuỗi docker pull → docker tag → docker push để migration multi-arch nếu chỉ pull một platform; có thể làm mất manifest list. Dùng tool hỗ trợ copy OCI artifact/manifest đầy đủ hoặc buildx phù hợp.
Tự động push GHCR bằng GitHub Actions
.github/workflows/container.yml:
GITHUB_TOKEN chỉ tồn tại trong workflow và nên được giới hạn bằng permissions. Package/repository settings vẫn phải cho workflow quyền publish. Ở môi trường yêu cầu supply-chain nghiêm ngặt, pin third-party actions theo full commit SHA thay vì chỉ major version.
Tự động push Docker Hub bằng GitHub Actions
Lưu trong GitHub Actions Secrets:
Workflow login/build:
Không dùng personal password. Tách token CI khỏi token developer để revoke/rotate độc lập.
Pull Private Image trong Docker Compose
Đăng nhập trên deployment host bằng token read-only:
compose.yml:
Deploy:
Compose dùng credential của Docker client/daemon context; không đặt registry token trực tiếp trong YAML hoặc .env được commit.
Để reproducible tuyệt đối:
Lưu tag, digest, Git SHA và deployment ID trong release metadata để rollback/audit.
Tag có thể thay đổi, digest thì không
Khi push lại cùng tag:
Server dùng cache hoặc pull ở thời điểm khác có thể chạy artifact khác nhau dù cùng tag. Production nên:
Build một lần.
Scan/test đúng digest.
Promote cùng digest qua staging → production.
Deploy bằng version bất biến hoặc digest.
Không rebuild source riêng cho từng environment.
Phân quyền theo least privilege
Ưu tiên organization/team thay vì cấp quyền từng user. Khi một thành viên rời team, revoke account/token và review deploy host còn credential cũ hay không.
Quản lý token an toàn
Dùng token riêng cho local, CI và production.
Bật 2FA/SSO theo policy.
Chỉ cấp read/write/delete đúng nhu cầu.
Lưu token trong OS credential store, CI secrets hoặc secret manager.
Không echo token, không bật shell debug khi xử lý secret.
Rotate định kỳ và ngay khi nghi ngờ lộ.
Xóa credential trên runner tạm sau job.
Audit lần dùng cuối, owner và ngày hết hạn.
Không backup ~/.docker/config.json vào nơi công khai.
Nếu token bị lộ, revoke/rotate trước; chỉ xóa khỏi Git không làm token cũ mất hiệu lực.
Image security và supply chain
Private Image vẫn có thể chứa vulnerability hoặc malware. Pipeline nên:
Thực hành:
Pin base Image bằng version/digest phù hợp.
Rebuild định kỳ để nhận security patches.
Scan dependency và OS package.
Tạo SBOM/provenance.
Ký Image bằng Sigstore Cosign hoặc cơ chế platform tương đương.
Chặn deploy khi vi phạm policy severity/age đã thống nhất.
Không copy .env, token hay private key vào Image.
Retention và cleanup
Một repository lâu ngày có thể có hàng nghìn tag CI. Policy ví dụ:
Giữ mọi release semver đang được hỗ trợ.
Giữ 30–90 ngày tag branch/PR.
Giữ N Image gần nhất của từng branch.
Không xóa digest đang chạy production hoặc dùng để rollback.
Có dry-run/report trước automation delete.
Tag và layer được chia sẻ. Xóa một tag không đảm bảo storage giảm ngay; registry quyết định garbage collection và accounting.
Trước cleanup, lập inventory:
Migration giữa Docker Hub và GHCR
Quy trình an toàn:
Freeze hoặc kiểm soát concurrent push.
Inventory repository, tag, digest, architecture và signature.
Copy đầy đủ OCI manifest/index và artifact liên quan.
So sánh source/destination digest.
Cập nhật CI để dual-push tạm thời nếu cần.
Cập nhật deployment reference và credential.
Theo dõi pull failure/rate limit.
Chỉ xóa registry cũ sau thời gian rollback.
Với multi-arch, dùng công cụ copy registry-to-registry hỗ trợ manifest list thay vì pull một platform rồi push lại.
Lỗi thường gặp
unauthorized: authentication required
Kiểm tra đúng registry hostname, username, token scope, SSO authorization và package/repository permission.
denied: permission_denied
Token đã login nhưng không có quyền push namespace hoặc package. Với GHCR organization, kiểm tra package access và workflow repository.
Image push nhầm namespace
Tên trước dấu / phải đúng owner/organization có quyền.
Production vẫn chạy Image cũ
Tag mutable và cache cục bộ. Dùng:
Tốt hơn: deploy version/digest mới rõ ràng.
exec format error
Image không có architecture của host. Build multi-arch hoặc chọn đúng platform.
Pull bị rate limit hoặc chậm
Kiểm tra authentication, plan, traffic pattern, cache và số node đồng thời. Không giả định private repository tự loại bỏ mọi quota.
Checklist production
Registry và organization thuộc quyền công ty/team.
Repository/package đang Private.
Team access theo least privilege.
CI dùng token riêng hoặc GITHUB_TOKEN giới hạn.
Production chỉ có read-only credential.
Login dùng --password-stdin và credential helper.
Image có semver, Git SHA và OCI source label.
Production deploy bằng version hoặc digest, không chỉ latest.
Multi-arch manifest đã được kiểm tra.
Image được test, scan, tạo SBOM và ký/attest theo policy.
Token có owner, expiry và rotation procedure.
Audit log và package permissions được review định kỳ.
Retention không xóa digest đang chạy/rollback.
Có runbook cho unauthorized, rollback và registry outage.
Tổng kết
Docker Hub phù hợp workflow Docker độc lập và hệ sinh thái phổ biến. GHCR đặc biệt thuận tiện khi source, permission và GitHub Actions cùng nằm trên GitHub. Dù chọn nền tảng nào, mô hình production nên là:
Hướng dẫn tự động deploy ứng dụng Docker lên VPS Ubuntu và cloud providers bằng GitHub Actions: AWS ECS/App Runner/EC2, Vercel, Render, secrets, healthcheck, rollback và zero-downtime strategy.
Hướng dẫn Docker Networks toàn diện: bridge, host, none, overlay, service discovery, port publishing, Compose network segmentation, internal networks, bảo mật và debug kết nối.