Docker و Go: حاويات التطبيقات بلغة Golang
في التطوير الحديث، أصبحت الحاويات المعيار الفعلي لنشر التطبيقات وتوسيع نطاقها. Docker و Go هما الثنائي المثالي لإنشاء خدمات مصغرة خفيفة وسريعة وآمنة. Go يتم تجميعه إلى ملف ثنائي ثابت، مما يجعله جذابًا بشكل خاص للحاويات: يمكن أن يزن الصورة النهائية بضعة ميغابايت فقط. في هذه المقالة، سنشرح كيفية حاويات تطبيقات Go بشكل صحيح، وتحسين Dockerfile، وتجنب الأخطاء الشائعة.
لماذا Docker و Go هما المزيج المثالي؟
Go (Golang) صُممت مع التركيز على البنى السحابية الحديثة. ميزاتها الرئيسية هي التجميع الثابت، والدعم المدمج للتزامن، وغياب التبعيات الخارجية في بيئة التشغيل. Docker، بدوره، يوفر بيئة معزولة لتشغيل التطبيقات. معًا، يسمحان بإنشاء صور:
- تشغل مساحة ضئيلة — يمكن أن تكون صورة تطبيق Go أقل من 10 ميجابايت.
- تبدأ بسرعة — الملف الثنائي الثابت لا يحتاج إلى مترجم أو آلة افتراضية.
- قابلة للتوسع بسهولة — مثالية للتنسيق في Kubernetes.
- أكثر أمانًا — الصورة المصغرة تقلل من سطح الهجوم.
إنشاء تطبيق Go بسيط للحاويات
لنبدأ بكتابة تطبيق ويب بسيط بلغة Go سنقوم بحاوياته. قم بإنشاء ملف main.go:
package main
import ( "fmt" "log" "net/http" "os")
func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from Go in Docker! 🐳") })
log.Printf("Server starting on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}هذا التطبيق يستمع لطلبات HTTP ويعيد رسالة ترحيبية. يمكن ضبط المنفذ عبر متغير البيئة PORT.
كتابة Dockerfile لتطبيق Go
الآن سنقوم بإنشاء Dockerfile. سنبدأ بالنهج الأساسي ثم نحسّنه.
Dockerfile أساسي (بدون تحسين)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./RUN go mod download
COPY . .RUN go build -o main .
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]يستخدم هذا Dockerfile multi-stage build — أحد أفضل الأنماط لـ Go. المرحلة الأولى (builder) تجمّع التطبيق، والثانية (الصورة النهائية) تحتوي فقط على الملف الثنائي المُجمّع. هذا النهج يتجنب تضمين المترجم وأدوات Go في الصورة النهائية.
Dockerfile محسّن (أفضل الممارسات)
لجعل الصورة أصغر وأكثر أمانًا، نستخدم scratch — صورة فارغة بدون shell وأدوات:
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./RUN go mod download
COPY . .
# تعطيل CGO، تفعيل التحسيناتRUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o main .
FROM scratch
WORKDIR /root/
COPY --from=builder /app/main .
# إضافة الشهادات الجذرية لـ HTTPSCOPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
CMD ["./main"]التحسينات الرئيسية:
CGO_ENABLED=0— يعطل CGO، مما يقلل حجم الملف الثنائي.-ldflags="-s -w"— يزيل جدول الرموز ومعلومات التصحيح.scratch— صورة مصغرة بدون طبقات زائدة.- نسخ
ca-certificates.crt— ضروري للعمل مع HTTPS.