Hướng dẫn dùng GitHub Container Registry (GHCR): Lưu trữ Docker Image ‘ngon, bổ, rẻ’

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Docker Hub hay GHCR: Đâu là lựa chọn tối ưu?

Nếu bạn từng “dính” lỗi Too Many Requests khi pull image từ Docker Hub, bạn sẽ hiểu nó ức chế thế nào. Tài khoản miễn phí của Docker Hub giới hạn chỉ 200 lượt pull mỗi 6 tiếng. Con số này rất dễ chạm trần nếu hệ thống CI/CD của bạn chạy liên tục. Chưa kể, bạn chỉ có duy nhất một private repository miễn phí.

Đó là lý do mình chuyển hẳn sang GitHub Container Registry (GHCR). Với gói cá nhân, bạn có ngay 500MB lưu trữ và 1GB băng thông hàng tháng hoàn toàn miễn phí. Mọi thứ từ source code đến image đều nằm chung một nhà GitHub. Việc quản lý nhờ đó cũng nhàn hơn hẳn.

Quick Start: Đẩy Docker Image lên GHCR trong 5 phút

Bạn không cần cài đặt công cụ nào mới. Chỉ cần terminal của bạn đã có sẵn Docker.

Bước 1: Khởi tạo Personal Access Token (PAT)

GitHub dùng token thay cho mật khẩu thông thường để bảo mật. Bạn truy cập Settings > Developer settings > Personal access tokens > Tokens (classic) và tích chọn:

  • write:packages: Để upload image.
  • read:packages: Để tải image về server.
  • delete:packages: Dùng khi cần dọn dẹp image cũ.

Bước 2: Đăng nhập CLI

Lưu token vào biến môi trường và login bằng lệnh sau:

export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin

Bước 3: Tag và Push Image

Giả sử image local của bạn là my-app. Hãy gắn tag theo chuẩn GHCR rồi đẩy lên:

# Gắn tag định dạng: ghcr.io/username/image-name:version
docker tag my-app ghcr.io/username/my-app:v1.0

# Đẩy lên registry
docker push ghcr.io/username/my-app:v1.0

Kiểm tra mục Packages trên profile GitHub, bạn sẽ thấy image đã nằm đó an toàn.

Cơ chế hoạt động của GHCR có gì đặc biệt?

Khác với Docker Hub, GHCR gắn chặt với Organization hoặc User. Điều này cực kỳ tiện lợi khi phân quyền. Bạn có thể giữ image ở chế độ Private nhưng vẫn cho phép một repository cụ thể quyền truy cập. Bạn không cần cấu hình SSH key hay login thủ công rườm rà trên server nữa.

Tự động hóa với GitHub Actions

Đây mới là phần đáng giá nhất. Thay vì build thủ công, mình luôn dùng GitHub Actions để tự động hóa quy trình: cứ git push là image mới tự động lên kệ.

Dưới đây là file workflow mẫu (.github/workflows/publish.yml) mình thường dùng cho các dự án Node.js:

name: Build and Push Docker Image

on:
  push:
    branches: ["main"]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository }}:latest

Điểm hay ở đây là ${{ secrets.GITHUB_TOKEN }}. Đây là token tự sinh, chỉ tồn tại trong lúc chạy Action. Nó an toàn hơn nhiều so với việc dùng PAT cố định.

Mẹo phân quyền truy cập Repository

Làm sao để server hoặc một repo khác pull được image Private? Câu trả lời nằm ở tính năng Manage Actions access.

  1. Truy cập Packages trên GitHub cá nhân.
  2. Chọn image tương ứng > Package settings.
  3. Tìm mục Manage Actions access ở phía dưới.
  4. Chọn Add repository và tìm repo cần cấp quyền.
  5. Đặt quyền là Read để server có thể pull image thoải mái.

Cách này giúp bạn kiểm soát chặt chẽ ai được phép dùng image mà không cần chia sẻ tài khoản chính.

Kinh nghiệm thực tế để tối ưu chi phí

Sau một thời gian dài sử dụng GHCR cho các dự án tại itfromzero, mình có vài lưu ý nhỏ cho bạn:

  • Dọn dẹp định kỳ: GHCR miễn phí 500MB đầu tiên. Nếu image của bạn nặng (khoảng 200MB/image), chỉ cần 3 bản build là gần hết dung lượng. Hãy dùng các Action tự động xóa image cũ sau 30 ngày.
  • Dùng Multi-stage Build: Hãy tối ưu Dockerfile. Một image Node.js dùng Alpine chỉ khoảng 100MB, trong khi bản đầy đủ có thể lên tới 1GB. Image nhẹ giúp push/pull nhanh và tiết kiệm dung lượng đáng kể.
  • Bảo mật token: Tuyệt đối không dán cứng PAT vào file YAML. Luôn ưu tiên dùng GITHUB_TOKEN có sẵn.
  • Test Local trước: Đừng để CI/CD tốn tài nguyên chỉ để fix những lỗi cú pháp ngớ ngẩn. Hãy chạy thử image bằng Docker Compose ở máy cá nhân trước khi push.

Việc chuyển sang GHCR giúp quy trình deploy lên VPS của mình mượt hơn hẳn. Chỉ cần login một lần, mọi thứ sau đó đều chạy tự động qua script. Hy vọng bài viết này giúp bạn làm chủ GHCR dễ dàng hơn. Nếu gặp lỗi khi cấu hình YAML, hãy để lại bình luận phía dưới nhé!

Share: