อัปเดต 24 กันยายน 2026 · คู่มือนี้ใช้สำหรับการ push จากเครื่องของเราไปยัง GitHub Container Registry (ghcr.io)

GitHub Container Registry หรือ GHCR เป็นที่เก็บ Docker/OCI image ของ GitHub การใช้ Docker CLI บนเครื่องเพื่อเผยแพร่ image ต้องยืนยันตัวตนด้วย Personal Access Token (classic) ที่มีสิทธิ์ write:packages โดยชื่อบัญชีหรือองค์กรจะเป็นส่วน NAMESPACE ของชื่อ image เช่น ghcr.io/octocat/myapp:1.0 [1]

เลือก token ให้ถูกประเภท: ปัจจุบัน GitHub Packages ระบุให้ใช้ PAT แบบ classic สำหรับการยืนยันตัวตนกับ registry; fine-grained PAT ยังใช้เข้าถึง Packages ในกรณีนี้ไม่ได้ [1][2]

#1. สร้าง PAT (classic)

  1. ลงชื่อเข้าใช้ GitHub แล้วคลิกรูปโปรไฟล์มุมขวาบน → Settings.
  2. เลือก Developer settings → Personal access tokens → Tokens (classic).
  3. คลิก Generate new token → Generate new token (classic). หรือเปิดหน้าสร้างโดยตรง: https://github.com/settings/tokens/new?scopes=write:packages.
  4. ตั้งชื่อในช่อง Note เช่น docker-push-ghcr-laptop และกำหนด Expiration ให้เหมาะกับระยะเวลาที่จะใช้งาน.
  5. เลือก scope write:packages สำหรับ push image. หากต้อง pull อย่างเดียวใช้ read:packages; ไม่จำเป็นต้องเลือก delete:packages เพื่อ push.
  6. คลิก Generate token แล้วคัดลอกเก็บในที่ปลอดภัยทันที อย่าส่ง token ลงแชตหรือ commit ลง Git. [1][2]

ข้อสังเกตเรื่อง repo: หน้า GitHub อาจเลือก scope repo เพิ่มโดยอัตโนมัติเมื่อเลือก write:packages ซึ่งให้สิทธิ์กว้างเกินงานนี้ เอกสาร GitHub แนะนำ URL สร้าง PAT โดยเลือก write:packages เท่านั้น เพื่อลดสิทธิ์ที่ไม่จำเป็น ตรวจทาน scopes บนหน้าจอก่อนกดสร้าง token เสมอ [1]

Scope ใช้ทำอะไร จำเป็นต่อการ push?
read:packages ดาวน์โหลด image และอ่าน metadata write:packages ครอบคลุมการดาวน์โหลดอยู่แล้ว
write:packages อัปโหลด/ดาวน์โหลด image และอ่าน/เขียน metadata จำเป็น
delete:packages ลบ image ไม่จำเป็น

#2. Login เข้าสู่ GHCR

แทน USERNAME ด้วยชื่อบัญชี GitHub ของผู้สร้าง token แม้ปลายทาง image จะเป็น namespace ขององค์กร คำสั่งต่อไปนี้สำหรับ Bash จะรับ token โดยไม่แสดงอักขระบนหน้าจอ และส่งให้ Docker ผ่าน --password-stdin:

read -r -s -p 'GitHub PAT: ' CR_PAT
printf '\n'
printf '%s' "$CR_PAT" | docker login ghcr.io -u USERNAME --password-stdin
unset CR_PAT

หากสำเร็จ Docker จะแสดง Login Succeeded อย่าใส่ค่า token ตรง ๆ ในคำสั่งหรือ Dockerfile เพราะอาจหลุดใน shell history หรือไฟล์โครงการ GitHub แนะนำ --password-stdin สำหรับการ login [1]

#Login ด้วย Command Prompt (CMD) บน Windows

เปิด Command Prompt (เช่น กด Win + R แล้วพิมพ์ cmd) และตรวจว่า Docker Desktop เปิดอยู่ จากนั้นใช้คำสั่ง:

docker login ghcr.io -u USERNAME

เมื่อขึ้นข้อความ Password: ให้วาง PAT (classic) ที่สร้างไว้แล้วกด Enter โดยใช้ชื่อบัญชี GitHub ของเจ้าของ token แทน USERNAME หากสำเร็จจะเห็น Login Succeeded วิธีนี้ให้ Docker รับ token ผ่าน prompt จึงไม่ต้องใส่ token เป็นอาร์กิวเมนต์ -p ในคำสั่ง CMD [1][6]

จากนั้นเข้าโฟลเดอร์ที่มี Dockerfile แล้ว build/push ได้โดยตรงใน CMD (ตัวอย่างนี้ใช้ octocat เป็น namespace):

cd C:\projects\myapp
docker build -t ghcr.io/octocat/myapp:1.0 .
docker push ghcr.io/octocat/myapp:1.0

ปรับเส้นทางโครงการ ชื่อบัญชี/องค์กร ชื่อ image และ tag ให้ตรงกับงานจริง อย่าใช้ docker login ghcr.io -u USERNAME -p YOUR_TOKEN เพราะ token จะปรากฏในคำสั่งที่พิมพ์ [6]

#3. Build และ Push Docker Image

สมมติโฟลเดอร์ปัจจุบันมี Dockerfile และเราต้องการส่ง image myapp เวอร์ชัน 1.0 ไปยังบัญชี octocat:

docker build -t ghcr.io/octocat/myapp:1.0 .
docker push ghcr.io/octocat/myapp:1.0

หากสร้าง image ไว้แล้วในชื่อ myapp:1.0 สามารถตั้ง tag และ push ได้ดังนี้:

docker tag myapp:1.0 ghcr.io/octocat/myapp:1.0
docker push ghcr.io/octocat/myapp:1.0

รูปแบบชื่อเต็มคือ ghcr.io/NAMESPACE/IMAGE_NAME:TAG โดย NAMESPACE เป็นชื่อผู้ใช้หรือองค์กรเจ้าของ package ตรวจผลที่หน้าโปรไฟล์หรือหน้าองค์กรบน GitHub ในส่วน Packages เมื่อ push image ครั้งแรก GHCR ตั้งค่าการมองเห็นเป็น private ตามค่าเริ่มต้น; ปรับ visibility ที่หน้าการตั้งค่า package หากต้องการให้ผู้อื่นดึงแบบสาธารณะ [1]

หากต้องการเชื่อม image กับ repository: การ push ผ่าน CLI ไม่เชื่อม package เข้ากับ repository อัตโนมัติ แม้ชื่อ image จะเหมือน repo ก็ตาม สามารถเพิ่ม label org.opencontainers.image.source ใน Dockerfile เช่น:

LABEL org.opencontainers.image.source="https://github.com/octocat/myapp"

จากนั้น build/push อีกครั้ง หรือเชื่อม repository ในการตั้งค่า package [1][3]

#แก้ปัญหาที่พบบ่อย

อาการ สิ่งที่ควรตรวจ
unauthorized หรือ denied ตอน login ใช้ PAT แบบ classic, token ไม่หมดอายุ, username ตรงกับเจ้าของ token และมี write:packages
Login ได้แต่ push ไปองค์กรไม่ได้ บัญชีต้องมีสิทธิ์กับ package/องค์กร; ตรวจนโยบาย PAT ขององค์กรและการอนุญาต Configure SSO หากองค์กรใช้ SAML SSO [1][2][4]
Push package เดิมไม่ได้ ตรวจสิทธิ์เขียน package เดิมและการเชื่อม package กับ repository; write:packages ไม่เพิ่มสิทธิ์ของบัญชีเหนือสิทธิ์ที่มีอยู่ [1][2]
คนอื่น pull ไม่ได้ image อาจเป็น private; เปิดสิทธิ์ให้ผู้ใช้หรือปรับเป็น public ตามที่ต้องการ [1]

#ใช้กับ GitHub Actions อย่างไร?

หาก workflow ใน repository ต้อง push image ไป GHCR โดยทั่วไปใช้ GITHUB_TOKEN ของ workflow พร้อม permissions: packages: write แทนการสร้าง PAT ส่วนตัว และตรวจว่า package ให้ repository นั้นเข้าถึงได้ โดยเฉพาะ package ที่เคย push ผ่าน CLI มาก่อน [1][5]

#สรุปคำสั่ง

# สร้าง PAT (classic) ที่มี write:packages ผ่านหน้า GitHub ก่อน
read -r -s -p 'GitHub PAT: ' CR_PAT
printf '\n'
printf '%s' "$CR_PAT" | docker login ghcr.io -u USERNAME --password-stdin
unset CR_PAT

docker build -t ghcr.io/USERNAME/myapp:1.0 .
docker push ghcr.io/USERNAME/myapp:1.0

Windows CMD: ใช้ docker login ghcr.io -u USERNAME แล้วป้อน PAT ที่ prompt จากนั้นใช้ docker build และ docker push ตามตัวอย่างในหัวข้อ CMD ด้านบน [6]

#อ้างอิง

  1. GitHub Docs — Working with the Container registry
  2. GitHub Docs — Managing your personal access tokens
  3. GitHub Docs — Connecting a repository to a package
  4. GitHub Docs — Authorizing a personal access token for use with single sign-on
  5. GitHub Docs — Publishing Docker images
  6. Docker Docs — docker login