เราเคยพูดถึงบริการ Managed Cloud Server อย่าง Cloudways ไปรอบหนึ่งแล้ว ซึ่งฟีเจอร์เด่นของมันอย่างหนึ่งคือรองรับการดีพลอยผ่าน Git โดยใช้ Git pull จาก repo ของเราโดยตรง
แต่ในความเป็นจริงการใช้ Git pull มาใส่เซิร์ฟเวอร์แบบดื้อๆ เลยนั้นอาจจะไม่สะดวกเท่าไหร่นัก โดยเฉพาะอย่างยิ่งโปรเจ็กท์ที่จำเป็นต้องมีการเซ็ตอัพต่างๆ เพิ่มเติมเสียก่อน (เช่นธีม Sage 9 ที่อย่างน้อยต้องไปสั่ง composer install
และ yarn
เพื่อคอมไพล์ assets ต่างๆ ก่อน)
ใน BitBucket จะมีฟีเจอร์ Pipelines ที่ช่วยให้เราสามารถสั่งทำงานต่างๆ ได้ทันทีหลังจากมีโค้ดใหม่ถูกส่งเข้า repo ซึ่งโดยปกติแล้ว Pipelines นี้จะถูกใช้ในการทำงานแบบ CI/CD (Continous Integration/Continous Delivery) เช่นใช้สำหรับการรันเทสโค้ดอัตโนมัติเมื่อโค้ดต่างๆ ถูก merge เข้ามาใน branch หลัก ไล่ไปจนถึงการบิวด์โค้ดแล้วดีพลอยขึ้นเซิร์ฟเวอร์ในทันทีหลังจากเทสผ่าน
เปิดใช้งาน BitBucket Pipelines
การเปิดใช้งาน BitBucket Pipelines นั้นสามารถทำได้ง่ายมาก เพียงแค่เขียนคำสั่ง Pipelines ลงในไฟล์ bitbucket-pipelines.yml
แล้วคอมมิตเข้าไปใน root directory ของ repo บน BitBucket ก็พร้อมใช้งาน โดย Pipelines จะรันอัตโนมัติทุกครั้งที่มีการ push โค้ดเข้ามาใน repo (เราสามารถเขียนคำสั่งให้รันเฉพาะ branch ได้)
ทีนี้มันจะมีเงื่อนไขอยู่เล็กน้อย นั่นคือใน BitBucket Cloud แบบฟรีนั้น จะสามารถใช้ Pipelines ได้ในทุก repo รวมกัน ไม่เกิน 50 นาทีต่อเดือน ซึ่งจากที่ลองใช้ส่วนตัวดูแล้ว พบว่าการรันครั้งหนึ่งจะใช้เวลาประมาณ 2-3 นาที ดังนั้นถ้าเราตั้งให้ Pipelines ทำงานเฉพาะกับ master เดือนนึงเราจะสามารถ release ได้ 15-20 ครั้ง (ในทุกโปรเจ็กท์รวมกัน) ได้สบายๆ
ในไฟล์ bitbucket-pipelines.yml
ให้ใส่คำสั่งลงไปตามนี้
# This is a sample build configuration for PHP. # Check our guides at https://confluence.atlassian.com/x/e8YWN for more examples. # Only use spaces to indent your .yml configuration. # ----- # You can specify a custom docker image from Docker Hub as your build environment. image: oneko/php-7.1-node-yarn pipelines: branches: master: - step: name: Build & Deploy caches: - node - composer deployment: production script: - echo "> Looking for theme directory" - X=`/bin/ls -d wp-content/themes/*/ | grep -v "\/twenty" | head -1` - if [ $X ]; then echo '- Found:' $X; cd $X; else echo 'No WordPress themes found'; fi - echo "> Building assets" - composer install - yarn - yarn run build:production - echo "- Asset built successful" - cd - - echo "> Deploying to" $DEPLOY_HOST - rsync -azP --exclude .git --exclude .gitignore --exclude bitbucket-pipelines.yml . [email protected]$DEPLOY_HOST:public_html
ข้อควรระวังของไฟล์ YAML คือเรื่องของการจัดย่อหน้า ที่ต้องย่อตามชั้นให้ถูกต้อง และต้องใช้ Spaces ในการย่อหน้าเท่านั้น ห้ามใช้ Tab
จากโค้ดด้านบนนั้นอธิบายได้ดังนี้
image:
เลือกอิมเมจ Docker ที่อยู่บน Docker Hub โดยเราจะใช้oneko/php-7.1-node-yarn
เพราะอิมเมจนี้มีมาให้เราครบตามที่ Sage 9 ต้องการ นั่นคือ PHP 7.1, Node.js, และ Yarnpipelines:
เริ่มคำสั่งของ BitBucket Pipelinesbranch:
ระบุคำสั่งตาม branchmaster:
คำสั่งสำหรับ branchmaster
- step:
สเต็ปการทำงาน (มีได้สูงสุด 10 step ซึ่งแต่ละ step จะทำงานตามscript:
)name:
ชื่อสเต็ปcaches:
โหลดแคชแพ็คเกจของโปรแกรมพวกนี้ไว้ เพื่อเวลารัน pipelines ครั้งต่อไปจะได้ไม่ต้องดาวน์โหลดแพ็คเพจใหม่ ในที่นี้เราให้แคชแพ็คเกจของnode
และcomposer
เอาไว้deployments:
ระบุว่าการดีพลอยในสเต็ปนี้ไปขึ้นเซิร์ฟเวอร์ใด ตั้งได้ 3 ค่าคือtest
,staging
, และproduction
ซึ่งผลการดีพลอยนี้จะไปโผล่อยู่ในเมนู Deployment ของ reposcript:
สคริปท์ (เป็น Linux shell script) สำหรับขั้นตอนการทำงานต่างๆ ในที่นี้ก็คือเราสั่งให้หาโฟลเดอร์ธีม สั่งคอมไพล์แอสเซ็ตทั้งหมด เสร็จแล้วดีพลอยขึ้นเซิร์ฟเวอร์ไปด้วยคำสั่งrsync
คำสั่ง
rsync
นั้นจะมีการเปรียบเทียบไฟล์ต้นทางกับปลายทางก่อน แล้วอัพเดทให้เฉพาะไฟล์ที่มีการเปลี่ยนแปลง ทำให้สามารถอัพโหลดได้เร็วกว่า ซึ่งต่างจากการใช้คำสั่งscp
หรือการอัพโหลดผ่าน FTP ปกติ ที่ไม่สามารถเทียบการเปลี่ยนแปลงของไฟล์ได้
ทั้งนี้หากธีมเราไม่จำเป็นต้องคอมไพล์แอสเซ็ตใดๆ ก่อน (เช่นไม่ได้ใช้ Sage 9) ในคำสั่ง script:
ให้ลบคำสั่งย่อยภายในออกให้เหลือแต่บรรทัดสุดท้าย (คำสั่ง rsync
) เพียงคำสั่งเดียวก็ใช้ได้เช่นกัน
หลังพุชไฟล์เข้า repo แล้ว ให้เปิด repo บนเว็บ BitBucket ขึ้นมา จากนั้นไปที่เมนู Settings > Environment Variables
แล้วให้ add เพิ่มเข้าไป 2 ค่า คือ
DEPLOY_HOST
หมายเลข IP Address ของเซิร์ฟเวอร์บน CloudwaysDEPLOY_USER
Application Credentials Username ของ Application ของเราบน Cloudways
ค่าทั้งสองอย่างสามารถดูได้จาก Application Dashboard บน Cloudways ซึ่งหากไม่มีอยู่ ให้กดเพิ่ม Username และ Password อันใหม่เข้าไปได้เลย
เตรียม SSH Key สำหรับดีพลอยขึ้น Cloudways
หลังจากเราคอมมิต bitbucket-pipelines.yaml
และตั้งค่า Environment Variables แล้ว ให้เราเปิดเข้าไปใน repo ที่ต้องการบน BitBucket เลือกเมนู Settings > SSH Keys
เราจะเจอกับหน้า SSH Keys แบบนี้ ให้เรากดที่ปุ่ม Generate keys
เพื่อสร้าง SSH Key ได้เลย
เสร็จแล้วเราจะได้คีย์ออกมาคู่หนึ่ง ให้เราคัดลอกคีย์ในส่วนของ Public Key เอาไว้
ทีนี้ด้านล่างของ SSH Keys จะมีส่วนของ Known Hosts อยู่ ส่วนนี้ให้เรากรอกหมายเลข IP Address ของเซิร์ฟเวอร์ Cloudways ลงในช่อง Host Address จากนั้นกดปุ่ม Fetch ด้านหลัง
การเพิ่ม Known Hosts จะช่วยให้เราสามารถรู้ได้ว่าเซิร์ฟเวอร์ที่เราเชื่อมต่อไปนั้นเป็นเซิร์ฟเวอร์ตัวที่เราต้องการเชื่อมต่อด้วยจริงๆ หรือไม่ ซึ่งสามารถช่วยป้องกันการโจมตีแบบ Man-in-the-Middle ได้ในระดับหนึ่ง
จากนั้นให้เรากลับไปที่ Application Dashboard บน Cloudways ในแถบ Application Credentials ถ้าเราเอาเมาส์ไปชี้ตรงรหัสผ่าน จะเห็นว่ามีคำว่า SSH Keys ต่ออยู่ข้างหลัง
ให้เรากดที่คำว่า SSH Keys จะมีหน้าต่าง Add/Update SSH Keys
เด้งขึ้นมา ให้เรากด Add แล้วเอา Public Key ที่ได้จากขั้นตอนก่อนหน้านี้มากรอกลงไปในช่อง Public Key ส่วนช่อง Label ตั้งชื่อว่าอะไรไปก็ได้ จากนั้นกด submit เป็นอันเสร็จ
เมื่อเพิ่ม SSH Key แล้ว ให้ไปที่เมนู Application Management > Application Settings
แล้วเลือกเปิดใช้งาน SSH Access
ถึงตรงนี้หาไม่มีอะไรผิดพลาด เมื่อมีการคอมมิตโค้ดเข้ามาใน branch master
คำสั่ง Pipelines ก็จะถูกรันอัตโนมัติ และดีพลอยโค้ดขึ้น Production ให้ทันที
หากใครอยากลองคอนฟิก Pipelines เพิ่มเติม (เช่นรันเทสต่างๆ, เพิ่มสเต็ป, เลือกอิมเมจ, ฯลฯ) สามารถไปอ่านคู่มือคำสั่งได้ในลิงก์นี้
การคอมมิตโค้ด
เนื่องจากว่าเราให้ Pipelines รันอัตโนมัติเมื่อมีโค้ดถูกส่งเข้า master
นั่นทำให้เราไม่สามารถพุชโค้ดเข้า master
รัวๆ ได้อีกต่อไป (เชื่อว่าหลายคนที่ dev อยู่คนเดียวจะทำแบบนี้) เพราะจะทำให้ Pipelines รันตลอดเวลาจนหมดโควต้าแต่ละเดือนไปเปล่าๆ
วิธีแก้คือให้เราแตก branch develop
ออกมา โค้ดต่างๆ ให้คอมมิตเข้า develop
เมื่อพร้อมที่จะดีพลอยแล้วก็ค่อย merge develop
เข้าสู่ master
เพื่อให้ Pipelines รันเพียงครั้งเดียว หรือพูดง่ายๆ ก็คือนำเอา Git Flow มาประยุกต์ใช้นั่นเอง
Leave a Reply