เอา Docker Image ขึ้น Docker Hub

สวัสดีครับ วันนี้เราจะมาสอนการเอา Docker Image ขึ้น Docker Hub จะเป็นอย่างไรนั้น มาเริ่มกันเลย
สำหรับใครที่ยังไม่รู้จักว่า Docker คืออะไร สามารถดูรายละเอียดตามด้านล่างนี้เลย
- เริ่มต้นใช้งาน Docker กัน Part 1
- เริ่มต้นใช้งาน Docker กัน Part 2
- Youtube เริ่มต้นใช้งาน Docker กัน
- รู้จักกับ Volume บน Docker กัน
- Youtube รู้จักกับ Volume บน Docker กัน
เอาล่ะ เรามาเริ่มกันเลย
ก่อนอื่นเลยเรามาทำความรู้จักกับ Docker Hub กันก่อนว่าคืออะไร
Docker Hub ก็คือ ผู้ให้บริการ Docker ที่เรียกได้ว่าเป็นศูนย์รวมของ Docker Image ต่าง ๆ ให้สำหรับสร้าง จัดการ และทำงานในทีมได้ง่าย ๆ สำหรับใครที่อยากรู้ว่ามีอะไรบ้าง สามารถเข้าไปดูได้ที่นี่
การเอา Docker Image ของเราขึ้นไปนั้น วัตถุประสงค์ก็คือเพื่อเอากลับไปใช้ใหม่หรืออาจจะไว้สำหรับแชร์ให้คนอื่นใช้งานก็ได้ จริง ๆ แล้วการเอา Docker Image เก็บไว้นั้นไม่จำเป็นจะต้องเก็บไว้ที่ Docker Hub อย่างเดียวเท่านั้น เราสามารถเก็บไว้ที่อื่นที่เค้าให้บริการก็ได้ แต่ผู้ให้บริการบางเจ้า อาจใช้คำเรียกไม่เหมือนกัน เช่น Container Registry, Registry, Repository ทั้งหมดนี้ก็คืออันเดียวกันนะ ถ้าใครเคยใช้ Git มาก่อนหรือ Version Control แล้ว จะคุ้นเคยกับคำสั่งที่ใช้ เช่น Push, Commit, Pull แต่ถ้าใครไม่เคยใช้ไม่เป็นไร ไม่ได้ยากอย่างที่คิด ส่วนจะเป็นยังไงนั้น เรามาดูกันเลย
โดยเราจะแบ่งเป็นทั้งหมด 2 วิธีด้วยกัน ก็คือ
- การเอา Docker Image ที่มีมาแล้ว มาใส่ในโปรเจคเรา
- การสร้าง Dockerfile แล้วเอา Image ที่เราสร้างขึ้นไปเก็บไว้
การเอา Docker Image ที่มีมาแล้ว มาใส่ในโปรเจคเรา
วิธีนี้จะเป็นการเอา Image ที่ทำไว้แล้วบน Docker Hub มาทำเป็นเวอร์ชั่นของเราเอง และเก็บไว้ที่เราเอง ซึ่งทำให้เราสามารถตั้งค่าหรือกำหนดค่าต่าง ๆ ได้ในแบบของเราเอง ส่วนจะเป็นอย่างไรนั้นเราไปดูกัน
ใครยังไม่สมัคร ก็สมัครให้เรียบร้อยก่อนนะ ถึงจะเริ่มใช้งานได้
ก่อนอื่นเราก็เข้าไปที่ Docker Hub คลิก Create repository เลย

เมื่อคลิกมาแล้ว เราจะเห็นคำสั่งทางด้านขวากับรายละเอียดด้านล่าง ด้านล่างจะเป็นในส่วนของการตั้งค่า Repository หรือ Docker Image เราให้สามารถ Public หรือ Private ได้ ซึ่งการตั้งเป็น Private นั้น เอาไว้สำหรับใช้งานส่วนตัว กับทำงานเป็นทีมเท่านั้น คนอื่นจะไม่เห็นในส่วนนี้ ซึ่งสามารถสร้างได้แค่ 1 Repository เท่านั้น ก็คือ 1 Image นั่นเอง

เริ่มต้นเราต้องทำการ Login Docker ใน Command Line ก่อนนะ โดยใช้คำสั่ง
docker login
เราก็ใส่ Username, Password ที่เราลงทะเบียนไว้ไป
จากนั้นเราจะมาดูรายละเอียดของคำสั่งกันเลย
docker tag local-image:tagname new-repo:tagname
docker tag เป็นการสร้าง Tag หรือ Version ให้กับ Image โดย Docker ที่เราใช้งานนั้นจะใช้ Image ต้นแบบที่ชื่อว่า nginx:latest และตามด้วยชื่อ image ใหม่และ tag ใหม่ โดยสิ่งที่เราจะเปลี่ยนก็มี
- local-image:tagname เปลี่ยนเป็น nginx:latest
- new-repo:tagname เป็น tichakon/nginx-volume:demo โดยที่ new-repo นั้นเราต้องใส่ username ของ Docker Hub ไว้ข้างหน้าด้วยนะ แล้วก็ตามด้วยชื่อ Image เรา แล้วคั่นด้วย : และตามด้วยชื่อ tag หรือ version ของเราตามลำดับ
เราจะได้คำสั่งแบบนี้
docker tag nginx:latest tichakon/nginx-volume:demo
สามารถไปดู Docker Desktop ที่ Tab Images ได้เลย (หน้าตาเปลี่ยนไปเพราะเป็น Version ใหม่นะ)

สามารถใช้ Command Line ดูได้โดยใช้คำสั่ง
docker images

เราจะเห็นว่ามี Image ที่เราแยกออกจาก nginx:latest มาแล้ว เอาล่ะไปต่อกันเลย
docker push new-repo:tagname
คำสั่ง docker push เป็นการเอา Docker ขึ้นไปเก็บไว้บนผู้ให้บริการ ในทีนี้เราจะเอา Docker ที่เราทำไว้เมื่อกี้ เอาขึ้นไป โดยใช้คำสั่ง
docker push tichakon/nginx-volume:demo
รอสักครู่จากนั้นไปดูบน Docker Hub เลย

จากนั้นเราลองคลิกเข้าไปดู

เสร็จแล้ว แต่เดี๋ยว อันนี้เป็นการ Push Docker ขึ้นไปโดยเอาต้นแบบจาก nginx:latest เราจะเอา Docker ที่เคยทำไว้บน Docker Compose จะเป็นอย่างไรนั้น ไปดูกัน
ก่อนอื่นเลยเราจะใช้ตัวอย่างที่แล้วตอนทำ Volume สามารถดูได้ที่นี่ หรือไปโหลดโปรเจคได้ที่นี่
เอาล่ะ ใครมีโปรเจคแล้วไปที่โฟลเดอร์ แล้วก็เริ่มรันกันเลย
docker compose -f docker-compose.yml up -d
เราเช็คการทำงานว่ายังใช้ได้ปกติมั้ย จากนั้นเราจะ commit ขึ้นไป แต่เราต้องรู้ Container ID ก่อน ใช้คำสั่ง
docker ps

ทำการ Copy Container เอาไว้ จากนั้นตามด้วยคำสั่ง
docker container commit 9ee92ce37644 tichakon/nginx-volume:demo
คำสั่ง docker container commit เป็นคำสั่งใช้ในการเซฟหรือบอกว่าเราขอแก้ไข ณ ตรงนี้นะ โดยเรานำ Container ที่ได้มาใส่ตรงนี้ และตามด้วยชื่อ Image ที่เราต้องการเอาขึ้นไปเก็บไว้ ในที่นี้ชื่อ tichakon/nginx-volume:demo
หลังจากนั้นตามด้วยคำสั่ง
docker push tichakon/nginx-volume:demo
docker push เป็นการนำสิ่งที่ Commit ไว้ขึ้นไปเก็บไว้บนผู้ให้บริการ
เสร็จแล้ว แต่เราก็งงว่า เอ๊ะ ไม่เห็นมีอะไรเปลี่ยนเพราะว่าเรา Push หรือเอาขึ้นที่ Tag เดิม ถ้าเราอยากเห็นการเปลี่ยนแปลงต้องเข้าไปดูใน Tag แต่เนื่องจากว่ามันเป็น Tag เดิมเลยเห็นการเปลี่ยนแปลงค่อนข้างยาก เราเลยมา push ที่ Tag อื่นบ้าง เราต้อง Commit ใหม่
docker container commit 9ee92ce37644 tichakon/nginx-volume:latest
จากนั้นทำการ push อีกรอบ
docker push tichakon/nginx-volume:latest
รอสักครู่ ไปดูที่ Docker Hub ของเราเลย ไปที่แท๊บชื่อ Tag เลย

จะเห็นว่ามี tag ที่ชื่อว่า latest มาแล้ว เอาล่ะ เราจะเอามาใช้กันบ้าง ว่าเป็นแบบไหน ก่อนอื่นก็ไปลบ image nginx-volume บนเครื่องเราก่อนนะ จากนั้นก็ Copy จากปุ่มด้านขวามาได้เลย
docker pull tichakon/nginx-volume:latest

เมื่อ pull มาแล้ว ก็มาเช็คกัน
docker run --name some-nginx -d -p 8080:80 tichakon/nginx-volume

เห็นอะไรมั้ยครับ มัน Error เพราะว่ามันติดว่ามันหาไฟล์ที่ Mount volume ไฟล์ที่เราโยนใส่เข้าไปใน Container ไม่เจอ แปลว่าที่เรา Commit หรือ Push ขึ้นไป ใช้ได้แล้วแหละ แต่เราจะแก้ Error หรือเอาโปรเจคขึ้นได้อย่างไรล่ะ คำตอบก็คือ เราต้องมีไฟล์ที่เราโยนเข้าไปใน Volume ให้เหมือนกันน่ะสิ เราจะไปดูแบบใช้ Docker Compose ละกันเผื่อจะได้เข้าใจง่าย
ไปที่โปรเจคเก่าเรากันเลย สร้างไฟล์ docker compose ขึ้นมาใหม่ โดยในทีนี้จะใช้ชื่อว่า docker-compose_new.yml

จากนั้นเพิ่ม Code ตามนี้เลย
version: "3.8"
services:
web:
container_name: some-nginx
image: tichakon/nginx-volume:latest
ports:
- '8080:80'
- '8081:81'
restart: always
volumes:
- './servers/test.conf:/etc/nginx/conf.d/test.conf'
- './web/test.html:/usr/share/nginx/html/test.html'
สิ่งที่เปลี่ยนไปจาก docker-compose.yml ก็คือ
- container_name เปลี่ยนจาก nginx-volume เป็น some-nginx
- image เปลี่ยนจาก nginx:latest เป็นของเราเองคือ tichakon/nginx-volume:latest ของใครเป็นแบบไหนก็ตามนั้นเลย
- volumes เราจะเอา volume ที่เก็บ log ออก แต่ที่เหลือเหมือนเดิมเลย
เราจะใช้ test.html กับ test.conf เหมือนเดิมเลยนะ เอาล่ะ เสร็จแล้วรันคำสั่งนี้เลย
docker compose -f docker-compose_new.yml up -d
เสร็จแล้ว ไม่ Error แล้ว ทีนี้ไปดูผลลัพธ์บนเว็บกัน ไปที่ localhost:8080

ไปที่ localhost:8081 กันต่อเลย

ไปดู Docker Desktop กัน

ไปดู Volume กัน

เอ๊ะ มี Volume งอกมา ใช่แล้ว นี่แหละคือที่เราเอาออกไว้ใน Docker Compose ก็คือมันฝังไว้กับ Docker Image ที่เราทำไว้ ทีนี้เข้าไปดู

เหมือนเป๊ะ แค่นี้ก็เสร็จแล้ว
เผื่อใครไม่อยากสร้าง Docker Compose เราสามารถใช้คำสั่งสั้น ๆ ได้เลยนะ แต่เราต้องมีไฟล์ test.html กับ test.conf ไว้แล้วนะ ก็ใช้คำสั่ง Mount Volume แบบ Docker ธรรมดาได้เลย ขอเขียนแบบสวย ๆ นะ ก็จะได้
docker run --name some-nginx \
-v /Users/tichakon/www/nginx-volume/servers/test.conf:/etc/nginx/conf.d/test.conf \
-v /Users/tichakon/www/nginx-volume/web/test.html:/usr/share/nginx/html/test.html \
-p 8080:80 \
-p 8081:81 \
-d \
tichakon/nginx-volume:latest
จะเห็นว่า พอใช้เป็น -v ตามด้วยชื่อ ทีนี้แหละยาวเลย เราต้องอ้างอิง Path แบบยาว ๆ แบบนี้แหละ แต่จริง ๆ แก้ได้นะ โดยเราจะใช้คำสั่งที่เคยสอนไป ก็คือ pwd
pwd
pwd เป็นการดูว่าตอนนี้ใน Command Line เราอยู่ที่ไหน

จะเห็นว่าตอนนี้ผู้เขียนอยู่ใน nginx-volume โปรเจคที่เรารัน Docker Compose เลย ถ้าเราใช้ Docker Compose ในส่วนของ Volume จะใช้ ./ ได้เลย แต่ถ้าใน Command Line หรือแบบ Docker ธรรมดาจะทำไม่ได้ ใครมีคำสั่งอะไรแนะนำก็บอกได้นะ แต่ผู้เขียนใช้ pwd ก็จะได้
docker run --name some-nginx \
-v $(pwd)/servers/test.conf:/etc/nginx/conf.d/test.conf \
-v $(pwd)/web/test.html:/usr/share/nginx/html/test.html \
-p 8080:80 \
-p 8081:81 \
-d \
tichakon/nginx-volume:latest
สำหรับใครที่ใช้ OS อื่น ๆ สามารถดูได้ที่นี่
เราไปดูวิธีต่อไปกันเลย
การสร้าง Dockerfile แล้วเอา Image ที่เราสร้างขึ้นไปเก็บไว้
ตามชื่อวิธีเลย เป็นการสร้าง Dockerfile ซึ่งเป็นการสร้าง Image ของเราขึ้นมา แล้วเอาไปเก็บไว้บนผู้ให้บริการ จะเป็นอย่างไรนั้นเราไปดูกัน
ก่อนอื่นเลยก็สร้าง Dockerfile ขึ้นมาในโปรเจคเลย

จากนั้นเอาโค้ดด้านล่างนี้ไปใส่
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install nginx -y
EXPOSE 80/tcp
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
จากนั้นใช้คำสั่งเดิมเลย
docker build -t nginx-ubuntu .
ไปดู Docker Desktop ในแท็บ Image กันเลย

ขึ้นมาแล้ว จากนั้นก็สร้าง tag ก่อนต่อเลย
docker tag nginx-ubuntu tichakon/nginx-ubuntu:latest
จากนั้นเอาขึ้นเลย
docker push tichakon/nginx-ubuntu:latest
รอสักครู่ จากนั้นไปดูบนเว็บได้เลย

เสร็จแล้วกับการสร้าง Dockerfile แล้ว Push ขึ้นไป ส่วนวิธีแก้ไขก็สามารถแก้ไขโดยการ Commit เหมือนกันเลย
เอาล่ะเสร็จไปแล้วสำหรับ 2 วิธี ทีนี้เราจะมาเล่าประสบการณ์เวลาทำจริงกัน
ปกติเวลาเราทำงานเราอาจจะไม่ได้ใช้ Container เดียว อาจจะใช้หลาย ๆ Container ตัวอย่างเช่น
version: "3.8"
services:
web:
container_name: some-nginx
image: nginx:latest
ports:
- '8085:80'
restart: always
phpmyadmin:
container_name: some-phpmyadmin
image: phpmyadmin
ports:
- 8086:80
environment:
- PMA_ARBITRARY=1
restart: always
จาก docker-compose.yml จะเห็นว่าเวลาเราเอาสิ่งนี้ขึ้นไปมันจะมี 2 Container แยกจากกัน

ซึ่งเวลาเราแก้ไข เราต้องแก้ทั้ง 2 Image คือ nginx กับ phpmyadmin แต่ถ้าเราอยากรวมทั้ง 2 services เข้าด้วยกัน เราจะใช้ Dockerfile แทน จะทำให้เราสามารถแก้ได้ในที่เดียว
ส่วนตัวคิดว่าการแยก 2 Container จะดีกว่า เพราะสมมติว่าเกิด Services บางตัวมีปัญหา เราไม่ต้องมานั่งแก้ทั้งโปรเจค แก้ทีละ Container ทีละ Image ไป แต่ถ้าทำ Dockerfile หรือ 1 Image ก็ต้องแก้ไฟล์เดียว บางทีมันไปกระทบกับส่วนอื่นด้วย ก็ให้ระวังไว้
สุดท้ายก็คือ Docker Hub ทำ Private ได้แค่ 1 Repository หรือ 1 โปรเจคเท่านั้น เพราะฉะนั้นถ้าใครต้องการ Private หลาย ๆ อันจะมีปัญหา แต่ที่เคยเจอไม่ค่อยมีใครเอาไฟล์ Config สำคัญ ๆ อย่างพวก .env หรือ Environment ไปใส่ใน Image อยู่แล้ว เพราะมันเสี่ยงต่อการถูกโจมตี จะใช้วิธี Mount Volume ไม่ก็พิมพ์คำสั่งเข้าไปแทนมากกว่า จึงทำให้บางที Public ไปก็ไม่มีปัญหา เพราะไฟล์สำคัญอยู่ที่เครื่องเรา แต่ถ้าต้องทำ Private จริง ๆ ล่ะก็ แนะนำให้ไปใช้เจ้าอื่นที่เก็บตัว Registry เช่น Gitlab หรือ DigitalOcean ก็ถือเป็นตัวเลือก แต่ดูให้ดีก่อนนะ
จบไปแล้วกับการเอา Docker Image ขึ้น Docker Hub เป็นยังไงกันบ้าง หวังว่าทุกคนจะเข้าใจกัน ถ้าเป็นเจ้าอื่นที่ไม่ใช่ Docker Hub คิดว่าหลักการเอาขึ้นน่าจะคล้าย ๆ กัน ถ้ามีโอกาสเดี๋ยวจะลองไปใช้เจ้าอื่นบ้างเพื่อเป็นทางเลือกและความรู้สำหรับผู้อ่าน สำหรับวันนี้ สวัสดีครับ
ช่องทางการติดต่อ
Email: [email protected]
Website: https://blog.tichaky.com/
Facebook: https://www.facebook.com/tichaky