Docker وGo: حاويات التطبيقات المتقدمة

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

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

ابدأ الدورة

مقدمة

\n

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

\n\n

1. البناء متعدد المراحل: صورة صغيرة في ثوانٍ

\n

Go يُترجم إلى ملف ثنائي ثابت، وهو مثالي للحاويات. ولكن إذا كنت تستخدم الصورة الكاملة golang:1.22 للتشغيل، فأنت تحمل المترجم ومدير الحزم والأدوات النظامية. الحل هو البناء متعدد المراحل.

\n\n

Dockerfile أساسي مع بناء متعدد المراحل

\n
# المرحلة 1: البناء\nFROM golang:1.22-alpine AS builder\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/main ./cmd/\n\n# المرحلة 2: صورة صغيرة\nFROM alpine:3.19\nRUN apk add --no-cache ca-certificates tzdata\nCOPY --from=builder /app/main /usr/local/bin/main\nEXPOSE 8080\nENTRYPOINT ["/usr/local/bin/main"]
\n\n

لماذا يعمل هذا؟

\n
    \n
  • Alpine — 5 ميجابايت، مجموعة أدوات صغيرة.
  • \n
  • CGO_ENABLED=0 — يعطل التبعيات C، يصبح الملف الثنائي ثابتًا.
  • \n
  • -ldflags="-s -w" — يزيل معلومات التصحيح، مما يقلل حجم الملف الثنائي بنسبة 30-40%.
  • \n
  • ca-certificates و tzdata — لطلبات HTTPS والوقت الصحيح.
  • \n
\n\n

النتيجة: صورة بحجم 10-15 ميجابايت بدلاً من 800+ ميجابايت. البناء — 15-20 ثانية (مع تخزين التبعيات مؤقتًا).

\n\n

2. تحسين التخزين المؤقت والطبقات

\n

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

\n\n
COPY go.mod go.sum ./\nRUN go mod download\nCOPY . .
\n\n

أيضًا استخدم .dockerignore:

\n
.git\n*.md\ntest/\ncoverage/\n.env\nDockerfile
\n\n

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

\n\n

خدعة متقدمة: تخزين الوحدات مؤقتًا

\n

إذا كنت تستخدم Go modules، يمكنك تركيب ذاكرة التخزين المؤقت:

\n
FROM golang:1.22-alpine AS builder\nWORKDIR /app\nRUN --mount=type=cache,target=/go/pkg/mod \\\n    --mount=type=cache,target=/root/.cache/go-build \\\n    go build -ldflags="-s -w" -o /app/main ./cmd/
\n\n

هذا يحافظ على الوحدات التي تم تنزيلها ونتائج البناء بين عمليات تشغيل docker build.

\n\n

3. فحوصات الصحة والإشارات والإيقاف الآمن

\n

Docker يمكنه التحقق من صحة الحاوية. أضف في Dockerfile:

\n\n
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\n    CMD ["/usr/local/bin/main", "health"]
\n\n

في كود Go، نفذ نقطة النهاية /healthz:

\n
package main\n\nimport (\n    "net/http"\n    "os"\n    "os/signal"\n    "syscall"\n)\n\nfunc main() {\n    http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {\n        w.WriteHeader(http.StatusOK)\n        w.Write([]byte("ok"))\n    })\n\n    srv := &http.Server{Addr: ":8080"}\n\n    // إيقاف آمن\n    go func() {\n        sigint := make(chan os.Signal, 1)\n        signal.Notify(sigint, syscall.SIGTERM, syscall.SIGINT)\n        <-sigint\n        srv.Shutdown(nil)\n    }()\n\n    srv.ListenAndServe()\n}
\n\n

مهم: يجب على تطبيق Go معالجة SIGTERM بشكل صحيح (الذي يرسله Docker عند إيقاف الحاوية). بدون إيقاف آمن، قد تفقد بيانات أو تترك اتصالات مفتوحة.

\n\n

4. Docker Compose للإنتاج: الشبكات وحدات التخزين وقيود الموارد

المدونات

توصيات الكتب