ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ฉันเสนอให้อ่านสำเนาของรายงานโดย Alexander Sigachev จาก Inventos "กระบวนการพัฒนาและทดสอบด้วย Docker + Gitlab CI"

ผู้ที่เพิ่งเริ่มใช้กระบวนการพัฒนาและทดสอบบน Docker + Gitlab CI มักจะถามคำถามพื้นฐาน จะเริ่มต้นที่ไหน? วิธีการจัด? วิธีการทดสอบ?

รายงานนี้ดีเพราะพูดถึงโครงสร้างเกี่ยวกับกระบวนการพัฒนาและการทดสอบโดยใช้ Docker และ Gitlab CI ตัวรายงานมาจากปี 2017 ฉันคิดว่าจากรายงานนี้ คุณสามารถเรียนรู้พื้นฐาน วิธีการ แนวคิด ประสบการณ์การใช้งาน

ใครสนใจโปรดอยู่ใต้แมว

ฉันชื่ออเล็กซานเดอร์ ซีกาเชฟ ฉันทำงานให้กับ Inventos ฉันจะบอกคุณเกี่ยวกับประสบการณ์การใช้ Docker ของฉัน และวิธีที่เราค่อยๆ นำไปใช้ในโครงการต่างๆ ในบริษัท

หัวข้อนำเสนอ: ขั้นตอนการพัฒนาโดยใช้ Docker และ Gitlab CI

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นี่เป็นการพูดคุยครั้งที่สองของฉันเกี่ยวกับนักเทียบท่า ในช่วงเวลาของการรายงานครั้งแรก เราใช้ Docker ในการพัฒนาบนเครื่องของนักพัฒนาเท่านั้น จำนวนพนักงานที่ใช้ Docker ประมาณ 2-3 คน ค่อยๆ ได้รับประสบการณ์และเราก้าวต่อไปอีกเล็กน้อย เชื่อมโยงไปยังของเรา รายงานฉบับแรก.

ในรายงานนี้จะมีอะไรบ้าง? เราจะแบ่งปันประสบการณ์ของเราเกี่ยวกับคราดที่เราเก็บได้ ปัญหาที่เราแก้ไขได้ ไม่ใช่ทุกที่ที่สวยงาม แต่อนุญาตให้ไปต่อได้

คำขวัญของเราคือ: เชื่อมต่อทุกสิ่งที่เราสามารถทำได้

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เรากำลังแก้ปัญหาอะไรอยู่?

เมื่อมีหลายทีมในบริษัท โปรแกรมเมอร์คือทรัพยากรที่ใช้ร่วมกัน มีขั้นตอนที่โปรแกรมเมอร์ถูกดึงออกจากโครงการหนึ่งและมอบให้กับอีกโครงการหนึ่งเป็นระยะเวลาหนึ่ง

เพื่อให้โปรแกรมเมอร์เข้าใจได้อย่างรวดเร็ว เขาจำเป็นต้องดาวน์โหลดซอร์สโค้ดของโครงการและเปิดใช้งานสภาพแวดล้อมโดยเร็วที่สุด ซึ่งจะทำให้เขาสามารถแก้ไขปัญหาของโครงการนี้ต่อไปได้

โดยปกติแล้ว หากคุณเริ่มต้นจากศูนย์ แสดงว่ามีเอกสารเพียงเล็กน้อยในโครงการ ข้อมูลเกี่ยวกับวิธีการตั้งค่ามีให้สำหรับผู้จับเวลาเก่าเท่านั้น พนักงานจัดสถานที่ทำงานด้วยตนเองในหนึ่งหรือสองวัน เพื่อให้เร็วขึ้น เราใช้ Docker

เหตุผลประการต่อไปคือการกำหนดมาตรฐานของการตั้งค่าในการพัฒนา จากประสบการณ์ของฉัน นักพัฒนามักจะริเริ่มเสมอ ในทุก ๆ ห้ากรณี จะมีการป้อนโดเมนแบบกำหนดเอง เช่น vasya.dev ที่นั่งถัดจากเขาคือ Petya เพื่อนบ้านของเขาซึ่งมีโดเมน petya.dev พวกเขาพัฒนาเว็บไซต์หรือส่วนประกอบบางอย่างของระบบโดยใช้ชื่อโดเมนนี้

เมื่อระบบเติบโตขึ้นและชื่อโดเมนเหล่านี้เริ่มเข้าสู่การกำหนดค่า ความขัดแย้งในสภาพแวดล้อมการพัฒนาจะเกิดขึ้นและเส้นทางของไซต์จะถูกเขียนใหม่

สิ่งเดียวกันนี้เกิดขึ้นกับการตั้งค่าฐานข้อมูล บางคนไม่กังวลกับความปลอดภัยและทำงานด้วยรหัสผ่านรูทที่ว่างเปล่า ในขั้นตอนการติดตั้ง MySQL ขอรหัสผ่านจากใครบางคนและรหัสผ่านกลายเป็น 123 บ่อยครั้งที่การกำหนดค่าฐานข้อมูลเปลี่ยนแปลงตลอดเวลาขึ้นอยู่กับความมุ่งมั่นของผู้พัฒนา มีคนแก้ไข บางคนไม่ได้แก้ไขการกำหนดค่า มีกลเม็ดเมื่อเรานำการกำหนดค่าการทดสอบบางอย่างออกมา .gitignore และผู้พัฒนาแต่ละรายต้องติดตั้งฐานข้อมูล สิ่งนี้ทำให้การเริ่มต้นทำได้ยาก เหนือสิ่งอื่นใดจำเป็นต้องจดจำเกี่ยวกับฐานข้อมูล ต้องเริ่มต้นฐานข้อมูล ต้องป้อนรหัสผ่าน ต้องลงทะเบียนผู้ใช้ ต้องสร้างตาราง และอื่นๆ

ปัญหาอีกประการหนึ่งคือไลบรารีเวอร์ชันต่างๆ บ่อยครั้งที่นักพัฒนาทำงานกับโครงการต่างๆ มีโครงการ Legacy ที่เริ่มต้นเมื่อห้าปีที่แล้ว (ตั้งแต่ปี 2017 - ed. note) ในตอนเปิดตัว เราเริ่มต้นด้วย MySQL 5.5 นอกจากนี้ยังมีโครงการสมัยใหม่ที่เราพยายามใช้ MySQL เวอร์ชันที่ทันสมัยกว่า เช่น 5.7 หรือเก่ากว่า (ในปี 2017 - ed. note)

ใครก็ตามที่ทำงานกับ MySQL จะรู้ว่าไลบรารีเหล่านี้มีการพึ่งพาอาศัยกัน ค่อนข้างมีปัญหาในการรัน 2 ฐานพร้อมกัน อย่างน้อยไคลเอนต์เก่าก็มีปัญหาในการเชื่อมต่อกับฐานข้อมูลใหม่ สิ่งนี้จะสร้างปัญหาหลายประการ

ปัญหาต่อไปคือเมื่อนักพัฒนาทำงานบนเครื่องท้องถิ่น เขาใช้ทรัพยากรในเครื่อง ไฟล์ในเครื่อง แรมในเครื่อง การโต้ตอบทั้งหมดในขณะที่พัฒนาวิธีแก้ปัญหานั้นดำเนินการภายใต้กรอบการทำงานบนเครื่องเดียว ตัวอย่างคือเมื่อเรามีเซิร์ฟเวอร์แบ็กเอนด์ใน Production 3 และผู้พัฒนาบันทึกไฟล์ไปยังไดเร็กทอรีราก และจากที่นั่น nginx จะนำไฟล์ไปตอบสนองต่อคำขอ เมื่อรหัสดังกล่าวเข้าสู่การผลิต ปรากฎว่ามีไฟล์อยู่ในหนึ่งในเซิร์ฟเวอร์ 3 เครื่อง

ทิศทางของไมโครเซอร์วิสกำลังพัฒนาอยู่ในขณะนี้ เมื่อเราแบ่งแอปพลิเคชันขนาดใหญ่ออกเป็นส่วนประกอบเล็กๆ ที่โต้ตอบกัน สิ่งนี้ทำให้คุณสามารถเลือกเทคโนโลยีสำหรับงานเฉพาะกลุ่มได้ นอกจากนี้ยังช่วยให้คุณสามารถแบ่งปันงานและความรับผิดชอบระหว่างนักพัฒนา

นักพัฒนา Frondend ที่พัฒนาบน JS แทบจะไม่มีอิทธิพลต่อ Backend เลย ในทางกลับกันผู้พัฒนาแบ็กเอนด์ก็พัฒนา Ruby on Rails ในกรณีของเราและไม่รบกวนการทำงานของ Frondend การโต้ตอบดำเนินการโดยใช้ API

ในฐานะโบนัส ด้วยความช่วยเหลือจาก Docker เราสามารถรีไซเคิลทรัพยากรบน Staging ได้ แต่ละโครงการจำเป็นต้องมีการตั้งค่าบางอย่างเนื่องจากความเฉพาะเจาะจง ในทางกายภาพ จำเป็นต้องจัดสรรเซิร์ฟเวอร์เสมือนและกำหนดค่าแยกจากกัน หรือแบ่งปันสภาพแวดล้อมและโปรเจ็กต์ที่ผันแปรบางประเภทได้ ทั้งนี้ขึ้นอยู่กับเวอร์ชันของไลบรารี ซึ่งมีอิทธิพลต่อกันและกัน

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เครื่องมือ เราใช้อะไร?

  • นักเทียบท่านั่นเอง Dockerfile อธิบายการขึ้นต่อกันของแอ็พพลิเคชันเดียว
  • Docker-compose เป็นบันเดิลที่รวบรวมแอปพลิเคชั่น Docker บางส่วนของเรา
  • เราใช้ GitLab เพื่อจัดเก็บซอร์สโค้ด
  • เราใช้ GitLab-CI สำหรับการรวมระบบ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

รายงานประกอบด้วยสองส่วน

ส่วนแรกจะพูดถึงวิธีที่ Docker ทำงานบนเครื่องของนักพัฒนา

ส่วนที่สองจะพูดถึงวิธีการโต้ตอบกับ GitLab วิธีที่เราเรียกใช้การทดสอบ และวิธีที่เราเผยแพร่สู่ Staging

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นักเทียบท่าเป็นเทคโนโลยีที่ช่วยให้ (ใช้วิธีการประกาศ) เพื่ออธิบายองค์ประกอบที่จำเป็น นี่คือตัวอย่าง Dockerfile ที่นี่เราประกาศว่าเรากำลังสืบทอดอิมเมจ Ruby:2.3.0 Docker อย่างเป็นทางการ มีการติดตั้ง Ruby เวอร์ชัน 2.3 เราติดตั้ง build libraries และ NodeJS ที่จำเป็น เราอธิบายว่าเราสร้างไดเร็กทอรี /app. ตั้งค่าไดเร็กทอรีแอปเป็นไดเร็กทอรีการทำงาน ในไดเร็กทอรีนี้ เราวาง Gemfile และ Gemfile.lock ขั้นต่ำที่จำเป็น จากนั้นเราจะสร้างโครงการที่ติดตั้งอิมเมจการพึ่งพานี้ เราระบุว่าคอนเทนเนอร์พร้อมที่จะฟังบนพอร์ตภายนอก 3000 คำสั่งสุดท้ายคือคำสั่งที่เรียกใช้แอปพลิเคชันของเราโดยตรง หากเราดำเนินการคำสั่งเริ่มต้นโครงการ แอปพลิเคชันจะพยายามเรียกใช้และเรียกใช้คำสั่งที่ระบุ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นี่เป็นตัวอย่างขั้นต่ำของไฟล์ docker-compose ในกรณีนี้ เราแสดงว่ามีการเชื่อมต่อระหว่างสองคอนเทนเนอร์ ซึ่งอยู่ในบริการฐานข้อมูลและบริการเว็บโดยตรง เว็บแอปพลิเคชันของเราส่วนใหญ่ต้องการฐานข้อมูลบางประเภทเป็นแบ็คเอนด์สำหรับการจัดเก็บข้อมูล เนื่องจากเราใช้ MySQL ตัวอย่างคือกับ MySQL - แต่ไม่มีสิ่งใดป้องกันไม่ให้เราใช้ฐานข้อมูลอื่น (PostgreSQL, Redis)

เรานำอิมเมจของ MySQL 5.7.14 จากแหล่งอย่างเป็นทางการจากฮับ Docker โดยไม่มีการเปลี่ยนแปลง เรารวบรวมรูปภาพที่รับผิดชอบเว็บแอปพลิเคชันของเราจากไดเร็กทอรีปัจจุบัน มันเก็บภาพมาให้เราตอนเปิดตัวครั้งแรก จากนั้นรันคำสั่งที่เราดำเนินการที่นี่ หากย้อนกลับไปจะเห็นว่ามีการกำหนดคำสั่งเรียกใช้งานผ่าน Puma ไว้แล้ว Puma เป็นบริการที่เขียนด้วย Ruby ในกรณีที่สอง เราลบล้าง คำสั่งนี้สามารถทำได้โดยพลการขึ้นอยู่กับความต้องการหรืองานของเรา

นอกจากนี้ เรายังอธิบายว่าเราจำเป็นต้องส่งต่อพอร์ตบนเครื่องโฮสต์ของนักพัฒนาจาก 3000 เป็น 3000 บนพอร์ตคอนเทนเนอร์ สิ่งนี้ทำโดยอัตโนมัติโดยใช้ iptables และกลไกของมัน ซึ่งฝังอยู่ใน Docker โดยตรง

นักพัฒนายังสามารถเข้าถึงที่อยู่ IP ที่มีอยู่เช่น 127.0.0.1 เป็นที่อยู่ IP ภายในหรือภายนอกของเครื่อง

บรรทัดสุดท้ายบอกว่าคอนเทนเนอร์เว็บขึ้นอยู่กับคอนเทนเนอร์ฐานข้อมูล เมื่อเราเรียกการเริ่มคอนเทนเนอร์เว็บ docker-compose จะเริ่มฐานข้อมูลให้เราก่อน เมื่อเริ่มต้นฐานข้อมูลแล้ว (อันที่จริงหลังจากเปิดตัวคอนเทนเนอร์! สิ่งนี้ไม่ได้รับประกันความพร้อมของฐานข้อมูล) จะเปิดตัวแอปพลิเคชันซึ่งเป็นแบ็กเอนด์ของเรา

วิธีนี้จะหลีกเลี่ยงข้อผิดพลาดเมื่อไม่ได้เรียกใช้ฐานข้อมูลและประหยัดทรัพยากรเมื่อเราหยุดคอนเทนเนอร์ฐานข้อมูล ซึ่งจะทำให้ทรัพยากรว่างสำหรับโครงการอื่นๆ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

อะไรทำให้เราใช้การเทียบท่าฐานข้อมูลในโครงการ เราแก้ไขเวอร์ชันของ MySQL สำหรับนักพัฒนาทั้งหมด วิธีนี้จะหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้นเมื่อเวอร์ชันต่างกัน เมื่อไวยากรณ์ การกำหนดค่า การตั้งค่าเริ่มต้นเปลี่ยนแปลง สิ่งนี้ทำให้คุณสามารถระบุชื่อโฮสต์ทั่วไปสำหรับฐานข้อมูล การเข้าสู่ระบบ รหัสผ่าน เรากำลังย้ายออกจากสวนสัตว์ชื่อและข้อขัดแย้งในไฟล์กำหนดค่าที่เรามีก่อนหน้านี้

เรามีโอกาสใช้การกำหนดค่าที่เหมาะสมที่สุดสำหรับสภาพแวดล้อมการพัฒนา ซึ่งจะแตกต่างจากค่าเริ่มต้น MySQL ได้รับการกำหนดค่าสำหรับเครื่องที่อ่อนแอโดยค่าเริ่มต้นและประสิทธิภาพการทำงานนอกกรอบนั้นแย่มาก

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นักเทียบท่าอนุญาตให้คุณใช้ตัวแปล Python, Ruby, NodeJS, PHP ของเวอร์ชันที่ต้องการ เราไม่จำเป็นต้องใช้ตัวจัดการเวอร์ชันบางประเภท ก่อนหน้านี้ Ruby ใช้แพ็คเกจ rpm ที่อนุญาตให้คุณเปลี่ยนเวอร์ชันขึ้นอยู่กับโครงการ นอกจากนี้ยังช่วยให้สามารถโยกย้ายรหัสและกำหนดเวอร์ชันพร้อมกับการอ้างอิงได้อย่างราบรื่นด้วยคอนเทนเนอร์ Docker เราไม่มีปัญหาในการทำความเข้าใจเวอร์ชันของทั้งล่ามและรหัส หากต้องการอัปเดตเวอร์ชัน ให้ลดคอนเทนเนอร์เก่าลงและยกคอนเทนเนอร์ใหม่ขึ้น หากเกิดข้อผิดพลาด เราสามารถลดคอนเทนเนอร์ใหม่ลง ยกคอนเทนเนอร์เก่าขึ้น

หลังจากสร้างอิมเมจแล้ว คอนเทนเนอร์ในการพัฒนาและการผลิตจะเหมือนกัน โดยเฉพาะอย่างยิ่งสำหรับการติดตั้งขนาดใหญ่

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI ในส่วนหน้าเราใช้ JavaScipt และ NodeJS

ตอนนี้เรามีโครงการสุดท้ายบน ReacJS นักพัฒนาเรียกใช้ทุกอย่างในคอนเทนเนอร์และพัฒนาโดยใช้โหลดซ้ำ

ถัดไป งานแอสเซมบลี JavaScipt จะเปิดขึ้นและโค้ดที่คอมไพล์เป็นสแตติกจะได้รับผ่านทรัพยากรการบันทึก nginx

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ที่นี่ฉันได้ให้รูปแบบของโครงการสุดท้ายของเรา

งานอะไรถูกแก้ไข? เราจำเป็นต้องสร้างระบบที่อุปกรณ์เคลื่อนที่สามารถโต้ตอบได้ พวกเขาได้รับข้อมูล ความเป็นไปได้อย่างหนึ่งคือการส่งการแจ้งเตือนแบบพุชไปยังอุปกรณ์นี้

เราทำสิ่งนี้ไปเพื่ออะไร?

เราแบ่งส่วนประกอบของแอปพลิเคชันออกเป็น: ส่วนผู้ดูแลระบบบน JS, แบ็กเอนด์ซึ่งทำงานผ่านอินเทอร์เฟซ REST ภายใต้ Ruby on Rails แบ็กเอนด์โต้ตอบกับฐานข้อมูล ผลลัพธ์ที่สร้างขึ้นจะมอบให้กับลูกค้า แผงผู้ดูแลระบบโต้ตอบกับแบ็กเอนด์และฐานข้อมูลผ่านอินเทอร์เฟซ REST

เรายังจำเป็นต้องส่งการแจ้งเตือนแบบพุช ก่อนหน้านั้น เรามีโครงการที่ใช้กลไกที่รับผิดชอบในการส่งการแจ้งเตือนไปยังแพลตฟอร์มมือถือ

เราได้พัฒนาโครงร่างต่อไปนี้: ตัวดำเนินการจากเบราว์เซอร์โต้ตอบกับแผงผู้ดูแลระบบ แผงผู้ดูแลระบบโต้ตอบกับแบ็กเอนด์ งานคือการส่งการแจ้งเตือนแบบพุช

การแจ้งเตือนแบบพุชโต้ตอบกับส่วนประกอบอื่นที่ใช้ใน NodeJS

คิวถูกสร้างขึ้นแล้วส่งการแจ้งเตือนตามกลไกของคิว

มีการดึงฐานข้อมูลสองฐานข้อมูลที่นี่ ในขณะนี้ ด้วยความช่วยเหลือของนักเทียบท่า เราใช้ 2 ฐานข้อมูลอิสระที่ไม่เกี่ยวข้องกันในทางใดทางหนึ่ง นอกจากนี้ พวกเขายังมีเครือข่ายเสมือนทั่วไป และข้อมูลจริงจะถูกจัดเก็บไว้ในไดเร็กทอรีต่างๆ บนเครื่องของผู้พัฒนา

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เหมือนกันแต่เป็นตัวเลข นี่คือจุดที่การใช้รหัสซ้ำเป็นสิ่งสำคัญ

หากก่อนหน้านี้เราได้พูดถึงการนำโค้ดกลับมาใช้ใหม่ในรูปแบบของไลบรารี ในตัวอย่างนี้ บริการของเราที่ตอบสนองต่อการแจ้งเตือนแบบพุชจะถูกใช้ซ้ำเป็นเซิร์ฟเวอร์ที่สมบูรณ์ มันมี API และการพัฒนาใหม่ของเราโต้ตอบกับมันแล้ว

ในขณะนั้นเราใช้ NodeJS เวอร์ชัน 4 ตอนนี้ (ในปี 2017 - ed. note) ในการพัฒนาล่าสุด เราใช้ NodeJS เวอร์ชัน 7 ไม่มีปัญหาในคอมโพเนนต์ใหม่ที่เกี่ยวข้องกับไลบรารีเวอร์ชันใหม่

หากจำเป็น คุณสามารถปรับโครงสร้างและเพิ่มเวอร์ชัน NodeJS จากบริการแจ้งเตือนแบบพุช

และถ้าเราสามารถรักษาความเข้ากันได้ของ API ได้ ก็จะสามารถแทนที่ด้วยโปรเจ็กต์อื่นที่ใช้ก่อนหน้านี้ได้

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

คุณต้องการเพิ่ม Docker อะไร เราเพิ่ม Dockerfile ลงในที่เก็บของเรา ซึ่งอธิบายการพึ่งพาที่จำเป็น ในตัวอย่างนี้ ส่วนประกอบถูกแยกย่อยตามเหตุผล นี่คือชุดขั้นต่ำของนักพัฒนาแบ็กเอนด์

เมื่อสร้างโปรเจ็กต์ใหม่ เราจะสร้างไฟล์ Docker โดยอธิบายถึงระบบนิเวศที่ต้องการ (Python, Ruby, NodeJS) ใน docker-compose จะอธิบายการพึ่งพาที่จำเป็น - ฐานข้อมูล เราอธิบายว่าเราต้องการฐานข้อมูลของเวอร์ชันนั้น ๆ เก็บข้อมูลที่นั่นและที่นั่น

เราใช้คอนเทนเนอร์ที่สามแยกต่างหากกับ nginx เพื่อให้บริการแบบคงที่ สามารถอัพโหลดรูปภาพได้ แบ็กเอนด์วางไว้ในวอลุ่มที่เตรียมไว้ล่วงหน้าซึ่งติดตั้งในคอนเทนเนอร์ด้วย nginx ซึ่งให้ค่าคงที่

ในการจัดเก็บการกำหนดค่า nginx, mysql เราได้เพิ่มโฟลเดอร์ Docker ซึ่งเราจัดเก็บการกำหนดค่าที่จำเป็น เมื่อนักพัฒนาทำ git clone ของ repository บนเครื่องของเขา เขามีโครงการที่พร้อมสำหรับการพัฒนาในระดับท้องถิ่นแล้ว ไม่ต้องสงสัยเลยว่าพอร์ตใดหรือการตั้งค่าใดที่จะใช้

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ต่อไป เรามีองค์ประกอบหลายอย่าง: ผู้ดูแลระบบ, แจ้ง API, การแจ้งเตือนแบบพุช

เพื่อเริ่มต้นทั้งหมดนี้ เราได้สร้างพื้นที่เก็บข้อมูลอีกแห่ง ซึ่งเราเรียกว่า dockerized-app ในขณะนี้ เราใช้ที่เก็บหลายแห่งก่อนแต่ละส่วนประกอบ พวกมันแตกต่างกันอย่างมีเหตุผล - ใน GitLab ดูเหมือนโฟลเดอร์ แต่ในเครื่องของผู้พัฒนาเป็นโฟลเดอร์สำหรับโครงการเฉพาะ ลงหนึ่งระดับคือส่วนประกอบที่จะรวมกัน

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นี่เป็นเพียงตัวอย่างเนื้อหาของ dockerized-app เรายังนำไดเร็กทอรี Docker มาที่นี่ ซึ่งเรากรอกการกำหนดค่าที่จำเป็นสำหรับการโต้ตอบของคอมโพเนนต์ทั้งหมด มี README.md ที่อธิบายวิธีการรันโปรเจ็กต์โดยสังเขป

ที่นี่เราได้ใช้ไฟล์นักเทียบท่าสองไฟล์ ทำเพื่อให้สามารถทำงานเป็นขั้นตอนได้ เมื่อนักพัฒนาทำงานร่วมกับแกนหลัก เขาไม่ต้องการการแจ้งเตือนแบบพุช เขาเพียงเปิดไฟล์ที่เขียนโดยนักเทียบท่า และทรัพยากรจะถูกบันทึกไว้

หากจำเป็นต้องรวมเข้ากับการแจ้งเตือนแบบพุช ก็จะเปิดใช้ docker-compose.yaml และ docker-compose-push.yaml

เนื่องจาก docker-compose.yaml และ docker-compose-push.yaml อยู่ในโฟลเดอร์ เครือข่ายเสมือนเครือข่ายเดียวจึงถูกสร้างขึ้นโดยอัตโนมัติ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

คำอธิบายของส่วนประกอบ นี่เป็นไฟล์ขั้นสูงที่รับผิดชอบในการรวบรวมส่วนประกอบต่างๆ มีอะไรโดดเด่นที่นี่? ที่นี่เราแนะนำส่วนประกอบบาลานเซอร์

นี่คืออิมเมจ Docker สำเร็จรูปที่เรียกใช้ nginx และแอปพลิเคชันที่ฟังบนซ็อกเก็ต Docker ไดนามิก เมื่อเปิดและปิดคอนเทนเนอร์ มันจะสร้างการกำหนดค่า nginx ใหม่ เราแจกจ่ายการจัดการส่วนประกอบตามชื่อโดเมนระดับที่สาม

สำหรับสภาพแวดล้อมการพัฒนา เราใช้โดเมน .dev - api.informer.dev แอปพลิเคชันที่มีโดเมน .dev มีอยู่ในเครื่องของผู้พัฒนา

นอกจากนี้ การกำหนดค่าจะถูกถ่ายโอนไปยังแต่ละโครงการและโครงการทั้งหมดจะเปิดพร้อมกันในเวลาเดียวกัน

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ในทางกราฟิก ปรากฎว่าไคลเอนต์คือเบราว์เซอร์ของเราหรือเครื่องมือบางอย่างที่เราส่งคำขอไปยังบาลานเซอร์

ตัวจัดสรรชื่อโดเมนจะกำหนดคอนเทนเนอร์ที่จะติดต่อ

อาจเป็น nginx ซึ่งให้ JS แก่ผู้ดูแลระบบ ซึ่งอาจเป็น nginx ซึ่งให้ API หรือไฟล์แบบสแตติกซึ่งมอบให้กับ nginx ในรูปแบบของการอัปโหลดรูปภาพ

แผนภาพแสดงว่าคอนเทนเนอร์เชื่อมต่อกันด้วยเครือข่ายเสมือนและซ่อนอยู่หลังพร็อกซี

ในเครื่องของผู้พัฒนา คุณสามารถเข้าถึงคอนเทนเนอร์โดยรู้ IP แต่โดยหลักการแล้วเราไม่ใช้สิ่งนี้ ไม่จำเป็นต้องเข้าถึงโดยตรง

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ตัวอย่างใดที่ควรดูในการเทียบท่าแอปพลิเคชันของคุณ ในความคิดของฉัน ตัวอย่างที่ดีคืออิมเมจนักเทียบท่าอย่างเป็นทางการสำหรับ MySQL

มันค่อนข้างท้าทาย มีหลายเวอร์ชั่น แต่ฟังก์ชันการทำงานช่วยให้คุณครอบคลุมความต้องการมากมายที่อาจเกิดขึ้นในกระบวนการพัฒนาเพิ่มเติม หากคุณใช้เวลาและเข้าใจว่าทั้งหมดมีปฏิสัมพันธ์กันอย่างไร ฉันคิดว่าคุณจะไม่มีปัญหาในการดำเนินการด้วยตนเอง

โดยปกติแล้ว Hub.docker.com จะมีลิงก์ไปยัง github.com ซึ่งมีข้อมูลดิบโดยตรง ซึ่งคุณสามารถสร้างอิมเมจได้เอง

นอกจากนี้ในที่เก็บข้อมูลนี้ยังมีสคริปต์ docker-endpoint.sh ซึ่งมีหน้าที่รับผิดชอบในการเริ่มต้นครั้งแรกและสำหรับการประมวลผลเพิ่มเติมของการเปิดใช้แอปพลิเคชัน

นอกจากนี้ในตัวอย่างนี้ ยังมีความสามารถในการกำหนดค่าโดยใช้ตัวแปรสภาพแวดล้อม ด้วยการกำหนดตัวแปรสภาพแวดล้อมเมื่อรันคอนเทนเนอร์เดียวหรือผ่าน docker-compose เราสามารถพูดได้ว่าเราต้องตั้งรหัสผ่านว่างสำหรับนักเทียบท่าเพื่อรูทบน MySQL หรืออะไรก็ตามที่เราต้องการ

มีตัวเลือกในการสร้างรหัสผ่านแบบสุ่ม เราบอกว่าเราต้องการผู้ใช้ เราต้องตั้งรหัสผ่านสำหรับผู้ใช้ และเราต้องสร้างฐานข้อมูล

ในโครงการของเรา เราได้รวมไฟล์ Dockerfile เข้าด้วยกันเล็กน้อย ซึ่งมีหน้าที่รับผิดชอบในการเริ่มต้น เราได้แก้ไขตามความต้องการของเราเพื่อให้เป็นเพียงส่วนเสริมของสิทธิ์ผู้ใช้ที่แอปพลิเคชันใช้ สิ่งนี้ทำให้เราสามารถสร้างฐานข้อมูลจากคอนโซลแอปพลิเคชันในภายหลัง โปรแกรม Ruby มีคำสั่งสำหรับสร้าง แก้ไข และลบฐานข้อมูล

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นี่คือตัวอย่างลักษณะเฉพาะของ MySQL เวอร์ชันบน github.com คุณสามารถเปิด Dockerfile และดูว่ามีการติดตั้งอย่างไร

docker-endpoint.sh เป็นสคริปต์ที่รับผิดชอบจุดเข้าใช้งาน ในระหว่างการเริ่มต้นเบื้องต้น จำเป็นต้องมีขั้นตอนการเตรียมการบางอย่าง และการดำเนินการทั้งหมดเหล่านี้จะดำเนินการในสคริปต์การเริ่มต้นเท่านั้น

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ไปที่ส่วนที่สองกันเถอะ

ในการจัดเก็บซอร์สโค้ด เราเปลี่ยนไปใช้ gitlab นี่เป็นระบบที่มีประสิทธิภาพพอสมควรซึ่งมีอินเทอร์เฟซแบบภาพ

หนึ่งในส่วนประกอบของ Gitlab คือ Gitlab CI ช่วยให้คุณสามารถอธิบายลำดับของคำสั่งที่จะใช้ในภายหลังเพื่อจัดระเบียบระบบการนำส่งโค้ดหรือเรียกใช้การทดสอบอัตโนมัติ

Gitlab CI 2 พูดคุย https://goo.gl/uohKjI - รายงานจาก Ruby Russia club - ค่อนข้างละเอียดและบางทีคุณอาจจะสนใจ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ตอนนี้เราจะดูสิ่งที่จำเป็นในการเปิดใช้งาน Gitlab CI ในการเริ่ม Gitlab CI เราเพียงแค่ต้องใส่ไฟล์ .gitlab-ci.yml ในรูทของโปรเจ็กต์

ที่นี่เราอธิบายว่าเราต้องการดำเนินการตามลำดับของสถานะ เช่น การทดสอบ การปรับใช้

เรารันสคริปต์ที่เรียกนักเทียบท่าโดยตรงเพื่อสร้างแอปพลิเคชันของเรา นี่เป็นเพียงตัวอย่างแบ็กเอนด์

ต่อไป เราบอกว่าจำเป็นต้องเรียกใช้การย้ายข้อมูลเพื่อเปลี่ยนฐานข้อมูลและเรียกใช้การทดสอบ

หากเรียกใช้สคริปต์อย่างถูกต้องและไม่ส่งคืนรหัสข้อผิดพลาด ระบบจะดำเนินการต่อไปยังขั้นตอนที่สองของการปรับใช้

ขณะนี้มีการใช้ขั้นตอนการปรับใช้สำหรับการจัดเตรียม เราไม่ได้จัดให้มีการเริ่มระบบใหม่ในช่วงหยุดทำงานเป็นศูนย์

เราบังคับให้ดับคอนเทนเนอร์ทั้งหมด จากนั้นจึงยกคอนเทนเนอร์ทั้งหมดขึ้นอีกครั้ง โดยเก็บในขั้นตอนแรกระหว่างการทดสอบ

เรากำลังเรียกใช้ตัวแปรสภาพแวดล้อมปัจจุบันในการย้ายฐานข้อมูลที่เขียนโดยนักพัฒนา

โปรดทราบว่าสิ่งนี้ใช้ได้กับสาขาหลักเท่านั้น

เมื่อเปลี่ยนสาขาอื่นจะไม่ถูกดำเนินการ

เป็นไปได้ที่จะจัดระเบียบการเปิดตัวตามสาขา

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ในการจัดระเบียบเพิ่มเติม เราจำเป็นต้องติดตั้ง Gitlab Runner

ยูทิลิตี้นี้เขียนด้วย Golang เป็นไฟล์เดียวเหมือนทั่วไปในโลก Golang ซึ่งไม่ต้องการการขึ้นต่อกันใดๆ

เมื่อเริ่มต้น เราลงทะเบียน Gitlab Runner

เราได้รับรหัสในอินเทอร์เฟซเว็บ Gitlab

จากนั้นเราเรียกคำสั่งเริ่มต้นในบรรทัดคำสั่ง

ตั้งค่า Gitlab Runner แบบโต้ตอบ (Shell, Docker, VirtualBox, SSH)

โค้ดบน Gitlab Runner จะดำเนินการกับทุกคอมมิชชัน ขึ้นอยู่กับการตั้งค่า .gitlab-ci.yml

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ลักษณะที่มองเห็นใน Gitlab ในเว็บอินเตอร์เฟส หลังจากที่เราเชื่อมต่อ GItlab CI แล้ว เราก็มีแฟล็กที่แสดงสถานะของบิลด์ในขณะนี้

เราพบว่ามีการคอมมิตเมื่อ 4 นาทีที่แล้ว ซึ่งผ่านการทดสอบทั้งหมดและไม่ทำให้เกิดปัญหาใดๆ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เราสามารถดูงานสร้างได้ใกล้ขึ้น ที่นี่เราเห็นว่าสองรัฐได้ผ่านไปแล้ว สถานะการทดสอบและสถานะการปรับใช้บนเวที

หากเราคลิกที่บิลด์เฉพาะ จะมีเอาต์พุตคอนโซลของคำสั่งที่เรียกใช้ในกระบวนการตาม .gitlab-ci.yml

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

นี่คือลักษณะของประวัติผลิตภัณฑ์ของเรา เราเห็นว่ามีความพยายามที่ประสบความสำเร็จ เมื่อมีการส่งการทดสอบ การทดสอบจะไม่ดำเนินการต่อไปยังขั้นตอนถัดไป และไม่มีการอัพเดตรหัสการจัดเตรียม

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เราได้แก้ไขงานใดบ้างในการจัดเตรียมเมื่อเราติดตั้งนักเทียบท่า ระบบของเราประกอบด้วยคอมโพเนนต์และเราจำเป็นต้องรีสตาร์ท คอมโพเนนต์เพียงบางส่วนที่ได้รับการอัพเดตในที่เก็บ ไม่ใช่ทั้งระบบ

ในการทำเช่นนี้ เราต้องแตกทุกอย่างออกเป็นโฟลเดอร์แยกต่างหาก

หลังจากที่เราทำสิ่งนี้ เรามีปัญหากับข้อเท็จจริงที่ว่า Docker-compose สร้างพื้นที่เครือข่ายของตัวเองสำหรับ Daddy แต่ละคน และไม่เห็นส่วนประกอบของเพื่อนบ้าน

เพื่อไปไหนมาไหน เราสร้างเครือข่ายใน Docker ด้วยตนเอง มีการเขียนใน Docker-compose ว่าคุณใช้เครือข่ายดังกล่าวสำหรับโครงการนี้

ดังนั้น แต่ละส่วนประกอบที่ขึ้นต้นด้วยตาข่ายนี้จะมองเห็นส่วนประกอบในส่วนอื่นๆ ของระบบ

ประเด็นต่อไปคือการแบ่งการจัดเตรียมในหลายโครงการ

เนื่องจากเพื่อให้สิ่งเหล่านี้ดูสวยงามและใกล้เคียงกับการผลิตมากที่สุดจึงเป็นการดีที่จะใช้พอร์ต 80 หรือ 443 ซึ่งใช้ทุกที่ในเว็บ

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เราแก้ปัญหาได้อย่างไร? เราได้กำหนด Gitlab Runner หนึ่งรายการให้กับโครงการสำคัญทั้งหมด

Gitlab อนุญาตให้คุณเรียกใช้ Gitlab Runners แบบกระจายหลายตัว ซึ่งจะทำให้งานทั้งหมดสลับกันในลักษณะที่วุ่นวายและเรียกใช้งาน

เพื่อให้เราไม่มีบ้าน เราจึงจำกัดกลุ่มของโปรเจ็กต์ของเราไว้ที่ Gitlab Runner หนึ่งรายการ ซึ่งจัดการได้โดยไม่มีปัญหากับวอลุ่มของเรา

เราย้าย nginx-proxy ไปเป็นสคริปต์เริ่มต้นแยกต่างหากและเพิ่มกริดสำหรับโครงการทั้งหมดในนั้น

โปรเจ็กต์ของเรามีกริดเดียว และบาลานเซอร์มีหลายกริดตามชื่อโปรเจ็กต์ มันสามารถ proxy เพิ่มเติมโดยชื่อโดเมน

คำขอของเรามาจากโดเมนที่พอร์ต 80 และได้รับการแก้ไขเป็นกลุ่มคอนเทนเนอร์ที่ให้บริการโดเมนนี้

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

มีปัญหาอะไรอีกบ้าง? นี่คือสิ่งที่คอนเทนเนอร์ทั้งหมดทำงานเป็นรูทโดยค่าเริ่มต้น นี่คือรูทที่ไม่เท่ากับโฮสต์รูทของระบบ

อย่างไรก็ตาม หากคุณป้อนคอนเทนเนอร์ คอนเทนเนอร์นั้นจะถูกรูทและไฟล์ที่เราสร้างในคอนเทนเนอร์นี้จะได้รับสิทธิ์รูท

หากผู้พัฒนาเข้าไปในคอนเทนเนอร์และสร้างคำสั่งที่นั่นเพื่อสร้างไฟล์ จากนั้นออกจากคอนเทนเนอร์ แสดงว่าเขามีไฟล์ในไดเร็กทอรีการทำงานของเขาที่เขาไม่สามารถเข้าถึงได้

จะแก้ไขได้อย่างไร? คุณสามารถเพิ่มผู้ใช้ที่จะอยู่ในคอนเทนเนอร์

เกิดปัญหาอะไรขึ้นเมื่อเราเพิ่มผู้ใช้

เมื่อสร้างผู้ใช้ เรามักไม่มีรหัสกลุ่ม (UID) และรหัสผู้ใช้ (GID) เดียวกัน

เพื่อแก้ปัญหานี้ในคอนเทนเนอร์ เราใช้ผู้ใช้ที่มี ID 1000

ในกรณีของเรา สิ่งนี้เกิดขึ้นพร้อมกับความจริงที่ว่านักพัฒนาเกือบทั้งหมดใช้ระบบปฏิบัติการ Ubuntu และบน Ubuntu ผู้ใช้คนแรกมี ID 1000

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

เรามีแผนไหม?

อ่านเอกสารประกอบของ Docker โครงการกำลังพัฒนาอย่างแข็งขัน เอกสารมีการเปลี่ยนแปลง ข้อมูลที่ได้รับเมื่อสองหรือสามเดือนก่อนเริ่มล้าสมัยอย่างช้าๆ

ปัญหาบางอย่างที่เราแก้ไขนั้นค่อนข้างจะแก้ไขได้ด้วยวิธีการมาตรฐาน

ดังนั้นฉันต้องการไปต่อเพื่อไปที่การประสานเสียงโดยตรง

ตัวอย่างหนึ่งคือกลไกในตัวของ Docker ที่เรียกว่า Docker Swarm ซึ่งแกะออกจากกล่อง ฉันต้องการเรียกใช้บางอย่างในการผลิตโดยใช้เทคโนโลยี Docker Swarm

ตู้วางไข่ทำให้การทำงานกับท่อนซุงไม่สะดวก ตอนนี้บันทึกถูกแยกออก กระจายอยู่ทั่วภาชนะ หนึ่งในภารกิจคือการเข้าถึงบันทึกอย่างสะดวกผ่านเว็บอินเตอร์เฟส

ขั้นตอนการพัฒนาและทดสอบด้วย Docker และ Gitlab CI

ที่มา: will.com

เพิ่มความคิดเห็น