تميمة الدب القطبي الخاصة بـ NordBastion تقف في قبو حجري إسكندنافي مظلم بجانب حامل خوادم، بإحدى قوائمه مستندة على مخطط تفرعات ثلاثي الأبعاد عائم بلون سماوي (سيان) هولوغرافي يمثل تاريخ Git بثلاثة خطوط متلاقية، وصندوق حصين محفور بالرموز الرونية يحوي شيفرة مصدرية على المنضدة بجانبه، وضوء الشفق القطبي يتساقط عبر نافذة مقوسة طويلة
كيفية · البنية التحتية للمطورين·18 دقيقة قراءة · 45 دقيقة تطبيق عملي

خادم Git خاص بك.
المستودع هو الهيكل التنظيمي.

المستودع الخاص سجل مؤرَّخ لما تبنيه، ومع من تبنيه، ومدى تقدمك فيه — وعلى منصة ما، يكون ذلك السجل بحوزة شركة في ولاية قضائية تخص طرفًا آخر. ست خطوات لنقله إلى خادم تستأجره مجهول الهوية: Forgejo خلف Caddy، وPostgreSQL تحته، ودفع عبر SSH على منفذ خاص به، ومُشغّل Actions لا يرى أسرار بيئة الإنتاج لديك أبدًا، ونسخة احتياطية استعدتها فعلًا. يكلف الخادم $3.90 شهريًا. تم اختباره على Debian 12.

الخطوات الست
  1. 01

    الاختيار

    مستودع عارٍ، Forgejo، GitLab

  2. 02

    التوفير

    منافذ محسومة قبل الإقلاع

  3. 03

    نشر

    Forgejo، Postgres، Caddy

  4. 04

    الدفع

    SSH، مفاتيح النشر، التوقيعات

  5. 05

    البناء

    مُشغّل يُبقى على مسافة

  6. 06

    Keep

    مرايا، نسخ احتياطية، ترقيات

قبل أن تبدأ · ما الذي تحتفظ به المنصة

الشيفرة هي الجزء الأقل أهمية. البيانات الوصفية هي الأصل الحقيقي.

يكاد كل جدال حول الاستضافة الذاتية لـ Git يكون جدالًا حول الشيفرة المصدرية، وهي الجزء الأقل أهمية على الإطلاق. معظمها عادي لا يلفت الانتباه، وجزء كبير منها ليس سوى طبقة رقيقة فوق مكتبات مفتوحة المصدر، ولو تسرّبت غدًا فإن الضرر العملي سيكون عادة إحراجًا لا أذى حقيقيًا. لهذا السبب تبدو عبارة "شيفرتي ليست سرًا" وكأنها إجابة كاملة، ولماذا هي ليست كذلك.

ما يحيط بالشيفرة هو الجزء المثير للاهتمام. المستودع سجل عمل مؤرَّخ ومنسوب وعالي الدقة: طوابع زمنية للالتزامات تصف متى تنام، وأسطر تأليف مشترك تصف مع من تعمل، وأسماء فروع تصف منتجات لم يُعلن عنها أحد، ومتتبع مشكلات يصف ما هو معطل ومدى سوئه، والتزام أول يحدد تاريخ المشروع كله. اقرأ مئة مستودع بهذه الطريقة ولن تكون تقرأ برمجيات بعد ذلك — بل ستكون تقرأ شركة، وخارطة طريقها، وعدد موظفيها، ومتاعبها.

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

أين يقيم المستودع من يملك التاريخ مرتبط بهويتك القانونية كيف تسوء الأمور
منصة، حساب شخصيالمنصة، في ولايتها القضائية الخاصةنعم — البريد الإلكتروني، والفوترة، وغالبًا رقم هاتفتعليق واحد للحساب يأخذ معه كل مستودع بعيد
منصة، حساب مؤسسةالمنصة، إضافة إلى من يدير المؤسسةنعم، ولصاحب عملك أيضًاإنهاء العمل يزيل وصولك إلى عملك الخاص
مستضاف ذاتيًا، على مزوّد سحابي عملاقأنت، على مستوى طبقة التطبيقنعم — حساب الفوترة هو الهويةاللقطة تقيم في الحساب الذي يمكن إغلاقه
مستضاف ذاتيًا، على خادم VPS بدون KYCأنت، وأنت فقطلا — بلا هوية، بلا بطاقة، يُسوَّى بالعملات المشفرةأنت مسؤول النظام الآن. النسخة الاحتياطية السيئة نهائية

الصف الثالث هو الصف الذي يوقع في الفخ الفرق التي تظن أنها حلت هذه المسألة بالفعل. منصة ثبّتّها بنفسك، على جهاز مستأجَر ببطاقة الشركة تحت حساب شركة موثّق، تكون قد نقلت التطبيق خارج المنصة الخارجية وتركت الهوية بالضبط حيث كانت. هذا مكسب حقيقي في التحكم ولا مكسب على الإطلاق في التعرض.

ويوضح الصف الرابع تكلفته الخاصة بصراحة، لأن بقية هذا الدليل تدور في معظمها حول دفع تلك التكلفة. نمط الفشل في الاستضافة الذاتية ليس المراقبة، بل الفقدان. المنصة تحتفظ بنسخ احتياطية لا تفكر فيها أبدًا. أما خادمك فيحتفظ بالنسخ الاحتياطية التي أعددتها أنت. الخطوة 06 ليست لمسة تجميلية اختيارية في النهاية — إنها الخطوة التي تجعل الخطوات الخمس الأخرى آمنة.

الخطوة 01 · الاختيار

كم من المنصة تحتاج فعلًا؟ الإجابة الصادقة غالبًا هي "لا شيء".

ابدأ بأصغر شيء يحل مشكلتك، لأن كل طبقة فوقه هي خدمة سيتوجب عليك تشغيلها. المستودع العاري عبر SSH هو أمر واحد على خادم تملكه بالفعل، ويمنحك مصدرًا بعيدًا حقيقيًا لـ Git بمصادقة وتاريخ وصلاحية دفع. لا تطبيق ويب، ولا قاعدة بيانات، ولا دوامة ترقيات، ولا شيء يحتاج إلى ترقيع سوى sshd. إذا كنت شخصًا واحدًا يريد إخراج التزاماته من حاسوب محمول ومن منصة خارجية، فهذه إجابة كاملة ويمكنك التوقف عن القراءة بعد الخطوة 02.

# On the server, as an unprivileged user:
mkdir -p ~/git/project.git && cd ~/git/project.git
git init --bare

# On your laptop:
git remote add origin ssh://user@git.example.com/~/git/project.git
git push -u origin main

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

الخاصية مستودع عارٍ عبر SSH Forgejo Gitea GitLab CE
واجهة ويب، طلبات سحب، مشكلاتلا شيءنعمنعمنعم، وأكثر من ذلك بكثير
الذاكرة عند السكونشبه معدومةبضع مئات من الميجابايتبضع مئات من الميجابايتعدة جيجابايتات، قبل التكامل المستمر
تكامل مستمر مدمجخطافات git، إذا كتبتها بنفسكForgejo ActionsGitea ActionsGitLab CI، الأكثر نضجًا
من يوجّه دفة المشروعمشروع GitCodeberg e.V.، جهة غير ربحيةشركة هادفة للربح، نواة مفتوحةشركة مدرجة في البورصة، نواة مفتوحة
الترخيصGPLv2GPLv3+ منذ الإصدار v9.0 (وMIT قبل ذلك)MIT، مع إضافات مملوكةنواة MIT، وفئات مملوكة
اخترها حينأنت وحدك وتريد صيانة معدومةتريد منصة حقيقية على خادم صغيرتشغّلها بالفعل وتعمل جيدًاتحتاج إلى مجموعة مزايا المؤسسات

يشترك Forgejo وGitea في أصل واحد وما زالا يبدوان متطابقين تقريبًا في الاستخدام اليومي. أصبح Forgejo تفرعًا كاملاً في أوائل 2024 وتتبعه جمعية Codeberg e.V.، وهي جمعية مسجَّلة غير ربحية في برلين؛ بينما تطوّر Gitea شركة هادفة للربح تملك علامته التجارية وتطلب من المساهمين التنازل عن حقوق الملكية. كلاهما برمجية جيدة. لكن واحدًا منهما فقط له وصي تتوافق حوافزه مع سبب قراءتك لهذه الصفحة.

تستخدم بقية هذا الدليل Forgejo. كل ما ورد في الخطوات من 02 إلى 06 ينطبق شبه حرفيًا على Gitea — يتغير اسم الحاوية وبعض متغيرات البيئة، لكن الشكل العام لا يتغير.

الخطوة 02 · التجهيز

قرر المنافذ قبل أن تقررها المنصة نيابة عنك. اثنان منها لـ SSH.

اطلب الخادم أولًا. في لوحة التحكم: Order → VPS → Sentinel، بصورة Debian 12، في أي حصن (bastion) تريد أن يقيم فيه التاريخ — هلسنكي، أو ستوكهولم، أو أوسلو، أو ريكيافيك. لا حاجة إلى عنوان بريد إلكتروني لفتح الحساب، وتُسوّى الفاتورة بعملة Monero أو Bitcoin أو عبر Lightning أو أي أصل آخر مدعوم. هذا الأمر أكثر أهمية هنا منه في معظم أعباء العمل الأخرى: فالمنصة هي الخدمة الوحيدة التي يقوم عرضها بأكمله على أن سجل عملك غير مرتبط باسم.

ثم نفّذ قائمة تحصين الساعة الأولى — SSH بالمفاتيح فقط على منفذ مُنقول، وترقيات دون إشراف، وجدار حماية يرفض كل شيء افتراضيًا — لأن كل ما يلي يفترض خادمًا ليس ملكًا لشخص آخر أصلًا.

ما الذي تضعه فعليًا على الإنترنت

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

وجّه اسم مضيف نحو الخادم — سجل A، وسجل AAAA إذا أردت الوصول إليه عبر IPv6 — ودعه ينتشر قبل أن تبدأ، لأن الوكيل العكسي سيحاول الحصول على شهادة لذلك الاسم في أول مرة يُقلع فيها، وفشل التحقق طريقة مربكة للبدء. ثم اكتب قواعد جدار الحماية بينما لا شيء يستمع بعد.

مشكلة SSH المزدوجة. تتحدث المنصة بـ SSH من أجل Git، وخادمك يتحدث بـ SSH بالفعل من أجل الإدارة. لا يمكن أن يمتلك كلاهما المنفذ 22، والخلط بينهما هو كيف ينتهي الأمر بالناس إلى خدمة إدارية تحتاج أيضًا إلى فهم Git. أبقهما منفصلين: الإدارة على المنفذ المنقول من دليل التحصين، وGit على منفذ عام مخصص يُطابَق إلى الحاوية. 2222 هو الاختيار المتعارف عليه ولا شيء مقدّس فيه.

ufw default deny incoming
ufw allow 47222/tcp                  # administrative SSH, moved
ufw allow 80/tcp                     # ACME HTTP-01 challenge
ufw allow 443/tcp                    # the web interface
ufw allow 2222/tcp                   # git over SSH, into the container
ufw enable
ufw status numbered

# Nothing else is open. In particular: PostgreSQL stays on the Docker
# network and is never published to the host, let alone the internet.

ثبّت Docker من المستودع الرسمي بدلًا من حزمة التوزيعة، حتى يكون Compose v2 متوفرًا والإصدار حديثًا. ثم أنشئ دليلًا للمكدس واجعله المكان الوحيد على الخادم الذي يحمل الحالة — وهو الدليل الذي تنسخه الخطوة 06 احتياطيًا.

curl -fsSL https://get.docker.com | sh
docker compose version

install -d -m 0750 /srv/forgejo
cd /srv/forgejo
الخطوة 03 · النشر

ثلاث حاويات. واحدة منها يجب ألا تكون قابلة للوصول أبدًا.

Forgejo وPostgreSQL وCaddy. يحتفظ Forgejo بالمستودعات ويقدّم الواجهة، ويحتفظ PostgreSQL بكل ما ليس كائن Git، وينهي Caddy اتصالات TLS ويحصل على الشهادة دون أن يُطلب منه ذلك مرتين. PostgreSQL غير منشور إلى المضيف عن قصد: فهو قابل للوصول فقط عبر شبكة Compose، بالاسم، من الحاوية الوحيدة التي تحتاجه.

/srv/forgejo/.env

FORGEJO_DOMAIN=git.example.com
FORGEJO_VERSION=15                             # the LTS line; 16 is current stable
POSTGRES_PASSWORD=$(openssl rand -base64 32)   # paste the value, do not leave the $( )

/srv/forgejo/docker-compose.yml

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:${FORGEJO_VERSION}
    container_name: forgejo
    environment:
      USER_UID: 1000
      USER_GID: 1000
      FORGEJO__database__DB_TYPE: postgres
      FORGEJO__database__HOST: db:5432
      FORGEJO__database__NAME: forgejo
      FORGEJO__database__USER: forgejo
      FORGEJO__database__PASSWD: ${POSTGRES_PASSWORD}
      FORGEJO__server__DOMAIN: ${FORGEJO_DOMAIN}
      FORGEJO__server__ROOT_URL: https://${FORGEJO_DOMAIN}/
      FORGEJO__server__SSH_DOMAIN: ${FORGEJO_DOMAIN}
      FORGEJO__server__SSH_PORT: "2222"          # what clones will say
      FORGEJO__server__SSH_LISTEN_PORT: "22"     # what the container listens on
      FORGEJO__service__DISABLE_REGISTRATION: "true"
      FORGEJO__repository__DEFAULT_PRIVATE: private
      FORGEJO__security__INSTALL_LOCK: "true"
    restart: unless-stopped
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"    # web, reached only by Caddy
      - "2222:22"                # git over SSH, public
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: forgejo-db
    environment:
      POSTGRES_USER: forgejo
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: forgejo
    restart: unless-stopped
    volumes:
      - ./postgres:/var/lib/postgresql/data
    # No ports: block. This is the point.

  caddy:
    image: caddy:2-alpine
    container_name: forgejo-caddy
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-data:/data
      - ./caddy-config:/config

/srv/forgejo/Caddyfile

git.example.com {
    encode zstd gzip
    request_body {
        max_size 512MB          # raise it if you push large repositories
    }
    reverse_proxy 127.0.0.1:3000
}

السطران الخاصان بـ SSH هما ما يخطئ فيه الناس، لذا يستحقان قراءة مرتين. SSH_LISTEN_PORT هو المنفذ داخل الحاوية، حيث يرتبط خادم SSH المدمج في Forgejo. SSH_PORT هو المنفذ الذي يطبعه Forgejo في عناوين الاستنساخ التي يعرضها لك — ويجب أن يطابق الجانب العام من تعيين المنفذ. اجعلهما غير متطابقين وسيعمل كل شيء ما عدا الشيء الوحيد الذي ينسخه المستخدمون ويلصقونه.

شغّلها، ثم أنشئ حساب المسؤول من سطر الأوامر. لا تستخدم أداة التثبيت عبر الويب. في نسخة جديدة تكون قابلة للوصول من أي شخص يعثر على اسم المضيف، ويصبح أول حساب يُنشأ من خلالها هو حساب المسؤول — سباق لا حاجة لك بخوضه. يغلقها INSTALL_LOCK في الملف أعلاه قبل أن تبدأ الحاوية أصلًا.

docker compose up -d
docker compose logs -f forgejo        # wait for "Starting new Web server"

docker compose exec -u git forgejo forgejo admin user create \
  --admin --username you --email you@example.com --random-password

افتح اسم المضيف في متصفح، وسجّل الدخول بكلمة المرور المطبوعة وغيّرها. ثم راجع الإعدادات التي تحوّل نسخة عاملة إلى نسخة مغلقة — معظمها مضبوط بالفعل عبر كتلة متغيرات البيئة أعلاه، ويستحق الأمر تأكيد كل واحد منها بدلًا من افتراض ذلك:

التسجيل

DISABLE_REGISTRATION = true. أنت من ينشئ الحسابات؛ لا أحد يسجّل نفسه بنفسه. إذا احتجت إلى تسجيلات عرضية بين الحين والآخر، استخدم مسار الدعوة بدلًا من فتح الباب على مصراعيه.

الظهور الافتراضي

DEFAULT_PRIVATE = private. المستودعات الجديدة تبدأ مغلقة. عندئذ يصبح النشر فعلًا مقصودًا لا نتيجة لإعداد افتراضي.

التصفح المجهول

يخفي REQUIRE_SIGNIN_VIEW = true حتى المستودعات العامة عن الزوار غير المسجَّلين. مناسب لمنصة فريق خاصة؛ غير مناسب إذا كنت تريد نشر أي شيء.

العامل الثاني

فعّله على حساب المسؤول قبل أن تفعل أي شيء آخر. المنصة الآن هي الجهاز القادر على إعادة كتابة كل فرع تملكه.

مسار واحد يستحق الحفظ عن ظهر قلب: الإعدادات الحية موجودة في ./data/gitea/conf/app.ini على المضيف. أبقى Forgejo اسم الدليل gitea للتوافق مع التثبيتات القائمة، وهو ما يفاجئ الجميع مرة واحدة بالضبط. تُكتب متغيرات البيئة من الصيغة FORGEJO__section__KEY في ذلك الملف عند بدء التشغيل، بحيث يمكنك إدارة الإعدادات كاملة من ملف Compose — لكن إذا حررت app.ini يدويًا، فإن متغير بيئة لنفس المفتاح سيطغى على تعديلك عند إعادة التشغيل التالية. اختر إحدى الطريقتين والتزم بها.

الخطوة 04 · الدفع

ادفع عبر SSH. ثم وقّعه، حتى لا يعتمد التاريخ على الخادم.

الصق مفتاحك العام في إعدادات الملف الشخصي، ثم علّم عميلك بمكان إقامة المنصة. ولأن Git على منفذ غير قياسي، فإن إدخالًا في إعدادات SSH لديك يستحق الثواني الثلاثين — فهو يُبقي المنفذ خارج كل عنوان ستكتبه لاحقًا ويجعل المستودعات البعيدة قابلة للنقل.

# ~/.ssh/config
Host git.example.com
    Port 2222
    User git
    IdentityFile ~/.ssh/id_ed25519

# Then, in any repository:
git remote set-url origin git@git.example.com:you/project.git
git push -u origin main
ssh -T git@git.example.com        # expect a greeting, not a shell

ذلك الأمر الأخير هو ما يخبرك ما إذا كان تعيين المنفذ وخادم SSH في الحاوية ومفتاحك متفقة جميعًا. رسالة ترحيب من Forgejo تعني أن السلسلة كلها تعمل. أما طلب كلمة مرور فيعني أنك وصلت بدلًا من ذلك إلى sshd الإداري للمضيف، وأن تعيين المنفذ خاطئ.

الآن وقّع التزاماتك. هذه هي الخطوة التي تتجاهلها معظم أدلة الاستضافة الذاتية، وهي أكثر أهمية على منصة مستضافة ذاتيًا منها على منصة خارجية. حقل مؤلف الالتزام نص حر — يستطيع أي شخص يمكنه الدفع أن يكتب اسمك فيه. التوقيع إثبات أن مفتاحًا محددًا هو من أنشأ التزامًا محددًا، ويظل إثباتًا حتى بعد أن يتعرض الخادم الذي دُفع إليه للاختراق أو الترحيل أو التخلص منه. يستطيع Git التوقيع بمفتاح SSH الذي تملكه بالفعل، فلم يعد هناك حاجة إلى الالتفاف عبر PGP:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

git commit --allow-empty -m "signed"
git log --show-signature -1

ثم أضف المفتاح العام نفسه مرة ثانية في المنصة، كمفتاح توقيع لا كمفتاح مصادقة. يتحقق Forgejo من التوقيع من جهة الخادم ويعرض الالتزام كمُوثَّق؛ ودون ذلك الإدخال الثاني لا توجد وسيلة لربط التوقيع بحسابك، ويظهر كل التزام كغير موثَّق حتى لو كان موقّعًا بشكل صحيح.

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

الترحيل من منصة خارجية لحظة جيدة للقيام بكل هذا بشكل صحيح. يأخذ مسار الترحيل الجديد في Forgejo عنوان مستودع ورمز وصول وينقل معه الفروع والوسوم والمشكلات والتعليقات والتصنيفات والمعالم والإصدارات وطلبات السحب. شغّله على مستودع واحد أولًا لترى شكل النتيجة، وتوقع أن تُبطئ حدود معدل استخدام واجهة برمجة التطبيقات الدفعات الكبيرة، وأبقِ المصدر للقراءة فقط لبضعة أسابيع بدلًا من حذفه في اليوم نفسه.

الخطوة 05 · البناء

مُشغّل التكامل المستمر جهاز يشغّل شيفرة غرباء. ضعه بناءً على ذلك.

تقرأ Forgejo Actions ملفات سير عمل بنفس صيغة GitHub Actions، من .forgejo/workflows/، وتسلّمها إلى برنامج منفصل يُسمى Forgejo Runner. المُشغّل ليس جزءًا من المنصة ولا يتوجب عليه الإقامة على الجهاز نفسه — وهذا هو التصميم بأكمله، ولهذا السبب تأتي هذه الخطوة بتحذير لا بهزّة كتفين.

فعّل Actions على النسخة، ثم احصل على رمز تسجيل من لوحة الإدارة — على مستوى النسخة كاملة، أو محصورًا في مؤسسة واحدة أو مستودع واحد، وهو الخيار الافتراضي الأفضل عندما تكون غير متأكد. يتصل المُشغّل بالمنصة من الداخل إلى الخارج، لذا فهو لا يحتاج إلى أي منافذ واردة على الإطلاق ويمكنه الجلوس خلف أي جدار حماية تريده، بما في ذلك على جهاز بلا عنوان عام.

# In the Compose environment of the forge, or app.ini:
#   FORGEJO__actions__ENABLED: "true"
# Then: Site administration -> Actions -> Runners -> Create new runner

# On the runner machine:
forgejo-runner generate-config > config.yml

forgejo-runner register --no-interactive \
  --instance https://git.example.com \
  --token <REGISTRATION_TOKEN> \
  --name runner-01 \
  --labels docker:docker://node:22-bookworm,debian:docker://debian:12

forgejo-runner --config config.yml daemon

التصنيفات هي العقد بين سير العمل والمُشغّل: مهمة تطلب runs-on: docker تحصل على حاوية مبنية من الصورة المذكورة على الجانب الأيمن. أعلن فقط عن التصنيفات التي أنت مستعد فعلًا لخدمتها، لأن مهمة تطلب تصنيفًا لا يقدّمه أحد تنتظر إلى الأبد بدلًا من أن تفشل، وهو أمر مربك لتصحيحه في نهاية يوم طويل.

.forgejo/workflows/ci.yml

on: [push, pull_request]

jobs:
  test:
    runs-on: docker
    container:
      image: node:22-bookworm
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
القاعدة التي تصنع الفرق

يُنفّذ المُشغّل كل ما يقوله ملف سير العمل، وملف سير العمل يصل عبر طلب سحب. إذا كان بإمكان أي شخص خارج فريقك فتح طلب سحب، فمكان المُشغّل جهاز مختلف عن المنصة — خادم Sentinel ثانٍ بسعر $3.90 شهريًا، بلا وصول إلى دليل بيانات المنصة، وبلا بيانات اعتماد قاعدة بيانات، وبلا أي شيء في بيئته يزعجك أن تراه مطبوعًا في سجل بناء. وعلى المنصة نفسها، اشترط موافقة قبل تشغيل مسارات العمل للمساهمين لأول مرة. الإخفاقان المعتاديان كلاهما مملّان ومكلفان: عبء عمل تعديني مدسوس في طلب سحب، وسرّ تطبعه خطوة أضافها أحدهم عمدًا.

احصر الأسرار بنفس الطريقة. يخزّنها Forgejo على مستوى المستودع والمؤسسة والنسخة؛ ومفتاح نشر يحتاجه مستودع واحد فقط ينبغي أن يوجد في ذلك المستودع فقط، بحيث لا يستطيع سير عمل مخترَق في مشروع غير ذي صلة قراءته. فضّل الرموز قصيرة الأجل على طويلة الأجل حيثما تدعم الوجهة ذلك، ولا تضع سرًا في ملف سير عمل أبدًا — فملف سير العمل موجود في المستودع، والمستودع له تاريخ.

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

الخطوة 06 · الحفظ

كل نسخة مستنسخة هي نسخة احتياطية من الشيفرة. لا شيء هو نسخة احتياطية من الحوار الدائر حولها.

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

أولًا، مرآة دفع. إنها مجانية وتُشغّل نفسها بنفسها. في مستودع: Settings → Mirror settings → أضف مرآة دفع بالعنوان ورمز وصول للوجهة. عندئذ يُكرّر Forgejo كل فرع ووسم بعد كل عملية دفع، إلى Forgejo ثانٍ، أو إلى Codeberg، أو إلى منصة قررت الإبقاء عليها كواجهة عرض لا كموطن رئيسي. تحذير واحد يستحق القول بوضوح: مرآة الدفع تعيد نشر التاريخ بأمانة، بما في ذلك أي سرّ كنت تنوي إزالته.

ثم نسخة احتياطية حقيقية، وهي ليست الأرشيف المدمج. يوفّر Forgejo أمر forgejo dump الذي يحزم الإعدادات والمستودعات والبيانات وتفريغًا لقاعدة البيانات في ملف zip واحد. إنه أمر مفيد فعلًا لتسليمه لمشرف عند الإبلاغ عن عِلّة. لكنه ليس ما ينبغي أن تعتمد عليه للعودة من الموت: فملف SQL الذي ينتجه له مشكلات معروفة منذ زمن طويل عند إعادة الاستيراد، ويعيد الأرشيف كتابة مجموعة المستودعات بأكملها في كل تشغيل، وهو ما يعني على نسخة حقيقية ملفًا كبيرًا يُكتب من الصفر كل ليلة. استخدم بدلًا من ذلك المسار المُمل والقابل للتحقق — فرّغ قاعدة البيانات بأداتها الخاصة، وانسخ دليل البيانات احتياطيًا كملفات:

#!/bin/sh
# /usr/local/bin/forgejo-backup — run from a systemd timer, nightly
set -eu
cd /srv/forgejo

# 1. Consistent database dump, written next to the data.
docker compose exec -T db pg_dump -U forgejo -Fc forgejo > ./db.dump

# 2. Everything that matters, to an encrypted offsite repository.
restic backup ./data ./db.dump ./docker-compose.yml ./.env ./Caddyfile

# 3. Retention, then prove the repository is still readable.
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
restic check

أرسلها إلى جهاز في ولاية قضائية مختلفة عن المنصة، عبر مستودع للإلحاق فقط بحيث لا يستطيع اختراق المنصة محو تاريخه الخاص — دليل النسخ الاحتياطي المشفر هو النسخة المطولة من السطور الثلاثة أعلاه، بما في ذلك مؤقت systemd وقيد المفتاح المخصص للإلحاق فقط.

ثم استعدها مرة واحدة، عن قصد. اطلب خادم VPS تجريبيًا، واستعد اللقطة إليه، وشغّل نفس ملف Compose في مواجهة دليل البيانات المستعاد، وحمّل تفريغ قاعدة البيانات، ووجّه إدخالًا في ملف hosts نحوه وسجّل الدخول. احسب الوقت الذي استغرقه كل ذلك. ذلك الرقم — لا مجرد وجود مهمة النسخ الاحتياطي — هو موقفك الحقيقي في الاستعادة، وكل من قام بهذا التمرين وجد على الأقل شيئًا واحدًا مفقودًا من قائمة التضمين في المرة الأولى.

# restic keeps absolute paths, so the stack reappears under the target.
restic restore latest --target /srv/restore
cd /srv/restore/srv/forgejo

docker compose up -d db                # empty volume: the entrypoint creates the database
docker compose exec -T db pg_restore -U forgejo -d forgejo \
  --clean --if-exists --no-owner < db.dump

docker compose up -d                   # then sign in and walk the issue tracker

الترقيات، باختصار. ثبّت الصورة على إصدار رئيسي بدلًا من :latest، حتى لا يعبر بك سحب تلقائي دون إشراف تغييرًا كاسرًا بينما أنت نائم. اقرأ ملاحظات الإصدار قبل عبور حد رئيسي، وخذ لقطة أولًا، وتذكر أن ترحيل قاعدة البيانات يعمل عند أول بدء تشغيل للإصدار الجديد — وهو باب باتجاه واحد. التحديث التلقائي على طريقة Watchtower فكرة جيدة لموقع ثابت وفكرة سيئة للجهاز الذي يحتفظ بكل فرع تملكه.

أربعة فحوصات قبل أن تعتبر الأمر منتهيًا. سجّل الخروج وتأكد من أن النسخة لا تقدّم أي وسيلة لإنشاء حساب. من متصفح بلا جلسة، تأكد من أن المستودع الخاص غير مرئي لا مجرد ممنوع. تأكد من أن المُشغّل لا يستطيع قراءة دليل بيانات المنصة. وتأكد من نجاح آخر فحص لـ restic — فمهمة النسخ الاحتياطي التي تفشل بصمت هي التي يملكها الجميع، إلى أن يأتي اليوم الذي يحتاجونها فيه.

الجزء الصادق · ما لا يفعله هذا

لقد أزلت طرفًا واحدًا. لم تُزل المبنى.

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

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

يصبح اسم المضيف عامًا بمجرد إصدار الشهادة. تُنشر كل شهادة موثوقة عمومًا في سجلات شفافية الشهادات التي يمكن لأي شخص البحث فيها، لذا فإن git.yourproject.com قابل للاكتشاف حتى لو لم تربطه بشيء أبدًا. ذلك ليس تسريبًا لشيفرتك، لكنه تسريب لحقيقة أن المشروع موجود وتقريبًا متى بدأ. استخدم نطاقًا فرعيًا لاسم تنشره بالفعل، أو تجاوز الشهادة العامة كليًا وصِل إلى المنصة عبر WireGuard أو خدمة onion.

أنت الآن تُرقّع تطبيق ويب. المنصة صفحة تسجيل دخول، وخط عرض لترميز غير موثوق، وخادم SSH، ومحرك تكامل مستمر، وكلها قابلة للوصول من الإنترنت. ذلك سطح أكبر بكثير من المستودع العاري في الخطوة 01، وهو سطح يجب عليك إبقاؤه محدَّثًا. اشترك في إعلانات الإصدارات، وعامل إصدار الأمان كمهمة تُنجز في نفس الأسبوع لا في نفس الربع السنوي.

الاتحاد (federation) لم يصل بعد. يعمل Forgejo فعليًا على اتحاد المنصات وينشر تقدمه في ذلك، لكن حتى اليوم لا يمكنك فتح طلب سحب على نسخة شخص آخر من نسختك الخاصة بالطريقة التي تفعلها على منصة مشتركة. عمليًا، يعني هذا أن المساهم الخارجي ما زال يحتاج إلى حساب على منصتك، أو أنك تقبل الرقع عبر البريد الإلكتروني، أو تحافظ على مرآة عامة للمساهمات العابرة. خطط لأي من الخيارات الثلاثة يناسب مشروعك بدلًا من أن تُفاجأ به.

ما اشتريته فعليًا، بدقة: السجل المؤرَّخ لما تبنيه، ومع من، ومتى، لم تعد تحوزه شركة يشمل نموذج عملها تحليله. هذا ادعاء ضيق، وهو ادعاء حقيقي. لا يستحق تكلفته إلا إذا أُنجزت الخطوة 06 — فمنصة مستضافة ذاتيًا بلا استعادة مُختبرة ليست تحسينًا في الخصوصية، بل نقطة فشل واحدة بعلامة تجارية أفضل.

التحجيم · ما الذي تطلبه

المنصة صغيرة. أما التكامل المستمر فليس كذلك.

الفئة شهرياً الموارد ما يشغّله براحة
Sentinel$3.902 vCPU · 4 GB · 120 GBForgejo + PostgreSQL لشخص واحد أو فريق صغير. البداية الصحيحة.
خادم Sentinel ثانٍ$3.90المُشغّل، على خادمه الخاصالعزل الذي يهم فعلًا، بسعر فنجان قهوة
Garrison$7.904 vCPU · 8 GB · 240 GBمنصة لعشرة أشخاص، سجل حاويات، وأصول ناتجة
Ravelin$16.908 vCPU · 16 GB · 480 GBتكامل مستمر مزدحم، مستودعات كبيرة، عدة مهام متوازية

لا شيء في هذا الجدول محسوب على أساس حجم Git. يبقى Forgejo وPostgreSQL معًا خاملين عند بضع مئات من الميجابايتات؛ وما يملأ الخادم هو التكامل المستمر — طبقات الحاويات، وذاكرات التخزين المؤقت للبناء، والأصول الناتجة — ومحتوى المستودع الذي ليس شيفرة مصدرية. احسب الحجم للقرص أولًا، وللأنوية ثانيًا، وللذاكرة أخيرًا. خادمان صغيران أفضل من خادم كبير واحد هنا، لأن الثاني حد أمني لا سعة إضافية.

ملاحظات ميدانية · ست فخاخ

ست طرق يمكن أن يسوء بها الأمر. اثنتان منها تكلفانك مالًا.

الفخ 01 · صاخب

تسجيل مفتوح، ومنصة مليئة بالغرباء

تظهر الشهادة في سجلات الشفافية، وتتبعها الماسحات الآلية في غضون أيام، وتمتلئ نسخة يكون فيها التسجيل مفعّلًا بحسابات ومستودعات مزعجة. اضبط DISABLE_REGISTRATION قبل أول إقلاع، لا بعد أول حادثة.

الفخ 02 · مكلف

المُشغّل الذي يعدّن عملات مشفرة لشخص آخر

التكامل المستمر الذي يشغّل مسارات عمل من أي طلب سحب هو حوسبة مجانية لمن يعثر عليه. اشترط موافقة للمساهمين لأول مرة، وأبقِ المُشغّل على خادمه الخاص، واقرأ مدد تنفيذ المهام بين الحين والآخر.

الفخ 03 · صامت

ROOT_URL خاطئ، وكل شيء يعمل جزئيًا

تشير عناوين الاستنساخ إلى مضيف خاطئ، وتُطلق الخطافات الشبكية نحو عنوان خاطئ، وتفشل استدعاءات OAuth وتتعطل الصور الرمزية. تبدو الواجهة سليمة، فلا أحد يشك في سطر واحد. اضبط DOMAIN وROOT_URL وSSH_DOMAIN وSSH_PORT معًا وتحقق من عنوان استنساخ في الواجهة.

الفخ 04 · مربك

خادما SSH، ومنفذ واحد

تريد الحاوية المنفذ 22 والمضيف يستخدمه بالفعل، فيهبط التعيين بصمت في مكان غير متوقع ويطلب git push كلمة مرور. انقل SSH الإداري أولًا، وانشر الحاوية على منفذ خاص بها، وتحقق باستخدام ssh -T.

الفخ 05 · قاتل

تفريغ لم تُستعَد منه نسخة قط

الأرشيف المدمج أداة دعم، لا مسار استعادة مُختبر، ولملف SQL الخاص به مشكلات معروفة عند إعادة الاستيراد. فرّغ قاعدة البيانات باستخدام pg_dump، وانسخ دليل البيانات احتياطيًا كملفات، واستعد الأمر كله على خادم تجريبي مرة واحدة.

الفخ 06 · بطيء

يمتلئ القرص بطبقات البناء، لا بالشيفرة

الشيفرة المصدرية صغيرة الحجم؛ أما طبقات الحاويات والأصول الناتجة وذاكرات تخزين التكامل المستمر فليست كذلك. خادم بسعة 120 جيجابايت مع خط أنابيب نشط يمتلئ في غضون أسابيع. احذف الصور القديمة وفق جدول زمني، وحدّد مدة الاحتفاظ بالأصول الناتجة، وراقب القرص بدلًا من المعالج.

الأسئلة الشائعة · استضافة Git الخاصة

أسئلة، أجوبة.

أحد عشر سؤالًا يتكرر طرحها أثناء بناء هذا — بدءًا بالسؤالين اللذين يحددان ما إذا كان ينبغي عليك بناؤه أصلًا.

Forgejo أم Gitea — أيهما يجب أن أثبّت فعلًا؟

Forgejo، بالنسبة لمعظم الناس، والسبب هو الحوكمة لا المزايا. يشترك المشروعان في أصل واحد وما زالا يبدوان متطابقين تقريبًا في الاستخدام: نفس ملف Go الثنائي، ونفس البصمة الخفيفة، ونفس واجهة الويب، وتكامل مستمر متقارب. ما يختلف هو من يوجّه دفة كل منهما. تتبع Forgejo لجمعية Codeberg e.V.، وهي جمعية مسجَّلة غير ربحية في برلين، وأصبحت تفرعًا كاملاً في أوائل 2024؛ وهي تنشر كل شيء كبرمجيات حرة ولا تطلب من المساهمين التنازل عن حقوق الملكية. أما Gitea فتطوّرها شركة هادفة للربح تملك العلامة التجارية والنطاق، وتشترط على المساهمين التنازل عن حقوق الملكية، وتتبع نموذج "النواة المفتوحة" بمزايا مدفوعة حول القاعدة المجانية. لا شيء من هذه الحقائق يجعل Gitea برمجية سيئة. لكن الهدف الكامل من نقل مستودعاتك خارج منصة هو التوقف عن الاعتماد على خارطة طريق شركة ما، فاختيار التفرع الذي يشرف عليه كيان غير ربحي هو الخيار الذي يتوافق مع سبب وجودك هنا أصلًا. ملاحظة عملية إن كنت ستنتقل لاحقًا: يمكن تثبيت Forgejo فوق دليل بيانات Gitea قائم، أما الاتجاه المعاكس فغير مدعوم.

هل أحتاج أصلًا إلى منصة؟ أليس المستودع العاري عبر SSH كافيًا؟

بالنسبة لشخص واحد بحاسوب محمول واحد وعادة كتابة رسائل التزام جيدة، فإن المستودع العاري كافٍ فعلًا، وهو أكثر شيء متينًا في هذا الدليل: أمر git init --bare على الخادم، وحساب SSH عادي، ولا يوجد تطبيق ويب يحتاج إلى ترقيع، ولا قاعدة بيانات تحتاج إلى نسخ احتياطي، ولا سطح هجوم يتجاوز sshd. لن يصل هذا الإعداد أبدًا إلى نهاية الدعم. تحتاج إلى منصة في اللحظة التي ينضم فيها شخص ثانٍ، أو في اللحظة التي تريد فيها أيًا من الأمور الأربعة التي لا يعرف المستودع العاري عنها شيئًا — تاريخ يمكن تصفحه، وطلبات سحب مع مراجعة، ومتتبع مشكلات يعيش بجانب الشيفرة، وتحكم في الوصول لكل مستودع على حدة. هذه ليست خطوة صغيرة إلى الأعلى؛ إنها الفرق بين التخزين والتعاون. كن صادقًا بشأن أي منهما تحل له المشكلة، لأن المنصة خدمة تُشغّلها أنت الآن، بينما المستودع العاري ليس سوى دليل.

هل يمكنني ترحيل مستودعاتي من GitHub، بما في ذلك المشكلات وطلبات السحب؟

نعم، وهي واحدة من أفضل قصص الترحيل في عالم الاستضافة الذاتية. تأخذ أداة الترحيل المدمجة في Forgejo عنوان مستودع ورمز وصول شخصي وتسحب أكثر بكثير من مجرد الشيفرة: الفروع والوسوم، والمشكلات بتعليقاتها، وطلبات السحب، والتصنيفات، والمعالم، والإصدارات. زوّدها برمز بنطاق قراءة فقط، وشغّلها على مستودع واحد أولًا لترى كيف تبدو النتيجة، ثم تابع بقية المستودعات. توقع ثلاثة أمور. الترحيلات الكبيرة أو الكثيرة ستصطدم بحدود معدل استخدام واجهة برمجة التطبيقات في المنصة المصدر وستستغرق وقتًا أطول فحسب — ابدأها واتركها تعمل. تُجلب المرفقات في المشكلات عبر الشبكة، لذا فإن أي نسخة خلف جدار حماية صارم للاتصالات الصادرة ستنتج مشكلات بصور معطوبة. وخيوط المراجعة لا تحطّ دائمًا في مكانها بالضبط، لأن نموذجي البيانات ليسا متطابقين. خطّط للإبقاء على المستودعات المصدر للقراءة فقط لبضعة أسابيع بدلًا من حذفها في العصر نفسه.

هل المنصة المستضافة ذاتيًا أكثر خصوصية فعلًا، أم أنها مختلفة فقط؟

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

ما الحجم الذي يحتاجه VPS؟

أصغر مما دربتنا وثائق GitLab على توقعه. Forgejo وGitea كل منهما ملف Go ثنائي واحد يبقى خاملًا عند بضع مئات من الميجابايتات من الذاكرة؛ أضف PostgreSQL ووكيلًا عكسيًا وستجد منصة مطوّر منفرد تجلس بارتياح في فئة Sentinel — 2 معالج افتراضي، 4 جيجابايت، 120 جيجابايت NVMe، بسعر $3.90 شهريًا — مع مساحة فائضة. يأتي الضغط الحقيقي من ثلاثة مصادر أخرى، ويستحق كل منها تحجيمًا مقصودًا. التكامل المستمر هو الأكبر: فالمُشغّل الذي يبني حاويات سيستخدم كل نواة تمنحها له ويملأ القرص بطبقات الصور. حجم المستودع هو الثاني: أصول الألعاب والدفاتر التفاعلية والاعتماديات المرفقة تنمو أسرع بكثير من الشيفرة المصدرية. الأصول الناتجة والسجل الخاص بالحاويات هما الثالث. القاعدة التي أثبتت جدواها عمليًا — ضع المنصة على Sentinel، وضع المُشغّل على Sentinel ثانٍ خاص به، ولا ترتقِ بالفئة إلا حين يخبرك القرص بذلك لا حين تخبرك المعالجات.

هل Forgejo Actions متوافق فعلًا مع مسارات عمل GitHub Actions الخاصة بي؟

متوافق بما يكفي لتشغيل معظم مسارات العمل المباشرة دون تعديل، لكنه ليس متوافقًا لدرجة أن تُرحّل خط أنابيب معقدًا دون قراءته. صيغة ملف سير العمل هي نفسها، ويوجد في .forgejo/workflows/ (كما تُقرأ .github/workflows/ أيضًا)، واللبنات المشتركة — الخروج (checkout)، وإعداد اللغة، والتخزين المؤقت، وعمليات البناء المصفوفية — تتصرف كما تتوقع لأن المُشغّل ينفذها داخل حاويات بالطريقة نفسها. ما ينكسر هو أي شيء يفترض وجود GitHub كمنصة لا Actions كصيغة: إجراءات من المتجر مثبّتة على عناوين github.com يجب السماح لنسختك بجلبها، وإجراءات تستدعي واجهة GitHub REST API لبيانات الإصدار أو طلب السحب، وصور مُشغّلات مستضافة على GitHub بمجموعة أدوات مثبّتة مسبقًا محددة جدًا، ومصادقة سحابية قائمة على OIDC. نمط الترحيل الذي ينجح: ابدأ بسير عمل يقتصر على البناء والاختبار، واجعله يعمل بنجاح، ثم أعد إضافة خطوات النشر واحدة تلو الأخرى.

ماذا يحدث لشيفرتي إذا تعطّل خادم VPS؟

الشيفرة نفسها هي الجزء الوحيد الذي يبقى بخير، وهذه هي الميزة الهادئة لـ Git مقارنة بكل خدمة أخرى مستضافة ذاتيًا تقريبًا: كل نسخة مستنسخة هي نسخة كاملة من التاريخ، فطالما أن مطورًا واحدًا لديه نسخة عمل حديثة، فإن المستودع لا يُفقد. ما يزول مع الخادم هو كل ما يحيط بالشيفرة — المشكلات، ونقاشات طلبات السحب، وتعليقات المراجعة، والإصدارات، والويكي، والمستخدمون، وقواعد الوصول، وتاريخ التكامل المستمر. تلك المواد لا توجد إلا في قاعدة البيانات، ولا يملك أحد نسخة منها، وهي عادة الجزء الذي استغرق سنوات ليتراكم. لذا عامل الاثنين بشكل مختلف. بالنسبة للشيفرة، اضبط مرآة دفع إلى موقع ثانٍ وستحصل على حماية مستمرة وتلقائية خارج الموقع دون أي جهد. أما بالنسبة للبيانات الوصفية، فأنت بحاجة إلى نسخة احتياطية حقيقية: تفريغ لقاعدة بيانات PostgreSQL إضافة إلى دليل البيانات، مشفّرة ومُرسلة إلى جهاز في ولاية قضائية أخرى وفق جدول زمني. تغطي الخطوة 06 كلا الأمرين، وتمرين الاستعادة في النهاية هو ما يحوّلهما من نية إلى ضمان.

هل يمكنني الإبقاء على GitHub كمرآة بدلًا من مغادرته كليًا؟

نعم، وبالنسبة للكثير من المشاريع فهذا هو الجواب الصحيح لا مجرد حل وسط. يدعم Forgejo مرايا الدفع، بحيث تكون نسختك هي المصدر الذي يعمل عليه فريقك ويُنسخ كل دفع تلقائيًا إلى مستودع على GitHub أو Codeberg أو نسخة Forgejo ثانية. تستمر الرؤية العامة، والمساهمون العابرون، وسجلات الحزم التي تتوقع عنوان GitHub، ورابط متتبع المشكلات في ملف README قديم في العمل جميعًا، بينما يبقى مصدر الحقيقة — والمستودعات الخاصة، وسجلات التكامل المستمر، وتاريخ المشكلات لكل ما لا تنشره — على خادمك. يعمل الأمر أيضًا في الاتجاه المعاكس: تحافظ مرايا السحب على نسخة محلية محدّثة دائمًا من المشاريع المصدر التي تعتمد عليها، وهذا يستحق القيام به لأي شيء ستتعطل بدونه لو حُذف غدًا. الأمر الوحيد الذي يجب التعامل معه بحذر هو ماذا تُزامن عبر المرآة: فمرآة دفع لمستودع يحتوي تاريخه على سرّ كنت تنوي إزالته تعيد نشر ذلك السرّ فورًا وتلقائيًا.

كيف أمنح مقاولًا صلاحية الوصول إلى مستودع واحد دون منحه الوصول إلى البقية؟

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

هل تحتاج المنصة إلى اسم نطاق، وهل يكشف ذلك عن هويتي؟

إنها تحتاج إلى اسم مضيف لواجهة الويب، لأن شهادات TLS تُصدر لأسماء ولا ينبغي لأي متصفح أن يثق بعنوان IP هنا. لكنها لا تحتاج إلى أن يكون ذلك الاسم قابلًا لتعقبه إليك. ثلاثة أمور يجب التعامل معها بحذر. سجّل النطاق في مكان لا يطلب الهوية التي حرصت على حمايتها في مكان آخر، وأبقِ خصوصية WHOIS مفعّلة — فمسجّل النطاق قرار ثقة منفصل عن قرار المضيف، وهو الأمر الذي ينساه الناس. توقع أن يصبح اسم المضيف عامًا بمجرد إصدار الشهادة، لأن كل شهادة موثوقة عمومًا تُنشر في سجلات شفافية الشهادات التي يمكن لأي شخص البحث فيها؛ واستخدام نطاق عام (wildcard) على اسم تستخدمه بالفعل يتجنب إضافة اسم جديد قابل للبحث. وإذا كنت تفضل ألا يكون لديك اسم عام على الإطلاق، فالبديل حقيقي: ضع المنصة على خدمة onion عبر Tor أو اجعلها قابلة للوصول فقط عبر WireGuard، وتجاوز الشهادة العامة كليًا، وتقبّل أن راحة فتح متصفح من أي مكان ستُفقد مقابل ذلك.

هل يمانع NordBastion إذا شغّلت منصة Git ومُشغّلات تكامل مستمر على خادم VPS؟

على الإطلاق لا — فالمنصة ومُشغّلاتها عبء عمل عادي، وهي من الأشياء الأكثر شيوعًا التي يبنيها عملاؤنا. لا تذكر سياسة الاستخدام المقبول أي شيء بخصوص استضافة الشيفرة المصدرية أو بنائها. ملاحظتان تشغيليتان لا سياسيتان. أولًا، مُشغّل تكامل مستمر يقبل مسارات عمل من غرباء هو خدمة حوسبة مجانية لمن يعثر عليه: والإساءة المعتادة هي تعدين العملات المشفرة داخل طلب سحب، وسيُكتشف ذلك في غضون أيام من فتحه. أبقِ التسجيل مغلقًا، واشترط موافقة قبل تشغيل مسارات العمل لأي شخص ليس متعاونًا بالفعل. ثانيًا، إذا كانت عمليات البناء لديك تسحب صورًا كبيرة للحاويات في كل مرة تشغيل، فذلك حركة بيانات عادية وهي مشمولة — لكن يستحق تخزينها مؤقتًا محليًا على أي حال، لأن ذلك يجعل خط الأنابيب لديك أسرع وهو التصرف اللائق تجاه سجلات الحاويات المصدر التي تعتمد عليها.

احصل على الخادم

منصة خاصة بك، على حساب ليس باسمك. بدون KYC، مدفوعة بالعملات المشفرة.

Sentinel — معالجان افتراضيان و4 جيجابايت بسعر $3.90 شهريًا، في هلسنكي أو ستوكهولم أو أوسلو أو ريكيافيك. يكفي لـ Forgejo وPostgreSQL والوكيل العكسي، مع مساحة للمستودعات التي كنت تنوي نقلها. أضف واحدًا ثانيًا للمُشغّل. بلا بريد إلكتروني عند التسجيل، وبلا وثيقة هوية، وبلا فهرس على مستوى المنتج لأي شيء تدفعه.

آخر مراجعة · 2026-10-12 · المصادر · وثائق مسؤول Forgejo (التثبيت وActions وسطر الأوامر)، ومقارنة Forgejo مع Gitea، وصفحات حوكمة Codeberg e.V.، ووثائق PostgreSQL وCaddy، وgit-config(1) · الدورية · سنوياً

استضافة خاصة، مبنية في الشمال.