تخطى إلى المحتوى الرئيسي

كيف تحول حاسوبك القديم إلى خادم سحابي Home Server باستخدام Docker؟

فريق جليتش نيوز
6 أكتوبر6 مشاهدة45 دقائق
كيف تحول حاسوبك القديم إلى خادم سحابي Home Server باستخدام Docker؟

هل لديك حاسوب قديم يجمع الغبار في المنزل؟ بدلًا من ترك القرص الصلب بداخله بلا استخدام، يمكنك تحويله إلى خادم منزلي يوفر لك مساحة تخزين خاصة تصل إليها من أجهزتك المختلفة، دون دفع اشتراك شهري لخدمات التخزين السحابي. في هذا الدليل سنبني Home Server بسيطًا باستخدام Ubuntu + Docker + Nextcloud، بحيث تحصل في النهاية على سحابة شخصية شبيهة بـ Google Drive أو OneDrive، ولكن البيانات تكون مخزنة على جهازك.

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

ماذا سنبني؟

المخطط النهائي سيكون بسيطًا:

الحاسوب القديم → Ubuntu → Docker → Nextcloud → ملفاتك

وسيكون بإمكانك:

  • رفع الملفات وتنزيلها.
  • إنشاء مجلدات وتنظيمها.
  • الوصول إلى الملفات من الهاتف والكمبيوتر.
  • مشاركة الملفات.
  • مزامنة مجلدات محددة.
  • الاحتفاظ ببياناتك على قرصك بدلًا من خدمة تخزين مدفوعة.

والأهم أن Docker سيجعل تشغيل Nextcloud وإدارته أسهل، بدل تثبيت كل مكون يدويًا على نظام التشغيل.

1. هل جهازك القديم مناسب؟

لا تحتاج إلى جهاز قوي جدًا لهذا المشروع.

للاستخدام الشخصي، جهاز قديم بمعالج 64-bit وذاكرة RAM مناسبة يمكن أن يكون كافيًا، خصوصًا إذا كان الاستخدام الأساسي هو تخزين الملفات.

لكن هناك فرق مهم:

إذا كان الجهاز يحتوي على SSD، استخدمه لنظام التشغيل وDocker.

أما ملفاتك الكبيرة، فيمكن تخزينها على HDD إضافي.

مثال عملي:


SSD 120GB
├── Ubuntu
├── Docker
└── Nextcloud

HDD 2TB
└── ملفات المستخدمين

ولا تحتاج إلى بطاقة رسومية لهذا المشروع.

2. لماذا Ubuntu بدل Windows؟

يمكن تشغيل Docker على Windows، لكن إذا كان هدفك تحويل الجهاز إلى خادم يعمل 24/7، فأنا أفضل Linux.

السبب بسيط:

  • استهلاك موارد أقل.
  • إدارة أسهل عن طريق SSH.
  • مناسب أكثر للخوادم.
  • Docker Engine يعمل بشكل مباشر.
  • لا تحتاج إلى تشغيل واجهة رسومية باستمرار.

سنستخدم Ubuntu 24.04 LTS في هذا الدليل.

Docker يدعم حاليًا Ubuntu 24.04 LTS رسميًا، إلى جانب إصدارات Ubuntu الأخرى المدعومة.

3. ثبّت Ubuntu على الجهاز القديم

قم بتثبيت Ubuntu 24.04 LTS على الجهاز.

أثناء التثبيت، إذا كان الجهاز سيستخدم كخادم فقط، فلا تحتاج إلى تثبيت بيئة سطح المكتب الكاملة.

يمكنك اختيار إعداد خادم بسيط ثم إدارة الجهاز من جهاز آخر باستخدام SSH.

بعد انتهاء التثبيت، حدّث النظام:


sudo apt update
sudo apt upgrade -y

ثم أعد تشغيل الجهاز:


sudo reboot

بعد عودة الجهاز، أصبح لدينا نظام تشغيل نظيف يمكن بناء الخادم فوقه.

4. أعطِ الخادم عنوان IP ثابتًا

هذه خطوة مهمة جدًا.

لنفرض أن الراوتر أعطى جهاز الخادم العنوان:


192.168.1.50

لا نريد أن يتغير هذا العنوان غدًا إلى:


192.168.1.72

لذلك الأفضل أن تدخل إلى إعدادات الراوتر وتعمل DHCP Reservation للجهاز.

مثال:


Home Server
IP: 192.168.1.50

بهذه الطريقة سيحصل الجهاز على نفس العنوان داخل الشبكة.

5. تثبيت Docker

هنا سنستخدم الطريقة الرسمية لتثبيت Docker Engine.

أولًا:


sudo apt update
sudo apt install ca-certificates curl -y

أنشئ مجلد مفاتيح Docker:


sudo install -m 0755 -d /etc/apt/keyrings

ثم أضف مفتاح Docker الرسمي:


sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc

واجعل المفتاح قابلًا للقراءة:


sudo chmod a+r /etc/apt/keyrings/docker.asc

ثم أضف مستودع Docker:


sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

حدّث المستودعات:


sudo apt update

ثم ثبّت Docker والـ Compose:


sudo apt install docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin -y

هذه هي الحزم التي توصي بها وثائق Docker الرسمية للتثبيت عبر مستودع Ubuntu.

6. تأكد من أن Docker يعمل

نفّذ:


sudo systemctl status docker

إذا كان كل شيء صحيحًا، يجب أن ترى أن الخدمة تعمل.

ثم اختبر Docker:


sudo docker run hello-world

إذا ظهرت رسالة الترحيب، فـ Docker يعمل بشكل صحيح.

7. اجعل Docker يعمل بدون sudo

لتسهيل إدارة الخادم، أضف المستخدم الحالي إلى مجموعة Docker:


sudo usermod -aG docker $USER

بعد ذلك سجّل الخروج ثم ادخل مرة أخرى.

اختبر:


docker ps

إذا عمل الأمر بدون sudo، فأنت جاهز.

8. لماذا نستخدم Docker Compose؟

بدل تشغيل كل Container بأوامر منفصلة، سنستخدم ملفًا واحدًا يسمى:


compose.yaml

يحتوي على الخدمات التي نريد تشغيلها وإعداداتها.

وبعد ذلك يكفي تنفيذ:


docker compose up -d

لتشغيل النظام بالكامل.

هذه إحدى نقاط قوة Docker Compose: يمكنك تعريف الخدمات والشبكات والتخزين في ملف واحد وإدارة المجموعة بأكملها من خلاله.

9. إنشاء مشروع الخادم

أنشئ مجلد المشروع:


mkdir -p ~/home-server
cd ~/home-server

سنضع داخله إعدادات الخدمات:


home-server/
├── compose.yaml
└── data/

أنشئ مجلد البيانات:


mkdir -p data

10. تشغيل Nextcloud

الآن نصل إلى الجزء المهم.

سنستخدم Nextcloud كواجهة السحابة الشخصية.

لكن هناك نقطة مهمة جدًا:

لا أنصح بتشغيل Nextcloud مع قاعدة بيانات داخل Container بدون تخزين دائم.

لأن الـ Container نفسه قابل للحذف والاستبدال.

Docker يوضح أن البيانات المكتوبة داخل الطبقة القابلة للكتابة الخاصة بالـ Container لا ينبغي الاعتماد عليها كآلية تخزين دائمة؛ لذلك نستخدم Volumes أو Bind Mounts للبيانات التي نريد الاحتفاظ بها.

سنجهز لذلك تخزينًا دائمًا.

أنشئ ملف:


nano compose.yaml

ثم ضع فيه:


services:

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped

    ports:
      - "8080:80"

    volumes:
      - ./data/nextcloud:/var/www/html

    depends_on:
      - db

  db:
    image: mariadb:11
    container_name: nextcloud-db
    restart: unless-stopped

    environment:
      MYSQL_ROOT_PASSWORD: CHANGE_THIS_ROOT_PASSWORD
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD

    volumes:
      - ./data/db:/var/lib/mysql

لا تستخدم كلمات المرور الموجودة في المثال كما هي.

غيّر:


CHANGE_THIS_ROOT_PASSWORD

و:


CHANGE_THIS_DATABASE_PASSWORD

إلى كلمات مرور قوية.

11. تشغيل الخادم

احفظ الملف ثم نفّذ:


docker compose up -d

تحقق من الحاويات:


docker compose ps

يجب أن ترى:


nextcloud
nextcloud-db

وتكون حالتهما:


Up

إذا أردت مشاهدة السجلات:


docker compose logs -f

وللخروج من عرض السجلات:


CTRL + C

لن تتوقف الحاويات عند الضغط على CTRL + C إذا كنت شغلتها باستخدام:


docker compose up -d

12. افتح Nextcloud

من أي جهاز داخل نفس الشبكة، افتح المتصفح:


http://192.168.1.50:8080

استبدل:


192.168.1.50

بعنوان IP الخاص بخادمك.

ستظهر لك شاشة إعداد Nextcloud.

اختر:

اسم المستخدم

و:

كلمة مرور قوية

ثم إعداد قاعدة البيانات:


Database user:
nextcloud

Database password:
كلمة المرور التي وضعتها في compose.yaml

Database name:
nextcloud

Database host:
db

لاحظ شيئًا مهمًا:

لا تكتب:


localhost

في خانة Database Host.

نحن نستخدم Docker Network، ولذلك اسم الخدمة:


db

هو عنوان قاعدة البيانات من داخل شبكة Docker.

13. الآن أصبح لديك Cloud خاص بك

بعد إتمام الإعداد، يمكنك تسجيل الدخول إلى:


http://192.168.1.50:8080

وستجد واجهة Nextcloud.

يمكنك الآن:

📁 إنشاء مجلدات.

⬆️ رفع الملفات.

⬇️ تنزيل الملفات.

🔗 مشاركة الملفات.

📱 الوصول إليها من الهاتف.

💻 مزامنة الملفات مع الكمبيوتر.

وهنا يبدأ الجهاز القديم فعليًا في أداء وظيفة تشبه Google Drive، ولكن التخزين موجود على جهازك.

⚠️ لكن لا تفعل هذه الخطوة بعد

قد تفكر الآن:

ممتاز، سأفتح المنفذ 8080 في الراوتر وأصل إلى الملفات من الإنترنت.

لا تفعل ذلك.

فتح Nextcloud مباشرة على الإنترنت بهذه الطريقة ليس التصميم الذي أوصي به.

أنت الآن لديك خدمة تحتوي على ملفات شخصية، وبالتالي يجب أن نفصل بين:

الوصول المحلي

و

الوصول الآمن من الإنترنت.

في الجزء التالي من الدليل سنضيف:


Internet
   ↓
HTTPS
   ↓
Reverse Proxy
   ↓
Nextcloud
   ↓
Database

وسنحتاج أيضًا إلى التفكير في:

  • اسم نطاق Domain.
  • HTTPS وشهادة TLS.
  • الوصول من الهاتف خارج المنزل.
  • DDNS إذا كان عنوان الإنترنت متغيرًا.
  • حماية الراوتر.
  • النسخ الاحتياطي.
  • ماذا يحدث إذا انقطع الإنترنت.
  • ماذا يحدث إذا مات القرص الصلب.

وهذه النقطة بالذات هي التي تحول المشروع من "جهاز قديم يشغل Docker" إلى Home Server يمكن الاعتماد عليه فعليًا.

الخلاصة حتى الآن

إذا نفذت الخطوات السابقة، أصبح لديك:


[Old PC]
    │
    ├── Ubuntu
    │
    └── Docker
          │
          ├── Nextcloud
          │
          └── MariaDB
                 │
                 └── Persistent Storage

المرحلة التالية التي أنصح أن نبنيها في المقال:

تأمين الوصول من الإنترنت باستخدام Cloudflare Tunnel بدل فتح منافذ الراوتر مباشرة؛ هذا أبسط وأقل خطورة للمستخدم المنزلي، وسنجعل الوصول مثل:

https://cloud.example.com

بدل:


http://IP:8080

13. الوصول إلى السحابة من الإنترنت بأمان

حتى الآن يعمل Nextcloud داخل الشبكة المنزلية:


http://192.168.1.50:8080

لكن هذا العنوان لن يعمل عندما تكون خارج المنزل.

هناك طرق كثيرة لفتح الخادم على الإنترنت، لكننا لن نفتح منفذ 80 أو 443 في الراوتر.

بدلًا من ذلك سنستخدم Cloudflare Tunnel.

الفكرة:


الهاتف / الكمبيوتر
        ↓
https://cloud.example.com
        ↓
Cloudflare
        ↓
Encrypted Tunnel
        ↓
cloudflared
        ↓
Docker Network
        ↓
Nextcloud

ميزة هذا الأسلوب أن الاتصال من الخادم إلى Cloudflare يكون اتصالًا صادرًا، وبالتالي لا تحتاج إلى فتح منفذ وارد في الراوتر.


14. ما الذي تحتاجه؟

قبل البدء تحتاج إلى:


  1. حساب Cloudflare.
  2. Domain تمتلكه.
  3. أن يكون الـ Domain مضافًا إلى Cloudflare.
  4. أن يكون الخادم متصلًا بالإنترنت.

لا تحتاج إلى IP ثابت من مزود الإنترنت.

ولا تحتاج إلى DDNS عند استخدام Cloudflare Tunnel.

إذا كان لديك مثلًا:


example.com

سنستخدم:


cloud.example.com

للوصول إلى Nextcloud.


15. إنشاء Cloudflare Tunnel

ادخل إلى لوحة Cloudflare.

اذهب إلى:

Networking → Tunnels

ثم اختر:

Create a tunnel

اختر:

Cloudflared

وأعطِ الـ Tunnel اسمًا واضحًا، مثل:


home-server

ثم أنشئ الـ Tunnel.

Cloudflare يوفر حاليًا طريقة لإنشاء Tunnel مُدار عن بُعد والحصول على Tunnel Token لتشغيل cloudflared.

بعد إنشاء الـ Tunnel، ستجد أمر تشغيل يحتوي على Token يبدأ عادةً بـ:


eyJ...

لا تنشر هذا الـ Token في مقال أو GitHub أو لقطة شاشة.

امتلاك هذا الـ Token يسمح بتشغيل Tunnel الخاص بك، لذلك اعتبره كلمة مرور. Cloudflare نفسها توصي بتدوير الـ Tokens دوريًا عند الحاجة.


16. لا تشغّل أمر Cloudflare الذي يعطيك إياه الموقع كما هو

Cloudflare قد يعرض لك أمرًا مثل:


docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token YOUR_TOKEN

هذا صالح لتشغيل Tunnel، لكننا نريد إدارة كل شيء من خلال Docker Compose.

لذلك سنضع cloudflared داخل ملف compose.yaml الموجود لدينا.

لكن قبل ذلك نحتاج إلى تعديل الشبكة.


17. إنشاء شبكة Docker مخصصة

اذهب إلى مجلد المشروع:


cd ~/home-server

افتح ملف Compose:


nano compose.yaml

استبدل محتوى الملف بالكامل بالنسخة التالية:


services:

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped

    ports:
      - "8080:80"

    environment:
      - APACHE_DISABLE_REWRITE_IP=1
      - TRUSTED_PROXIES=172.20.0.0/16
      - FORWARDED_FOR_HEADERS=HTTP_X_FORWARDED_FOR

    volumes:
      - ./data/nextcloud:/var/www/html

    depends_on:
      - db

    networks:
      - homecloud


  db:
    image: mariadb:11
    container_name: nextcloud-db
    restart: unless-stopped

    environment:
      MYSQL_ROOT_PASSWORD: CHANGE_THIS_ROOT_PASSWORD
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD

    volumes:
      - ./data/db:/var/lib/mysql

    networks:
      - homecloud


  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped

    command:
      - tunnel
      - --no-autoupdate
      - run
      - --token
      - ${TUNNEL_TOKEN}

    networks:
      - homecloud


networks:
  homecloud:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

لماذا أضفنا هذه الإعدادات؟

لأن cloudflared أصبح داخل نفس شبكة Docker التي يوجد فيها Nextcloud.

وبالتالي يستطيع الوصول إليه باستخدام:


http://nextcloud:80

وليس:


http://localhost:8080

وهذه نقطة مهمة جدًا.

داخل حاوية cloudflared:


localhost

يعني حاوية cloudflared نفسها، وليس جهاز Ubuntu وليس حاوية Nextcloud.


18. ضع الـ Tunnel Token في ملف منفصل

لا أنصح بوضع الـ Token مباشرة داخل compose.yaml.

أنشئ ملف:


nano .env

ضع فيه:


TUNNEL_TOKEN=ضع_التوكن_الذي_أعطاك_إياه_Cloudflare_هنا

مثال شكلي فقط:


TUNNEL_TOKEN=eyJxxxxxxxxxxxxxxxxxxxxxxxx

ثم احفظ الملف.

أعطِ الملف صلاحيات مناسبة:


chmod 600 .env

والآن أصبح لدينا:


home-server/
├── compose.yaml
├── .env
└── data/
    ├── nextcloud/
    └── db/

19. تأكد من إعدادات Docker قبل تشغيلها

هذه خطوة أريد منك ألا تتجاوزها.

نفّذ:


docker compose config

إذا كانت الصياغة صحيحة، سيعرض Docker الـ configuration النهائي.

إذا ظهر:


yaml: ...

أو أي خطأ، توقف هنا ولا تنفذ up.

إذا لم يظهر خطأ في الصياغة، ننتقل للخطوة التالية.


20. إعادة تشغيل الخدمات

نفّذ:


docker compose up -d

ثم:


docker compose ps

المفترض أن ترى الخدمات الثلاث:


nextcloud
nextcloud-db
cloudflared

وحالتها:


Up

إذا أردت التأكد من Tunnel تحديدًا:


docker logs cloudflared

ابحث عن رسالة تشير إلى أن الـ Tunnel أصبح متصلًا.

يمكنك أيضًا:


docker logs cloudflared --tail 50

لعرض آخر 50 سطرًا فقط.


21. اختبار الاتصال بين Cloudflare وNextcloud

قبل أن نربط الـ Domain، نختبر أن cloudflared يستطيع الوصول إلى Nextcloud.

نفّذ:


docker exec cloudflared wget -qO- http://nextcloud:80/status.php

المفترض أن تحصل على JSON قريب من:


{
  "installed": true,
  "maintenance": false,
  "needsDbUpgrade": false
}

إذا ظهر هذا، فهذا يعني أن:


cloudflared
     ↓
Docker Network
     ↓
Nextcloud

يعمل بشكل صحيح.


22. ربط الـ Domain بـ Nextcloud

ارجع إلى Cloudflare Dashboard.

افتح الـ Tunnel الذي أنشأناه.

اذهب إلى:

Routes → Add route → Published application

ثم:


Hostname

اختر الـ Domain الخاص بك واكتب:


cloud

بحيث يصبح:


cloud.example.com

Service

اكتب:


http://nextcloud:80

وليس:


http://localhost:8080

وليس:


http://192.168.1.50:8080

لأن cloudflared يتصل بـ Nextcloud من داخل شبكة Docker.

Cloudflare يعرّف الـ Published Application كربط بين hostname عام وخدمة داخلية، ويمكن أن تكون الخدمة مثل http://localhost:8080 عندما يكون الطرفان على نفس الـ host؛ في حالتنا نحن نستفيد من شبكة Docker، لذلك يكون اسم الخدمة nextcloud:80 هو العنوان الصحيح من داخل الـ network.

23. لا تفتح أي Port في الراوتر

هذه النقطة يجب أن تكون واضحة في المقال.

لا تعمل Port Forwarding لـ:


80
443
8080

Cloudflare Tunnel مصمم للعمل بدون فتح منافذ inbound على الخادم.

اتصال الخادم سيكون:


Home Server
     │
     │ outbound
     ↓
Cloudflare

وليس:


Internet
     │
     │ inbound
     ↓
Home Router
     ↓
Home Server

وهذا يقلل سطح التعرض للخادم بشكل كبير.


24. إضافة الـ Domain إلى Nextcloud

هناك خطوة أخرى مهمة.

Nextcloud لديه حماية تسمى:


trusted_domains

وهي تحدد أسماء النطاقات المسموح باستخدامها للوصول إلى الخادم. إذا لم تضف cloud.example.com، فقد تحصل على:

Access through untrusted domain

وثائق Nextcloud توضح أن كل hostname مستخدم للوصول إلى الخادم يجب أن يكون موجودًا في trusted_domains.

نفّذ:


docker exec --user www-data nextcloud php occ config:system:set trusted_domains 1 --value=cloud.example.com

استبدل:


cloud.example.com

بالـ Domain الحقيقي.

ثم تحقق:


docker exec --user www-data nextcloud php occ config:system:get trusted_domains

يجب أن ترى عنوان الـ Domain ضمن القائمة.


25. أخبر Nextcloud أن الاتصال الخارجي HTTPS

هنا توجد نقطة مهمة جدًا.

المستخدم يتصل:


https://cloud.example.com

لكن Cloudflare Tunnel يرسل الطلب داخليًا إلى:


http://nextcloud:80

لذلك Nextcloud قد يعتقد أن المستخدم يستخدم HTTP.

وهذا قد يؤدي إلى:


  • Redirect خاطئ.
  • روابط HTTP بدل HTTPS.
  • تحذيرات أمنية.
  • مشاكل في بعض الـ cookies.

Nextcloud يوفر overwriteprotocol تحديدًا لهذه الحالات.

نفّذ:


docker exec --user www-data nextcloud php occ config:system:set overwriteprotocol --value=https

ثم:


docker exec --user www-data nextcloud php occ config:system:set overwrite.cli.url --value=https://cloud.example.com

واستبدل الـ Domain بالطبع.


26. ضبط الـ Reverse Proxy بشكل صحيح

نحن أضفنا:


TRUSTED_PROXIES=172.20.0.0/16

لأن cloudflared موجود داخل الشبكة:


172.20.0.0/16

ووضعنا:


FORWARDED_FOR_HEADERS=HTTP_X_FORWARDED_FOR

حتى يستطيع Nextcloud التعامل مع عنوان العميل الذي يصل عبر الـ proxy.

وثائق Nextcloud تحذر تحديدًا من أن إعداد trusted_proxies بشكل خاطئ يمكن أن يسمح بتزييف عناوين IP، ولذلك لا ينبغي استخدام 0.0.0.0/0 أو فتح الثقة لأي Proxy عشوائي.


27. اختبار الموقع من خارج المنزل

الآن افتح من هاتفك باستخدام بيانات الهاتف وليس Wi-Fi المنزل:


https://cloud.example.com

إذا ظهرت صفحة تسجيل دخول Nextcloud، فقد نجح الجزء الأصعب.

اختبر:


  1. تسجيل الدخول.
  2. رفع ملف صغير.
  3. تنزيل الملف.
  4. إنشاء مجلد.
  5. مشاركة ملف.
  6. فتح الرابط من جهاز آخر.

28. اختبار HTTPS

يجب أن يكون العنوان:


https://cloud.example.com

وليس:


http://cloud.example.com

ولا تحتاج إلى تركيب شهادة SSL يدويًا داخل Nextcloud في هذا التصميم؛ Cloudflare يتولى اتصال HTTPS من المستخدم إلى Cloudflare، بينما Tunnel ينقل الطلب إلى الخدمة الداخلية. إعداد overwriteprotocol=https يجعل Nextcloud يولّد الروابط باعتبار الاتصال الخارجي HTTPS.

29. ماذا لو ظهر "Access through untrusted domain"؟

تحقق من:


docker exec --user www-data nextcloud php occ config:system:get trusted_domains

إذا لم تجد:


cloud.example.com

أضفه:


docker exec --user www-data nextcloud php occ config:system:set trusted_domains 1 --value=cloud.example.com

ثم أعد تحميل الصفحة.


30. ماذا لو حدث Redirect لا نهائي؟

تحقق من:


docker exec --user www-data nextcloud php occ config:system:get overwriteprotocol

يجب أن تكون النتيجة:


https

وتحقق أيضًا:


docker exec --user www-data nextcloud php occ config:system:get overwrite.cli.url

يجب أن تكون:


https://cloud.example.com

هذا الإعداد مهم لأن Nextcloud قد لا يستطيع اكتشاف البروتوكول الخارجي بنفسه عندما تكون طبقة HTTPS موجودة أمامه.


31. اختبار حالة الخدمات

نفّذ:


docker compose ps

ثم:


docker logs cloudflared --tail 50

ثم:


docker logs nextcloud --tail 50

وأخيرًا:


docker logs nextcloud-db --tail 50

إذا كانت الخدمات تعمل بدون أخطاء واضحة، فالبنية الأساسية أصبحت:


                 INTERNET
                     │
                     ▼
             ┌──────────────┐
             │  Cloudflare   │
             │     HTTPS     │
             └───────┬──────┘
                     │
              Cloudflare Tunnel
                     │
                     ▼
             ┌──────────────┐
             │  cloudflared │
             └───────┬──────┘
                     │
             Docker Network
                     │
              ┌──────┴──────┐
              ▼             ▼
         Nextcloud        MariaDB
              │
              ▼
       Persistent Storage

⚠️ 32. لكن لدينا مشكلة أكبر يجب حلها قبل اعتبار الخادم جاهزًا

في هذه المرحلة لا أنصح بكتابة عبارة "استغنِ عن خدمات التخزين المدفوعة" في المقال وكأن المشكلة انتهت.

لأننا حتى الآن لدينا:


نسخة واحدة من البيانات
        ↓
HDD واحد

إذا مات الـ HDD:

قد تختفي ملفاتك.

إذا سُرق الجهاز:

قد تختفي ملفاتك.

إذا حدث تلف في نظام الملفات:

قد تختفي ملفاتك.

إذا أصاب الجهاز Ransomware ووصل إلى الملفات:

قد تتضرر النسخة الأصلية والنسخ المتصلة بها.

لذلك الجزء التالي في الدليل ليس اختياريًا.

سنضيف:


المرحلة التالية — Backup حقيقي

سننشئ:


              Nextcloud
                  │
                  ▼
             Main Disk
                  │
          ┌───────┴───────┐
          ▼               ▼
    Local Backup     External Backup

وسنشرح تحديدًا:


  • كيف نعمل Backup لقاعدة MariaDB.
  • كيف ننسخ بيانات Nextcloud.
  • لماذا لا يكفي نسخ مجلد data فقط.
  • كيف نستخدم قرص USB خارجي.
  • كيف نجعل النسخ الاحتياطي تلقائيًا.
  • كيف نختبر أن النسخة الاحتياطية قابلة للاستعادة فعلًا.

وهنا بالذات لن نستخدم أمرًا عشوائيًا مثل cp -r ونقول للمستخدم إن لديه Backup. سنبني استراتيجية استعادة حقيقية؛ لأن الهدف من الـ Backup ليس أن يكون لديك ملف اسمه backup، بل أن تستطيع استعادة

الخادم عندما يحدث عطل.

33. لا تعتمد على القرص الأصلي فقط

وصلنا الآن إلى أهم جزء في المشروع: النسخ الاحتياطي.

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

إذا تعطل القرص، فستحتاج إلى نسخة أخرى.

ووفقًا لوثائق Nextcloud، النسخة الاحتياطية الصحيحة يجب أن تشمل على الأقل:

  • ملفات الإعدادات config.
  • مجلد البيانات data.
  • الـ themes.
  • التطبيقات المخصصة إذا كنت تستخدمها.
  • قاعدة البيانات.

وبما أن إعدادنا يستخدم:


./data/nextcloud:/var/www/html

فإن مجلد:


data/nextcloud

يحتوي على تثبيت Nextcloud وملفاته المهمة، بما فيها config وdata.

أما قاعدة MariaDB، فلا ننسخ مجلد قاعدة البيانات كبديل عن Backup حقيقي؛ سنأخذ منها Dump يمكن استعادته.

34. أضف قرصًا خارجيًا للنسخ الاحتياطي

أفضل بداية لهذا المشروع هي استخدام قرص USB خارجي.

مثال:


الجهاز القديم
     │
     ├── قرص النظام
     │
     └── قرص USB خارجي
             │
             └── Backup

إذا كان لديك قرص 2TB مثلًا، فلا يلزم أن يكون بنفس حجم قرص البيانات تمامًا إذا كانت بياناتك الفعلية أقل من ذلك.

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

35. معرفة اسم القرص الخارجي

بعد توصيل القرص، نفّذ:


lsblk

ستظهر قائمة بالأقراص.

مثال:


NAME   SIZE TYPE MOUNTPOINTS
sda    120G disk
├─sda1  512M part /boot/efi
└─sda2 119G part /
sdb      2T disk
└─sdb1   2T part

في هذا المثال:


sda

هو قرص Ubuntu.

و:


sdb

هو القرص الخارجي.

لا تفترض أن جهازك يستخدم sdb.

قد يظهر القرص باسم مختلف.

36. تحذير مهم قبل تهيئة القرص

إذا كان القرص يحتوي بالفعل على ملفات مهمة، لا تنفذ أي أمر mkfs.

أمر مثل:


sudo mkfs.ext4 /dev/sdb1

سيؤدي إلى تهيئة القسم وحذف البيانات الموجودة عليه.

لذلك إذا كان القرص جديدًا أو لا يحتوي على بيانات مهمة، يمكننا تهيئته.

أما إذا كان مستخدمًا بالفعل، احتفظ بنظام الملفات الموجود واستخدمه بعد التأكد من القسم الصحيح.

37. إنشاء مكان للقرص

سنستخدم:


sudo mkdir -p /mnt/backup

ثم نركب القرص:


sudo mount /dev/sdb1 /mnt/backup

استبدل /dev/sdb1 بالقسم الصحيح الذي ظهر عندك في lsblk.

تحقق:


df -h /mnt/backup

يجب أن ترى مساحة القرص الخارجي.

مثال:


Filesystem      Size  Used Avail Use%
/dev/sdb1       1.8T   20G  1.7T   2%

38. اجعل القرص يُركب تلقائيًا

هناك مشكلة إذا اعتمدنا على:


/dev/sdb1

لأن اسم الجهاز قد يتغير في بعض الظروف.

الأفضل استخدام UUID.

احصل عليه:


sudo blkid /dev/sdb1

مثال:


/dev/sdb1: UUID="8f4c7e21-..." TYPE="ext4"

انسخ الـ UUID.

ثم افتح:


sudo nano /etc/fstab

وأضف في آخر الملف:


UUID=8f4c7e21-XXXXXXXX-XXXXXXXX /mnt/backup ext4 defaults,nofail 0 2

استبدل الـ UUID بالقيمة الفعلية.

بعد ذلك اختبر ملف fstab:


sudo mount -a

ثم:


df -h /mnt/backup

إذا ظهر القرص بدون أخطاء، فالإعداد صحيح.

39. أنشئ مجلد النسخ الاحتياطية

سنرتب النسخ بهذا الشكل:


/mnt/backup/
└── nextcloud/
    ├── 2026-10-06/
    ├── 2026-10-07/
    └── ...

أنشئ المجلد:


sudo mkdir -p /mnt/backup/nextcloud

ثم اجعل المستخدم الحالي قادرًا على الكتابة إليه:


sudo chown -R $USER:$USER /mnt/backup/nextcloud

40. قبل النسخ: فعّل Maintenance Mode

لا نريد أن يكتب المستخدمون ملفات جديدة أثناء أخذ النسخة.

Nextcloud يوصي باستخدام Maintenance Mode أثناء النسخ لمنع حدوث عدم اتساق بين الملفات وقاعدة البيانات.

من مجلد المشروع:


cd ~/home-server

ثم:


docker compose exec -T nextcloud php occ maintenance:mode --on

تحقق:


docker compose exec -T nextcloud php occ maintenance:mode

يجب أن تظهر حالة تشير إلى أن Maintenance Mode مفعّل.

41. أخذ نسخة من ملفات Nextcloud

أنشئ مجلدًا بتاريخ اليوم:


BACKUP_DIR="/mnt/backup/nextcloud/$(date +%F)"
mkdir -p "$BACKUP_DIR"

ثم انسخ ملفات Nextcloud:


sudo tar -C data/nextcloud -czf "$BACKUP_DIR/nextcloud-files.tar.gz" .

سيشمل هذا النسخة الكاملة من مجلد Nextcloud، بما في ذلك:


config/
data/
apps/
themes/

وهذا يتوافق مع مبدأ Nextcloud في الاحتفاظ بمجلدات التثبيت والإعدادات والبيانات المطلوبة للاستعادة.

42. أخذ نسخة من قاعدة البيانات

الآن نأخذ Database Dump من MariaDB.

سنستخدم:


docker compose exec -T db sh -c \
'mariadb-dump --single-transaction --default-character-set=utf8mb4 -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' \
> "$BACKUP_DIR/nextcloud-database.sql"

لاحظ أننا لم نكتب كلمة مرور قاعدة البيانات داخل الأمر نفسه.

كما أننا استخدمنا:


--single-transaction

و:


--default-character-set=utf8mb4

وهما متوافقان مع توصيات Nextcloud لنسخ MariaDB، خصوصًا مع دعم Unicode/emoji.

43. تحقق من أن النسخة موجودة

نفّذ:


ls -lh "$BACKUP_DIR"

يجب أن ترى شيئًا شبيهًا:


nextcloud-database.sql
nextcloud-files.tar.gz

تحقق من حجم الملفات:


du -h "$BACKUP_DIR"/*

لا تنتقل للخطوة التالية إذا كان أحد الملفات حجمه 0 بايت.

44. أعد تشغيل Nextcloud

بعد انتهاء النسخ:


docker compose exec -T nextcloud php occ maintenance:mode --off

ثم:


docker compose exec -T nextcloud php occ maintenance:mode

يجب أن تكون Maintenance Mode معطلة.

افتح Nextcloud وتأكد أن الملفات ما زالت موجودة.

45. لا تعتبر النسخة الاحتياطية ناجحة بعد

هذه نقطة مهمة جدًا.

وجود:


nextcloud-files.tar.gz

و:


nextcloud-database.sql

لا يعني أن النسخة الاحتياطية صالحة.

الاختبار الحقيقي هو الاستعادة.

وثائق Nextcloud نفسها توضح أن استعادة النظام تحتاج إلى قاعدة البيانات وملفات البيانات والإعدادات، وأنه لا يمكن إكمال الاستعادة بدونها.

لذلك يجب أن نختبر النسخة.

46. اختبار سلامة ملف النسخة

أولًا اختبر أرشيف الملفات:


tar -tzf "$BACKUP_DIR/nextcloud-files.tar.gz" > /dev/null

إذا لم يظهر خطأ، فهذا يعني أن الأرشيف قابل للقراءة.

يمكنك أيضًا:


echo $?

إذا ظهرت:


0

فالعملية نجحت.

47. اختبار قاعدة البيانات

يمكننا اختبار أن ملف SQL ليس فارغًا:


ls -lh "$BACKUP_DIR/nextcloud-database.sql"

ثم:


head -n 20 "$BACKUP_DIR/nextcloud-database.sql"

يجب أن ترى أوامر SQL ومعلومات مرتبطة بقاعدة البيانات.

لا تعدّل الملف.

48. احتفظ بنسخ متعددة

لا نريد:


Backup واحد

بل:


Backup اليوم
Backup أمس
Backup الأسبوع الماضي

مثلًا:


/mnt/backup/nextcloud/
├── 2026-10-04/
├── 2026-10-05/
└── 2026-10-06/

لكن هناك مشكلة:

إذا امتلأ القرص بعد عدة أشهر، سيتوقف النسخ الاحتياطي.

لذلك يمكننا لاحقًا إضافة سياسة احتفاظ مثل:


آخر 7 نسخ يومية
+
4 نسخ أسبوعية
+
3 نسخ شهرية

وهذا أفضل بكثير من حذف كل شيء عشوائيًا بعد عدد معين من الأيام.

49. اجعل النسخ الاحتياطي تلقائيًا

بعد أن تأكدنا يدويًا أن العملية تعمل، يمكن تحويلها إلى Cron Job.

لكن لا أنصح بوضع Cron الآن قبل اختبار النسخة يدويًا.

الترتيب الصحيح هو:


Manual Backup
      ↓
Verify
      ↓
Test Restore
      ↓
Automation

وليس:


Automation
      ↓
اكتشف بعد شهر أن النسخ كانت تفشل

وهذه نقطة مهمة جدًا في أي نظام Backup.

50. ماذا لو تعطل الجهاز؟

لنفترض أن القرص الداخلي مات.

لدينا:


Backup
├── nextcloud-files.tar.gz
└── nextcloud-database.sql

يمكن إعادة تثبيت Ubuntu وDocker ثم إعادة بناء الخدمات واستعادة البيانات.

لكن لا تحاول استعادة قاعدة البيانات الآن على خادمك العامل كاختبار.

لأن استعادة قاعدة البيانات فوق قاعدة البيانات الحالية قد تتطلب حذف وإعادة إنشاء قاعدة البيانات، وهي عملية مدمرة إذا نُفذت على الخادم الخطأ. وثائق Nextcloud نفسها تنص على ضرورة حذف الجداول/إعادة إنشاء قاعدة البيانات قبل استعادة النسخة.

51. قاعدة ذهبية: لا تختبر Restore على الخادم الإنتاجي

إذا أردت اختبار الاستعادة فعليًا، استخدم:

  • جهازًا ثانيًا، أو
  • VM، أو
  • خادمًا مؤقتًا.

ثم:


Backup
   ↓
New Server
   ↓
Restore
   ↓
Test Login
   ↓
Test Files
   ↓
Test Sharing

إذا نجحت العملية، أصبح لديك دليل حقيقي أن الـ Backup صالح.

52. بعد الاستعادة: تحديث بصمة الملفات

إذا تمت استعادة Backup قديم، يوفر Nextcloud أمر:


docker compose exec -T nextcloud php occ maintenance:data-fingerprint

وهو مهم بعد استعادة ملفات أو قاعدة البيانات حتى تستطيع تطبيقات المزامنة اكتشاف التغييرات بشكل صحيح.

53. تحديث Nextcloud بأمان

هنا أيضًا يجب ألا نرتكب خطأ شائعًا:


docker compose pull
docker compose up -d

ثم نأمل أن كل شيء يعمل.

لا أنصح بهذا كإجراء تحديث أعمى.

قبل أي تحديث:


Backup
  ↓
Check compatibility
  ↓
Update
  ↓
Database migration
  ↓
Test

وثائق Nextcloud توصي بوجود Backup حديث قبل كل Upgrade، وتحذر من أن عملية التحديث لا تعتبر Backup لقاعدة البيانات أو مجلد البيانات. كما أن الرجوع إلى إصدار أقدم غير مدعوم وقد يؤدي إلى تلف البيانات.

54. لا تستخدم latest بلا تفكير

في ملفنا السابق استخدمنا:


image: nextcloud:latest

وهنا أريد تصحيحًا مهمًا للمقال.

للتجربة المنزلية البسيطة يمكن أن يعمل، لكن للدليل الذي نريد أن يكون موثوقًا وقابلًا للتكرار، تثبيت Major Version محدد أفضل من ترك Docker يسحب أي إصدار مستقبلي.

Docker Official Image يوضح الإصدارات والعلامات المتاحة، كما يشير إلى أن صورة Docker الرسمية لـ Nextcloud موجهة أكثر للمستخدمين الخبراء، بينما يوفر مشروع Nextcloud أيضًا All-in-One كخيار أبسط لمن يريد تجربة متكاملة.

لذلك في نسخة المقال النهائية سأتعامل مع إدارة الإصدار والتحديث كجزء من التشغيل، وليس مجرد أمر docker pull.

55. فحص حالة Nextcloud

من لوحة Nextcloud اذهب إلى:

Administration settings → Overview

راقب:

  • Security & setup warnings.
  • Database.
  • Background jobs.
  • PHP.
  • Storage.
  • HTTPS.
  • Apps.

إذا ظهرت تحذيرات، لا نتجاهلها لمجرد أن الموقع يعمل.

الهدف ليس:

"الموقع فتح."

الهدف:

"الخادم يعمل بطريقة صحيحة ويمكن استعادته."

56. تأكد من عدم فتح منافذ غير ضرورية

على Ubuntu:


sudo ss -tulpn

ويمكنك أيضًا:


sudo ufw status

في تصميم Cloudflare Tunnel، لا نحتاج إلى فتح:


80
443

في الراوتر للوصول إلى Nextcloud.

ولا ينبغي فتح:


3306

لـ MariaDB على الإنترنت.

قاعدة البيانات يجب أن تبقى داخل شبكة Docker.

57. ماذا أصبح لدينا الآن؟

بعد إكمال هذا الجزء، البنية أصبحت:


                         INTERNET
                            │
                            ▼
                    ┌───────────────┐
                    │   Cloudflare  │
                    │ HTTPS / WAF   │
                    └───────┬───────┘
                            │
                       Tunnel
                            │
                            ▼
                    ┌───────────────┐
                    │  cloudflared  │
                    └───────┬───────┘
                            │
                    Docker Network
                            │
              ┌─────────────┴─────────────┐
              │                           │
              ▼                           ▼
       ┌─────────────┐             ┌─────────────┐
       │  Nextcloud  │             │   MariaDB   │
       └──────┬──────┘             └─────────────┘
              │
              ▼
       Internal Storage
              │
              │ Backup
              ▼
       ┌──────────────┐
       │ External HDD │
       └──────────────┘

وهنا أصبح لدينا بالفعل Private Cloud وليس مجرد Docker Container.

58. هل استغنينا فعلًا عن Google Drive وOneDrive؟

جزئيًا، وليس 100%.

أنت لم تعد مضطرًا لدفع اشتراك تخزين شهري فقط لكي تمتلك مساحة شخصية.

لكن في المقابل أصبحت مسؤولًا عن:

  • الجهاز.
  • الكهرباء.
  • الإنترنت.
  • القرص.
  • النسخ الاحتياطي.
  • التحديثات.
  • الأمان.
  • الاستعادة عند حدوث مشكلة.

وهذه هي المفاضلة الحقيقية في الـ Self-Hosting.

الخدمة السحابية المدفوعة تبيعك الراحة والإدارة.

أما الـ Home Server فيعطيك التحكم والخصوصية وتقليل التكلفة الشهرية، مقابل مسؤولية الإدارة.

59. قبل أن تعتبر المشروع مكتملًا

استخدم هذه القائمة:

الخادم

  • Ubuntu يعمل.
  • Docker يعمل.
  • Nextcloud يعمل.
  • MariaDB تعمل.
  • البيانات محفوظة على Storage دائم.

الوصول

  • Domain يعمل.
  • HTTPS يعمل.
  • Cloudflare Tunnel متصل.
  • لا توجد Port Forwarding غير ضرورية.
  • trusted_domains مضبوط.

Backup

  • Backup للـ Nextcloud files.
  • Backup لقاعدة البيانات.
  • Backup على قرص مختلف.
  • أكثر من نسخة محفوظة.
  • تم اختبار سلامة الملفات.
  • تم اختبار Restore على بيئة منفصلة.

التشغيل

  • توجد خطة للتحديث.
  • توجد خطة للاستعادة.
  • توجد مساحة تخزين كافية.
  • لا توجد تحذيرات أمنية مهمة.

الخلاصة

تحويل حاسوب قديم إلى Home Server ليس مجرد تثبيت Docker وتشغيل Nextcloud.

المشروع الحقيقي يتكون من أربع طبقات:

1️⃣ الخدمة

Nextcloud لإدارة الملفات.

2️⃣ البنية

Ubuntu + Docker + MariaDB.

3️⃣ الوصول الآمن

Cloudflare Tunnel + HTTPS + Domain.

4️⃣ الاستمرارية

Backup قابل للاستعادة، وليس مجرد نسخة ملفات.

وهنا تكمن أهم قاعدة في الـ Self-Hosting:

إذا لم تختبر استعادة النسخة الاحتياطية، فلا تفترض أن لديك Backup.

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


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


المراجع الرسمية التي تحققت منها لهذا الجزء: Cloudflare Tunnel Documentation وNextcloud Reverse Proxy Configuration.


أعجبك المقال؟ شاركه

النشرة البريدية

كن أول من يعرف بمستقبل التقنية

أهم الأخبار والتحليلات التقنية مباشرة في بريدك.

مقالات قد تهمك