Docker وGo: حاويات التطبيقات من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا Docker وGo هما الثنائي المثالي؟



Go (Golang) وDocker هما أداتان غيرتا نهج تطوير ونشر خدمات الواجهة الخلفية. يتم تجميع Go في ملف ثنائي ثابت واحد، بينما يسمح Docker بتغليف هذا الملف الثنائي في بيئة معزولة. معًا، يقدمان حاويات بسيطة وسريعة وآمنة يمكن تشغيلها في أي مكان: من كمبيوتر المطور إلى مجموعة Kubernetes الإنتاجية.



في هذه المقالة، سننتقل من الصفر إلى تطبيق Go جاهز للإنتاج ومعبأ في Docker. ستتعلم كيفية كتابة Dockerfile، تحسين حجم الصورة، استخدام البناء متعدد المراحل، وتشغيل الحاويات مع خدمة Go.



1. الأساسيات: تطبيق Go وDockerfile بسيط



لنبدأ بخادم HTTP بسيط بلغة Go. لننشئ ملف main.go:



package main

import ( "fmt" "net/http")

func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from Go inside Docker!") })

fmt.Println("Server is running on :8080") http.ListenAndServe(":8080", nil)}


الآن لنكتب Dockerfile بسيطًا:



FROM golang:1.22-alpine AS builder

WORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN go build -o server .

FROM alpine:3.19RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/server .EXPOSE 8080CMD ["./server"]


لنقم ببناء الصورة وتشغيل الحاوية:



docker build -t go-server .docker run -p 8080:8080 go-server


الآن افتح المتصفح وانتقل إلى http://localhost:8080 - سترى ترحيبًا من تطبيق Go الذي يعمل داخل الحاوية.



لماذا البناء متعدد المراحل؟

في المرحلة الأولى، نستخدم صورة Go الرسمية مع مجموعة كاملة من أدوات التجميع. في المرحلة الثانية، نستخدم Alpine Linux البسيط، حيث يتم نسخ الملف الثنائي النهائي فقط. هذا يسمح بالحصول على صورة بحجم حوالي 15-20 ميجابايت بدلاً من 500+ ميجابايت إذا تركنا صورة Go الكاملة.



2. تحسين الصورة: تقليل الحجم وسرعة البناء



الصورة الصغيرة لا توفر المساحة فحسب، بل توفر أيضًا تحميلًا أسرع وسطح هجوم أصغر. دعنا ننظر إلى التقنيات الرئيسية لتطبيقات Go.



2.1. استخدام .dockerignore

أنشئ ملف .dockerignore في جذر المشروع:



.git*.mdDockerfile.dockerignorenode_modules/test/


هذا يمنع نسخ الملفات غير الضرورية إلى سياق البناء ويسرع العملية.



2.2. تخزين التبعيات مؤقتًا

في Dockerfile الخاص بنا، نقوم أولاً بنسخ go.mod و go.sum فقط، ثم نقوم بتشغيل go mod download. يقوم Docker بتخزين كل طبقة مؤقتًا، وطالما لم تتغير هذه الملفات، لن يتم إعادة تحميل التبعيات في كل مرة يتغير فيها الكود.



2.3. CGO والتجميع الثابت

يستخدم Go افتراضيًا CGO لبعض العمليات (مثل العمل مع الشبكة عبر استدعاءات النظام). للحصول على ملف ثنائي ثابت تمامًا بدون تبعيات على libc، استخدم علامات التجميع:



RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server .


هذا يضمن أن الملف الثنائي سيعمل على أي توزيعة Linux، بما في ذلك الصور البسيطة مثل scratch.



2.4. Scratch - أخف صورة أساسية

إذا كان تطبيقك لا يتطلب شل، ping، أو أدوات مساعدة أخرى، استخدم الصورة الفارغة scratch:



FROM scratchCOPY --from=builder /app/server /EXPOSE 8080CMD ["/server"]


سيكون حجم هذه الصورة مساويًا لحجم الملف الثنائي نفسه - غالبًا أقل من 10 ميجابايت.



3. Docker Compose: تطبيق Go متعدد الحاويات



نادرًا ما تتكون التطبيقات الحقيقية من

المدونات

توصيات الكتب