دليل النشر

نشر تطبيق Go (Gin) على خادم VPS

انشر على VPS Cloud ←

دليل عملي

التطوير

نشر تطبيق Go (Gin) على خادم VPS

تُصرّف لغة Go إلى ملفّ ثنائي ساكن واحد دون تبعيات: إنّها اللغة المثالية للاستضافة الذاتية. تتّسع واجهة Gin في 15 إلى 30 ميجابايت من الذاكرة وتبدأ في مللي ثوانٍ. يأخذك هذا الدليل من الصفر إلى بيئة إنتاج متكاملة: ‎Dockerfile متعدّد المراحل بصورة ‎`scratch`، وDocker Compose مع Nginx وCertbot، وإعادة التحميل الفوري في التطوير عبر ‎`air`، وإدارة الأسرار، وتصحيح أكثر الأخطاء شيوعًا.

8 دقائق للقراءةعدد الخطوات: 7
المحتويات· لماذا الاستضافة الذاتية لواجهة Go على خادم VPS1/10
  1. 01لماذا الاستضافة الذاتية لواجهة Go على خادم VPS
  2. 02الفوائد الملموسة
  3. 03المتطلّبات العتادية والبرمجية
  4. 04‏Dockerfile متعدّد المراحل بصورة scratch
  5. 05Docker Compose للإنتاج مع Nginx وCertbot
  6. 06إعادة التحميل الفوري في التطوير مع air
  7. 07متغيّرات البيئة والأسرار
  8. 08تصحيح الأخطاء: المشاكل الشائعة
  9. 09نشر Go (Gin) بنقرة واحدة من Marketplace ServOrbit
  10. 10للمزيد

لماذا الاستضافة الذاتية لواجهة Go على خادم VPS

على خلاف Java أو Node، يُصرَّف تطبيق Go (مع إطار العمل Gin) إلى ملفّ ثنائي ساكن واحد لا يحتاج إلى مفسّر ولا إلى بيئة تشغيل ولا إلى مكتبة مشتركة. يمكنك حرفيًا وضع الملفّ الثنائي على خادم VPS وتشغيله. تغيّر هذه الخفّة كلّ شيء بالنسبة للاستضافة الذاتية: تعمل واجهة Gin في 15 إلى 30 ميجابايت من الذاكرة وتبدأ في بضع مللي ثوانٍ. على خادم VPS، تستغلّ هذه الكفاءة إلى أقصى حدّ. كما تتجنّب تعقيد صور Docker الضخمة: تكفي صورة ‎scratch بحجم 10 ميجابايت، وعمليات البناء والسحب شبه فورية.

الفوائد الملموسة

  • ملفّ ثنائي ساكن واحد: لا بيئة تشغيل لتثبيتها، والنشر بمجرّد نسخ ملفّ
  • بصمة ذاكرية ضئيلة (15-30 ميجابايت) تتيح إغراق خادم VPS صغير بالطلبات
  • صورة Docker باسم ‎scratch أو ‎distroless بحجم 10-15 ميجابايت: عمليات بناء وسحب شبه فورية
  • بدء التشغيل في مللي ثوانٍ: عمليات إعادة نشر وإعادة تشغيل دون انقطاع ملحوظ
  • تزامن أصلي عبر goroutines: معالج افتراضي واحد يدير آلاف الاتصالات المتزامنة
  • سطح هجوم مُقلّص: لا مفسّر ولا حزم نظام لترقيعها

المتطلّبات العتادية والبرمجية

هنا تتألّق Go: تتّسع واجهة Gin دون قاعدة بيانات على خادم VPS بمعالج افتراضي واحد (1 vCPU) و1 جيجابايت من الذاكرة. ومع PostgreSQL في الموقع نفسه، استهدف 2 جيجابايت للراحة. لست بحاجة حتى إلى Go على الخادم إذا صرّفت في CI أو بالتصريف المتقاطع محليًا (‎GOOS=linux GOARCH=amd64 go build). ثبّت Docker وDocker Compose على الخادم. وجّه نطاق ‎api.mondomaine.com نحو عنوان IP الخاص بخادم VPS عبر سجلّ A. تكفي 5 جيجابايت من القرص بسهولة. على جهازك، يُنصح باستخدام ‎Go 1.27 أو أحدث — من go.dev/dl.

‏Dockerfile متعدّد المراحل بصورة scratch

‏Dockerfile متعدّد المراحل هو مفتاح الصورة النهائية المصغّرة. المرحلة الأولى تصرّف الملفّ الثنائي داخل حاوية Go كاملة؛ والثانية تنسخه إلى صورة ‎scratch فارغة — لا shell، ولا نظام تشغيل، فقط ملفّك الثنائي وشهادات CA لاتصالات HTTPS الصادرة. مثال كامل لمشروع Gin:

FROM golang:1.27-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o server .

FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

الراية ‎CGO_ENABLED=0 تفرض ملفًّا ثنائيًا ساكنًا بنسبة 100%، ضروري لعمل ‎FROM scratch. وتقلّص راية ‎-ldflags="-s -w" حجم الملفّ الثنائي بنحو 30% بحذف جداول التنقيح. أمّا نسخ شهادات CA فضروريّ متى كانت واجهتك تتصل بخدمات HTTPS خارجية (Stripe، SendGrid...). إذا احتجت shell للتنقيح، استبدل ‎FROM scratch بـ ‎FROM gcr.io/distroless/static-debian12.

Docker Compose للإنتاج مع Nginx وCertbot

  1. إنشاء هيكل الملفّات على الخادم

    اتصل عبر SSH وأنشئ مجلّد المشروع: ‎mkdir -p /opt/myapp/{nginx/conf.d,certbot/www,certbot/conf} && cd /opt/myapp. هذا الهيكل سيستضيف إعداد Nginx وأحجام Certbot.

  2. كتابة ملفّ docker-compose.yml

    أنشئ ‎/opt/myapp/docker-compose.yml بثلاثة خدمات: ‎app (صورة Go الخاصة بك)، و‎nginx (الوكيل العكسي)، و‎certbot (تجديد SSL). مثال مصغّر:

    services:
      app:
        image: monapp:latest
        restart: unless-stopped
        env_file: .env
        expose:
          - "8080"
      nginx:
        image: nginx:1.27-alpine
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx/conf.d:/etc/nginx/conf.d:ro
          - ./certbot/www:/var/www/certbot:ro
          - ./certbot/conf:/etc/letsencrypt:ro
        depends_on:
          - app
      certbot:
        image: certbot/certbot
        volumes:
          - ./certbot/www:/var/www/certbot
          - ./certbot/conf:/etc/letsencrypt
  3. إعداد Nginx كوكيل عكسي

    أنشئ ‎nginx/conf.d/app.conf. ابدأ ببلوك HTTP فقط للتحقّق من تحدّي ACME، ثمّ أضف بلوك HTTPS بعد الحصول على الشهادة:

    server {
        listen 80;
        server_name api.mondomaine.com;
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
        location / {
            return 301 https://$host$request_uri;
        }
    }
    server {
        listen 443 ssl;
        server_name api.mondomaine.com;
        ssl_certificate /etc/letsencrypt/live/api.mondomaine.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.mondomaine.com/privkey.pem;
        location / {
            proxy_pass http://app:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
  4. الحصول على شهادة Let's Encrypt

    شغّل Nginx وحده أوّلًا، ثمّ أطلق Certbot في وضع webroot: ‎docker compose up -d nginx && docker compose run --rm certbot certonly --webroot -w /var/www/certbot -d api.mondomaine.com --email [email protected] --agree-tos. بعد إصدار الشهادة، أعد تشغيل Nginx: ‎docker compose restart nginx.

  5. بناء التطبيق وتشغيله

    ابنِ صورة Go على الخادم (أو انقلها عبر ‎docker save/load أو registry خاص): ‎docker build -t monapp:latest .. ثمّ أطلق المنظومة الكاملة: ‎docker compose up -d. تتبّع السجلّات بـ ‎docker compose logs -f app.

  6. أتمتة تجديد SSL

    أضف crontab على الخادم لتجديد الشهادة تلقائيًا كلّ أسبوع: ‎(crontab -l 2>/dev/null; echo "0 3 * * 0 cd /opt/myapp && docker compose run --rm certbot renew && docker compose restart nginx") | crontab -. لا يُجدّد Certbot فعليًا إلّا إذا كان انتهاء الصلاحية في أقل من 30 يومًا.

  7. إعداد Gin لبيئة الإنتاج

    حوّل Gin إلى وضع الإصدار (release) باستخدام ‎gin.SetMode(gin.ReleaseMode) أو المتغيّر ‎GIN_MODE=release لتعطيل سجلّات التنقيح المطوّلة. اقرأ المنفذ والأسرار من البيئة (‎os.Getenv)، ولا تُضمّنها أبدًا في الشيفرة مباشرةً.

إعادة التحميل الفوري في التطوير مع air

في مرحلة التطوير، إعادة التصريف والتشغيل يدويًا عند كلّ تعديل أمر مُرهق. يراقب ‎air (github.com/air-verse/air، الإصدار الحالي v1.67.4) شجرة الملفّات ويعيد تشغيل الملفّ الثنائي عند كلّ تغيير في ملفّات ‎.go. التثبيت: ‎go install github.com/air-verse/air@latest. شغّل ببساطة ‎air في جذر مشروعك — يُولَّد ملفّ إعداد ‎.air.toml افتراضي تلقائيًا عند أوّل تشغيل. لتخصيص المجلّدات المُراقَبة أو استثناء ‎vendor/:

[build]
  cmd = "go build -o ./tmp/server ."
  bin = "./tmp/server"
  include_ext = ["go", "html", "tmpl"]
  exclude_dir = ["vendor", "testdata"]

‏air مخصّص للتطوير المحلّي فقط: لا تثبّته أبدًا في صورة Docker الإنتاجية.

متغيّرات البيئة والأسرار

لا تُضمّن الأسرار (مفاتيح API، كلمات مرور قواعد البيانات، رموز JWT) مباشرةً في الشيفرة. الممارسة المعيارية في Go هي قراءتها من البيئة بـ ‎os.Getenv("DB_PASSWORD"). في التطوير المحلّي، ملفّ ‎.env محمّل بـ ‎godotenv يبسّط سير العمل: ‎go get github.com/joho/godotenv، ثمّ عند البدء:

import "github.com/joho/godotenv"
func main() {
    _ = godotenv.Load() // يحمّل .env إذا وُجد، صامت في الإنتاج
    db := os.Getenv("DB_DSN")
    port := os.Getenv("PORT")
    if port == "" { port = "8080" }
    // ...
}

في الإنتاج، مرّر المتغيّرات عبر ‎env_file: .env في Docker Compose (هذا الملفّ يجب ألّا يُحفظ في git أبدًا — أضف ‎.env إلى ‎.gitignore). للأسرار البالغة الحساسية، فضّل أسرار Docker أو خزنة خارجية. القاعدة الذهبية: سرّ في ‎git log هو سرّ مكشوف.

فعّل تنميط (profiling) ‎pprof الخاص بـ Go خلف نقطة نهاية محمية: ‎import _ "net/http/pprof" مكشوفة على منفذ داخلي لا يمكن الوصول إليه إلّا عبر نفق SSH (‎ssh -L 6060:localhost:6060 user@vps). تحصل على مخطّطات لهب (flame graphs) للمعالج والذاكرة في بيئة الإنتاج الحقيقية دون حمل زائد يُذكر. فكّر أيضًا في التصريف باستخدام ‎-ldflags="-s -w" لتقليص حجم الملفّ الثنائي بنحو 30% عبر إزالة جداول التنقيح.

تصحيح الأخطاء: المشاكل الشائعة

إليك الأخطاء الخمسة الأكثر شيوعًا عند أوّل نشر Go على خادم VPS، مع رسائل الخطأ الدقيقة وطريقة الإصلاح.

1. ‎standard_init_linux.go:228: exec user process caused: no such file or directory — صُرِّف الملفّ الثنائي مع تفعيل CGO وصورة ‎scratch لا تحتوي libc. الإصلاح: أعد التصريف بـ ‎CGO_ENABLED=0 go build -o server ..

2. ‎exec format error — صُرِّف الملفّ الثنائي لمعمارية مختلفة (مثلًا macOS ARM ‎→ Linux AMD64). الإصلاح: تحقّق من ‎GOOS=linux GOARCH=amd64 قبل البناء، أو ابنِ مباشرةً على الخادم.

3. ‎bind: address already in use (المنفذ 8080) — عملية أخرى تستمع على هذا المنفذ. تحقّق بـ ‎ss -tlnp | grep 8080 وأوقف العملية المتعارضة، أو غيّر المنفذ في ‎.env.

4. ‎x509: certificate signed by unknown authority أو ‎certificate has expired — حاوية ‎scratch تفتقر إلى شهادات CA، أو انتهت صلاحية شهادة Let's Encrypt. الإصلاح: تحقّق من وجود ‎COPY --from=build /etc/ssl/certs/ca-certificates.crt في ‎Dockerfile، وأعد تشغيل Certbot للتجديد.

5. ‎permission denied عند بدء الملفّ الثنائي — الملفّ الثنائي ليس قابلًا للتنفيذ. الإصلاح: تحقّق من الصلاحيات بـ ‎ls -la server وطبّق ‎chmod +x server إذا لزم. في ‎Dockerfile، ‎COPY --from=build يحفظ الصلاحيات عادةً، لكنّ ‎RUN chmod +x /server الصريح يضمن النتيجة.

نشر Go (Gin) بنقرة واحدة من Marketplace ServOrbit

تقدّم Marketplace ServOrbit قالب Go (Gin) Stack جاهزًا: Go من الملفّ الثنائي الرسمي go.dev، وNginx، وPostgreSQL 16 تُثبَّت تلقائيًا على VPS عند الطلب. لا جلسة SSH للإعداد الأساسي — تصل مباشرة إلى خطوة تصريف مشروعك ورفع الملفّ الثنائي. صفحة marketplace تحتوي المواصفات والحالات ودليل الاستخدام الأول.

للمزيد

أصبح بإمكانك الآن نشر واجهة Go على خادم VPS باحترافية. للمضيّ أبعد: اضبط Traefik v3 وكيلًا عكسيًا بدلًا من Nginx — يدير التوجيه وشهادات Let's Encrypt وموازنة التحميل في حاوية واحدة بإعداد تصريحي عبر labels Docker (راجع دليلنا [Traefik v3 على VPS](/blog/traefik-v3-vps-reverse-proxy)). للتحديثات في الإنتاج دون انقطاع، اطّلع على مقالنا حول [أفضل ممارسات تحديث Docker Compose](/blog/docker-compose-mise-a-jour-best-practices-vps): النشر المتدرّج، وفحوصات الصحّة، واستراتيجيات الرجوع للإصدار السابق. وإذا فضّلت إسناد البنية التحتية، فإنّ [قالب Go (Gin) في Marketplace](/applications/developpement/golang) يُعدّ المنظومة كاملةً في دقائق.

انشر Go (Gin) Stack في دقائق

يُثبِّت قالب Go (Gin) Stack ServOrbit Go 1.22+ وNginx وPostgreSQL 16 على VPS الخاص بك. صرِّف مشروعك ثمّ انشر الملفّ الثنائي فورًا.