> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# تثبيت Outline لقاعدة معرفة فريقك مع PostgreSQL وRedis والدخول عبر authentik
- URL: https://arabroot.io/articles/تثبيت-outline-لقاعدة-معرفة-الفريق/
- Published: 2026-09-19T15:35:00.000Z
- Updated: 2026-10-04T20:05:53.000Z
- Description: مكان واحد يكتب فيه فريقك إجراءاته وقراراته ويجد فيه ما يبحث عنه بسرعة، يعمل على سيرفرك أنت ويدخل إليه الموظفون بحساباتهم في authentik، مع نسخ احتياطي وتحديث لا تخسر فيهما شيئاً.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, تطبيقات لفريقك, الاستضافة الذاتية, Outline

لنفرض أن مطوراً في فريقك أمضى يوماً كاملاً حتى عرف لماذا يفشل النشر Deployment على سيرفر الإنتاج، ثم كتب الحل في رسالة على المحادثات أو في ملف على جهازه، فسوف تجد بعد ستة أشهر أن المشكلة نفسها عادت، وأن من يواجهها اليوم لا يعرف أين كتب الحل، أو أن صاحبه غادر الشركة وأخذ هذه المعرفة معه. والحل الأول الذي يخطر على البال هو مجلد مشترك فيه ملفات Word أو Markdown، وهذا الحل يعمل في الأسبوع الأول، ولكنه يفشل بسرعة لأن البحث Search فيه ضعيف، ولا يعرف أحد أي نسخة من الملف هي الأحدث، ولا يستطيع شخصان تعديل الملف نفسه في الوقت نفسه. والحل الثاني هو الويكي المدمج في مستودع الكود على Gitea أو GitHub، وهو مناسب لتوثيق الكود، ولكنه غير مناسب لفريق الدعم أو الموارد البشرية الذين لا يستخدمون Git أصلاً.

لذلك فالحل الأنسب هو ويكي داخلي Wiki يجمع إجراءات النشر وقرارات التصميم وخطوات استقبال الموظف الجديد Onboarding وحلول المشكلات التي تتكرر كل شهر في مكان واحد يبحث فيه الجميع. ومن الخيارات المعروفة التي تثبتها على سيرفرك [BookStack](https://www.bookstackapp.com/?ref=arabroot.io) و[Wiki.js](https://js.wiki/?ref=arabroot.io)، وهما مفتوحا المصدر Open Source، و[**Outline**](https://www.getoutline.com/?ref=arabroot.io) الذي يتناوله هذا الدليل، حيث تكتب فيه بمحرر Editor سريع يدعم Markdown، ويعدل عدة أشخاص المستند نفسه في اللحظة نفسها Real-time Collaboration، وتنتظم المستندات في مجموعات Collections لكل منها صلاحياتها Permissions، وفيه بحث فوري وقوالب Templates وتعليقات Comments، وتستطيع مشاركة مستند واحد عبر رابط، وله واجهة API كاملة.

ولاحظ أن Outline ليس مفتوح المصدر بالمعنى الدقيق، فالكود متاح على GitHub ولكنه منشور [برخصة Business Source License 1.1](https://github.com/outline/outline/blob/v1.10.1/LICENSE?ref=arabroot.io) واختصاراً BSL، وهذه الرخصة تسمح لك بتثبيته واستخدامه داخل مؤسستك لموظفيك والمتعاقدين معك، ولكنها تمنع أن تقدمه خدمة مستندات تجارية Document Service لجهات أخرى تنشئ فيه فرقها ومستنداتها، وكل إصدار يتحول إلى رخصة Apache 2.0 بعد تاريخ تحدده الرخصة نفسها، وهو للإصدار 1.10.1 يوم 9 سبتمبر 2030\. فإذا كان الويكي لفريقك فلا توجد مشكلة، وإذا كنت تريد تقديمه لعملائك فاقرأ الرخصة أولاً.

وقد يتساءل البعض: لماذا يأتي هذا الدليل بعد authentik، ولماذا لا أنشئ حسابات بكلمات مرور داخل Outline نفسه؟ والإجابة أن **Outline لا يملك نظام كلمات مرور Passwords خاصاً به**، حيث يدخل المستخدم عبر [مزود هوية](https://docs.getoutline.com/s/hosting/doc/authentication-7ViKRmRY5o?ref=arabroot.io) Identity Provider من نوع OIDC أو Google أو Microsoft أو Slack، أو عبر [رابط يصل إلى بريده](https://docs.getoutline.com/s/hosting/doc/email-magic-link-N2CPh5tmTS?ref=arabroot.io) Magic Link إذا كان حسابه موجوداً مسبقاً، لذلك سوف نستخدم authentik الذي ثبتناه في [دليل تثبيت authentik](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-authentik-%D9%84%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%88%D8%AD%D8%AF/) مزوداً للهوية، وأما إذا احتاج فريقك إلى ويكي بكلمات مرور محلية دون مزود هوية فإن BookStack أو Wiki.js أنسب له.

وسوف نناقش في هذا المقال ما يلي:

- إعداد التطبيق والـ Provider في authentik، ولماذا يحتاج Outline إلى ربط خاص للبريد يرسل `email_verified`.
- تثبيت Outline باستخدام Docker Compose مع PostgreSQL وRedis، وشرح الأسطر المهمة في الملف.
- ربط النطاق مع TLS وWebSocket، ثم الدخول الأول، وأول مجموعة ومستند، وإعدادات المدير.
- تخزين المرفقات على قرص السيرفر أو على خدمة متوافقة مع S3.
- النسخ الاحتياطي والاستعادة، والتحديث إلى إصدار أحدث، وأشهر المشكلات وحلولها.

## ما تحتاجه قبل أن تبدأ Requirements

- سيرفر Linux بمعالجين 2 vCPU وذاكرة RAM بحجم 2 GB على الأقل، والسبب أن Outline نفسه [يحتاج إلى 512 MB كحد أدنى](https://docs.getoutline.com/s/hosting/doc/requirements-ULdYnwi4wG?ref=arabroot.io) وينصح توثيقه بـ 1 GB أو أكثر بحسب عدد المستخدمين، ثم يأخذ PostgreSQL وRedis نصيبهما من الذاكرة أيضاً. ويتطلب Outline قاعدة PostgreSQL من الإصدار 14 فأحدث وRedis من الإصدار 4 فأحدث، ونستخدم في هذا الدليل PostgreSQL 17 وRedis 8.
- Docker Engine مع Compose v2، وإذا لم يكن مثبتاً فاتبع [دليل تثبيت Docker](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-docker-%D8%B9%D9%84%D9%89-ubuntu/) أولاً.
- نطاق فرعي Subdomain مثل `wiki.example.com` يشير إلى السيرفر، وReverse Proxy يصدر شهادة TLS Certificate ويدعم WebSocket مثل [Nginx Proxy Manager](https://arabroot.io/articles/nginx-proxy-manager-%D9%86%D8%B7%D8%A7%D9%82%D8%A7%D8%AA-%D9%88%D8%B4%D9%87%D8%A7%D8%AF%D8%A7%D8%AA-tls/)، والسبب أن التحرير الجماعي كله يمر عبر WebSocket.
- سيرفر authentik على `https://auth.example.com`، ويجب أن يصل إليه الـ Container الخاص بـ Outline، والسبب أن Outline يطلب التوكن Token من authentik مباشرة من السيرفر وليس عبر متصفح المستخدم.
- حساب [SMTP](https://docs.getoutline.com/s/hosting/doc/smtp-cqCJyZGMIB?ref=arabroot.io) لإرسال الإشعارات Notifications والدعوات ورسائل الدخول بالبريد، وهو اختياري ولكننا ننصح به، والسبب أن الدخول بالبريد وإشعارات التعديلات لا تعمل بدونه.

## نبدأ من authentik

سوف نبدأ بـ authentik، والسبب أن Outline يحتاج إلى معرف العميل Client ID والسر Client Secret قبل أن يعمل، وهما لا يظهران إلا بعد إنشاء الـ Provider.

### لماذا يحتاج البريد إلى ربط خاص فيه email\_verified؟

يرسل authentik مع نطاق Scope البريد `email` قيمة `email_verified`، ومنذ [الإصدار 2025.10](https://docs.goauthentik.io/releases/2025.10/?ref=arabroot.io) صارت هذه القيمة في الربط الافتراضي `false`، والسبب أن authentik لا يملك مصدراً واحداً يعرف منه هل تحقق المستخدم من بريده أم لا. والمشكلة أن Outline يرفض الدخول ببريد غير مؤكد في حالتين: إذا كان لهذا البريد حساب موجود مسبقاً في Outline، مثل زميل دعوته بالبريد، أو إذا حددت نطاقات مسموحة Allowed Domains في الإعدادات كما سوف نفعل لاحقاً، وعندها يعرض رسالة تقول إن البريد لم يتم التحقق منه. لذلك أنشئ [ربطاً جديداً للنطاق](https://docs.goauthentik.io/add-secure-apps/providers/property-mappings/?ref=arabroot.io) Scope Mapping من **Customization ← Property Mappings ← Create ← Scope Mapping**:

- **Name:** `OAuth Mapping: OpenID email with email_verified`
- **Scope name:** `email`
- **Expression:**

```python
return {
    "email": request.user.email,
    "email_verified": True,
}
```

وبهذا الإعداد تثق بالبريد المسجل في authentik كما هو، وهذا مناسب إذا كان المديرون Admins وحدهم ينشئون الحسابات، أو كانت الحسابات تأتي من Google Workspace. أما إذا كان التسجيل الذاتي Self-registration مفتوحاً في authentik فلا تقم بإرسال `True` ثابتة، والسبب أن Outline يربط البريد المؤكد بالحساب الموجود الذي يحمل البريد نفسه، فيستطيع من يسجل ببريد زميلك أن يدخل إلى حساب زميلك في الويكي، والحل أن ترسل قيمة تحفظها بعد التحقق الفعلي من البريد كما يشرح [توثيق authentik](https://integrations.goauthentik.io/documentation/outline/?ref=arabroot.io).

### إنشاء التطبيق Application والـ Provider

من **Applications ← New Application** أدخل الاسم `Outline` والـ slug `outline`، ثم اختر [**OAuth2/OpenID Provider**](https://docs.goauthentik.io/add-secure-apps/providers/oauth2/?ref=arabroot.io) واضبطه كما يلي:

- **Authorization Flow:** `default-provider-authorization-implicit-consent`.
- **Client Type:** Confidential. احفظ Client ID والسر.
- **Grant Types:** أبق **Authorization Code** و**Refresh token** مفعلين.
- **Redirect URIs:** `Strict` و`Authorization` والعنوان `https://wiki.example.com/auth/oidc.callback`.
- **Signing Key:** `authentik Self-signed Certificate`.

واخترنا المطابقة Strict لأن authentik يقبل عندها عنوان العودة الذي يطابق المسجل حرفياً فقط، فلا يستطيع أحد أن يوجه رمز الدخول إلى عنوان آخر يملكه، والمسار `/auth/oidc.callback` ثابت في Outline، ويبنيه من قيمة `URL` التي سوف نضعها في ملف Compose.

![إعداد الـ Provider الخاص بـ Outline في authentik مع Redirect URI بمطابقة Strict ومفتاح التوقيع](https://arabroot.io/content/images/2026/09/outline-01-provider-redirect.webp)

عنوان إعادة التوجيه ومفتاح التوقيع للـ Provider الخاص بـ Outline (العنوان في الصورة محلي)

ثم في **Advanced protocol settings**:

- **Subject Mode:** *Based on the User's username*.
- **Selected Scopes:** `openid` و`profile` والـ mapping الذي أنشأته للبريد، واحذف الـ mapping الافتراضي `authentik default OAuth Mapping: OpenID 'email'`، والسبب أن الاثنين يرسلان النطاق `email` نفسه فيتعارضان.

![قائمة Selected Scopes وفيها openid وprofile وmapping البريد مع email_verified](https://arabroot.io/content/images/2026/09/outline-02-provider-scopes.webp)

النطاقات المختارة: البريد يأتي من الـ mapping المخصص

⚠️

إذا أنشأت الـ Provider بطريقة غير المعالج Wizard، مثل API أو blueprint، فتأكد من تفعيل **Authorization Code** في Grant Types، والسبب أن authentik يرفض الطلب بدونه برسالة «Invalid grant\_type for provider»، ولا يعرض Outline إلا رسالة عامة هي «Authentication failed».

وإذا أردت أن يقتصر الويكي على موظفين محددين، فاربط بالتطبيق مجموعة Group مثل `employees` من تبويب **Policy / Group / User Bindings**، وبالتالي يرفض authentik دخول من ليس فيها قبل أن يصل إلى Outline أصلاً.

## تثبيت Outline خطوة بخطوة

### المجلد وملف .env والأسرار Secrets

سوف نضع كل ما يخص Outline في مجلد واحد، فيسهل نسخه احتياطياً ونقله إلى سيرفر آخر:

```bash
sudo mkdir -p /opt/outline
cd /opt/outline
```

ثم ننشئ ملف `.env` بالأسرار، ونضع فيه Client ID والسر اللذين حفظتهما من authentik:

```bash
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 24)
SECRET_KEY=$(openssl rand -hex 32)
UTILS_SECRET=$(openssl rand -hex 32)
OIDC_CLIENT_ID=الصق-معرف-العميل
OIDC_CLIENT_SECRET=الصق-السر
SMTP_PASSWORD=change-me
EOF
chmod 600 .env
```

يستخدم Outline المفتاح [SECRET\_KEY](https://github.com/outline/outline/blob/v1.10.1/.env.sample?ref=arabroot.io) لتشفير Encryption بيانات حساسة داخل قاعدة البيانات Database، ويطلبه بصيغة hex بطول 32 بايت، ولهذا نولده بالأمر `openssl rand -hex 32`. ولا تقم بتغييره بعد التشغيل، والسبب أنك إذا غيرته أو فقدته فلن يستطيع Outline قراءة تلك البيانات مرة أخرى، لذلك احفظه مع النسخة الاحتياطية Backup. أما `UTILS_SECRET` فهو مفتاح ثان يطلبه Outline، وتكفيه أي قيمة عشوائية طويلة.

### ملف docker-compose.yml

وملف Compose كما يلي، وفيه ثلاث خدمات هي Outline وPostgreSQL وRedis:

```yaml
services:
  outline:
    image: outlinewiki/outline:1.10.1
    restart: unless-stopped
    environment:
      NODE_ENV: production
      URL: https://wiki.example.com
      PORT: "3000"
      SECRET_KEY: ${SECRET_KEY:?}
      UTILS_SECRET: ${UTILS_SECRET:?}
      DEFAULT_LANGUAGE: en_US
      # قاعدة البيانات وRedis على شبكة Compose الداخلية
      DATABASE_URL: postgres://outline:${POSTGRES_PASSWORD}@postgres:5432/outline
      PGSSLMODE: disable
      REDIS_URL: redis://redis:6379
      # الملفات المرفقة على القرص
      FILE_STORAGE: local
      FILE_STORAGE_LOCAL_ROOT_DIR: /var/lib/outline/data
      FILE_STORAGE_UPLOAD_MAX_SIZE: "262144000"
      # TLS ينتهي عند الوكيل العكسي
      FORCE_HTTPS: "false"
      # تسجيل الدخول عبر authentik
      OIDC_CLIENT_ID: ${OIDC_CLIENT_ID}
      OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
      OIDC_AUTH_URI: https://auth.example.com/application/o/authorize/
      OIDC_TOKEN_URI: https://auth.example.com/application/o/token/
      OIDC_USERINFO_URI: https://auth.example.com/application/o/userinfo/
      OIDC_LOGOUT_URI: https://auth.example.com/application/o/outline/end-session/
      OIDC_USERNAME_CLAIM: preferred_username
      OIDC_DISPLAY_NAME: authentik
      OIDC_SCOPES: openid profile email
      # البريد
      SMTP_HOST: smtp.example.com
      SMTP_PORT: "587"
      SMTP_USERNAME: wiki@example.com
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_FROM_EMAIL: wiki@example.com
      SMTP_SECURE: "false"
      ENABLE_UPDATES: "false"
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - data:/var/lib/outline/data
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - default
      - proxy

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: outline
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: outline
    volumes:
      - db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U outline -d outline"]
      interval: 10s
      timeout: 5s
      retries: 10

  redis:
    image: redis:8.8.3-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 10

volumes:
  data:
  db:
  redis:

networks:
  proxy:
    external: true
```

في الإعداد أعلاه لاحظ التالي:

- ربطنا المنفذ Port رقم 3000 بالعنوان `127.0.0.1`، والسبب أن Docker يتجاوز جدار الحماية Firewall عند نشر المنافذ، فلا يصل إلى Outline من الخارج إلا الـ Reverse Proxy الذي ينضم معه إلى الشبكة المشتركة `proxy`.
- Redis ما زال إلزامياً في Outline، حيث [يشترطه التوثيق](https://docs.getoutline.com/s/hosting/doc/requirements-ULdYnwi4wG?ref=arabroot.io) ويستخدمه للطوابير Queues والتخزين المؤقت Cache، ولا تشبه الحالة هنا authentik الذي تخلى عن Redis، لذلك لا تحذف خدمة redis من الملف.
- `FORCE_HTTPS: "false"` لأن TLS ينتهي عند الـ Reverse Proxy، والقيمة الافتراضية `true` تجعل Outline يحول الطلبات إلى https بنفسه، و[ملف الإعدادات النموذجي](https://github.com/outline/outline/blob/v1.10.1/.env.sample?ref=arabroot.io) يسمح بتعطيلها عندما تكون متأكداً أن TLS ينتهي قبله.
- كتبنا عناوين OIDC الأربعة يدوياً كما في [توثيق authentik](https://integrations.goauthentik.io/documentation/outline/?ref=arabroot.io)، ويدعم Outline أيضاً المتغير `OIDC_ISSUER_URL` ليكتشفها وحده من `/.well-known/openid-configuration` كما يشرح [توثيق OIDC في Outline](https://docs.getoutline.com/s/hosting/doc/oidc-8CPBm6uC0I?ref=arabroot.io)، ولكن العناوين الصريحة أوضح عند تتبع الأخطاء.
- `OIDC_LOGOUT_URI` هو العنوان الذي يحول إليه Outline المستخدم عند تسجيل الخروج فتنتهي جلسته في authentik أيضاً، وفيه slug التطبيق `outline`، ويطلب توثيق Outline أن تضبطه أو تضبط `OIDC_DISABLE_REDIRECT`، والسبب أن المستخدم بدونه يضغط زر الخروج فيجد نفسه داخل Outline مرة أخرى لأن جلسته في authentik ما زالت قائمة.
- `SMTP_SECURE: "false"` مع المنفذ 587 يعني STARTTLS، أي أن الاتصال يبدأ عادياً ثم يرقيه Outline إلى TLS، ومع المنفذ 465 اجعل القيمة `"true"`، ولاحظ أن القيمة الافتراضية في بيئة الإنتاج `true`، فإذا تركتها مع المنفذ 587 فسوف يفشل الاتصال.
- `ENABLE_UPDATES: "false"` يمنع Outline من إرسال إحصاءات مجهولة الهوية إلى المطورين ليتحقق من وجود إصدار جديد، فإذا أردت أن ترى حالة التحديث في الإعدادات فاتركه `true`.
- لا يوجد فحص صحة Health Check لخدمة outline في الملف، والسبب أن [الـ Image الرسمية](https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t?ref=arabroot.io) فيها فحص مدمج على المسار `/_health` كل دقيقة، فلا تضف فحصاً آخر.

### التشغيل ومتابعة السجلات Logs

الآن سوف نقوم بإنشاء شبكة `proxy` مرة واحدة إن لم تكن موجودة من تثبيت الـ Reverse Proxy، ثم نشغل الخدمات ونتابع سجل Outline:

```bash
docker network create proxy
docker compose up -d
docker compose logs -f outline
```

وفي التشغيل الأول ينفذ Outline ترحيلات قاعدة البيانات Migrations وحده، فترى في السجل السطر `Running migrations…` ثم `OIDC plugin registered`، وهذا يعني أن متغيرات OIDC قرئت كاملة، فإذا لم يظهر هذا السطر فلن ترى زر authentik في صفحة الدخول. وفي الإصدارات القديمة كانت الترحيلات تحتاج إلى أمر منفصل هو `yarn db:migrate`، ولم يعد ذلك لازماً لأن [الترحيلات تعمل تلقائياً](https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t?ref=arabroot.io) عند بدء الـ Container. وللتحقق نفذ:

```bash
curl -s http://127.0.0.1:3000/_health
```

والمخرج سوف يكون `OK`، وبعد دقيقة تقريباً تظهر خدمة outline في `docker compose ps` بحالة `healthy`.

## ربط النطاق Domain وشهادة TLS

في Nginx Proxy Manager أنشئ مضيفاً Proxy Host للنطاق `wiki.example.com` يوجه إلى الـ Container المسمى outline على المنفذ `3000`، وفعل **Websockets Support**، والسبب أن التحرير الجماعي لا يعمل بدونه، واختر شهادة Let's Encrypt مع Force SSL، ثم أضف في [الإعداد المتقدم](https://nginxproxymanager.com/advanced-config/?ref=arabroot.io) السطر التالي حتى يقبل الـ Reverse Proxy مرفقات بالحجم الذي حددناه في `FILE_STORAGE_UPLOAD_MAX_SIZE`:

```nginx
client_max_body_size 250m;
```

وإذا كنت تستخدم [Caddy](https://caddyserver.com/docs/caddyfile/directives/reverse%5Fproxy?ref=arabroot.io) فهذا كل ما تحتاجه، لأنه يمرر WebSocket تلقائياً:

```nginx
wiki.example.com {
    reverse_proxy outline-outline-1:3000
}
```

ويجب أن تطابق قيمة `URL` في ملف Compose العنوان العام حرفياً، والسبب أن Outline يبني منها عنوان العودة callback الذي يرسله إلى authentik، فإذا اختلف حرف واحد رفض authentik الطلب.

## الدخول الأول

افتح `https://wiki.example.com/`، ولن ترى نموذج تسجيل Sign-up Form، وإنما زر «Continue with authentik» الذي يأخذ اسمه من `OIDC_DISPLAY_NAME`:

![صفحة Login to Outline مع زر Continue with authentik وزر Continue with Email](https://arabroot.io/content/images/2026/09/outline-03-outline-login.webp)

صفحة دخول Outline (يظهر زر البريد بعد إعداد SMTP)

وعند الضغط عليه ينقلك إلى authentik مع عبارة «Log in to continue to Outline»، فأدخل كلمة المرور واجتز المصادقة الثنائية 2FA كالمعتاد:

![صفحة دخول authentik بعبارة Log in to continue to Outline](https://arabroot.io/content/images/2026/09/outline-04-authentik-login.webp)

الدخول في authentik نيابة عن Outline

**وأول من يدخل ينشئ مساحة العمل Workspace ويصبح مديرها Admin**، ويجد فيها مجموعة Welcome بمستندات تعريفية، لذلك احرص على أن تكون أنت أول من يدخل بعد التشغيل مباشرة، ولا تقم بنشر الرابط للفريق قبل ذلك.

![مساحة عمل Outline بعد أول دخول مع مجموعة Welcome ومستنداتها وحساب Sara Ahmed](https://arabroot.io/content/images/2026/09/outline-05-first-login-workspace.webp)

مساحة العمل بعد الدخول الأول

## أول مجموعة وأول مستند

أنشئ من **New collection** مجموعة لكل فريق أو مجال، مثل `Engineering`، وحدد من يقرؤها ومن يعدلها، ثم اضغط **New doc** واكتب كما تكتب في Markdown، أي `##` للعناوين Headings و`1.` للقوائم Lists، وتستطيع سحب الصور إلى المحرر مباشرة، حيث يحفظ Outline المرفقات في الـ Volume `data` تحت `/var/lib/outline/data/uploads/`:

![مستند Deployment runbook في مجموعة Engineering مع عناوين وقائمة خطوات وصورة مرفقة](https://arabroot.io/content/images/2026/09/outline-06-document-with-attachment.webp)

مستند في مجموعة Engineering مع صورة مخزنة محلياً

## إعدادات المدير الأساسية

افتح **Settings** من صورة حسابك، وأول ما سوف تعدله الأقسام التالية:

- **Authentication:** يظهر authentik بحالة «Connected». أضف نطاق مؤسستك `example.com` في **Allowed domains**، والسبب أن Outline عندها لا ينشئ حساباً لبريد من خارج هذا النطاق حتى لو سمح به authentik، وتستطيع أيضاً تعطيل الدخول بالبريد إذا أردت أن يمر الجميع عبر authentik وحده.
- **Security:** اختر الصلاحية الافتراضية للأعضاء الجدد Editor أو Viewer، وقرر هل تسمح بالمشاركة العامة Public Sharing للمستندات، وغالب الظن أنك لا تريد أن يشارك أحد إجراءات الإنتاج برابط عام.
- **Users** و**Groups:** امنح دور Admin لمن تريد، وأنشئ مجموعات مستخدمين وامنحها صلاحيات على المجموعات Collections.

![صفحة Authentication في إعدادات Outline مع authentik متصل وخياري Email وPasskeys والنطاقات المسموحة والإصدار v1.10.1](https://arabroot.io/content/images/2026/09/outline-07-authentication-settings.webp)

إعدادات المصادقة في Outline، ويظهر الإصدار المثبت أسفل القائمة

## تخزين المرفقات على S3 (اختياري)

التخزين المحلي Local Storage يكفي لسيرفر واحد، وأما إذا أردت حفظ المرفقات Attachments في خدمة متوافقة مع S3 مثل AWS S3 أو Cloudflare R2 أو سيرفر MinIO أو Garage لديك، فاستبدل قسم الملفات في ملف Compose بما يلي:

```yaml
      FILE_STORAGE: s3
      AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY}
      AWS_SECRET_ACCESS_KEY: ${S3_SECRET_KEY}
      AWS_REGION: us-east-1
      AWS_S3_UPLOAD_BUCKET_URL: https://s3.example.com
      AWS_S3_UPLOAD_BUCKET_NAME: outline
      AWS_S3_FORCE_PATH_STYLE: "true"
      AWS_S3_ACL: private
      # لـ R2 وبعض المزودين الذين لا يدعمون presigned POST
      # AWS_S3_UPLOAD_METHOD: put
```

وهنا يرفع المتصفح الملفات إلى الـ bucket مباشرة بروابط موقعة Presigned URLs ولا تمر عبر Outline، لذلك يجب أن يصل متصفح المستخدم إلى عنوان S3، وأن يسمح إعداد CORS على الـ bucket بالطلبين `PUT` و`POST` من `https://wiki.example.com`. واجعل صلاحية مفتاح الوصول Access Key مقصورة على هذا الـ bucket، والسبب أن المفتاح محفوظ في ملف على السيرفر، فإذا تسرب فلا يصل صاحبه إلى غير مرفقات الويكي، والتفاصيل في [توثيق Outline](https://docs.getoutline.com/s/hosting/doc/file-storage-N4M0T6Ypu7?ref=arabroot.io).

## كيف تتأكد أن كل شيء يعمل؟

- الأمر `docker compose ps` يعرض الـ Containers الثلاثة بحالة `healthy`، والأمر `curl -s https://wiki.example.com/_health` يعيد `OK`.
- الدخول عبر authentik يعمل من نافذة خاصة Private Window، ويطلب المصادقة الثنائية إذا كانت مفروضة.
- افتح المستند نفسه في متصفحين واكتب في أحدهما، فإذا ظهر ما تكتبه فوراً في الآخر فاتصال WebSocket سليم.
- ارفع صورة في مستند ثم حدث الصفحة، ويجب أن تبقى الصورة ظاهرة.
- عند إضافة عضو جديد يرسل Outline إلى بريده رسالة «Welcome to Outline»، ولتجربة الرسائل قبل ربط خدمة بريد حقيقية وجه SMTP إلى [Mailpit](https://mailpit.axllent.org/?ref=arabroot.io)، وهو سيرفر SMTP تجريبي يلتقط الرسائل ويعرضها في واجهة ويب دون أن يرسلها.

## النسخ الاحتياطي Backup والاستعادة Restore

[تحتاج إلى نسخ ثلاثة أشياء](https://docs.getoutline.com/s/hosting/doc/backups-KZtPOADCHG?ref=arabroot.io): الأول قاعدة PostgreSQL، وفيها المستندات وسجل تعديلاتها Revision History والمستخدمون والصلاحيات، والثاني الـ Volume `data` وفيه المرفقات، أو الـ bucket إن كنت تستخدم S3، والثالث ملف `.env` بما فيه `SECRET_KEY`. ولا حاجة إلى نسخ Redis، والسبب أنه للطوابير والتخزين المؤقت فقط، ويعيد Outline بناء ما يحتاجه فيه.

```bash
cd /opt/outline
mkdir -p backups
docker compose exec -T postgres pg_dump -U outline -d outline -Fc > backups/outline-db-$(date +%F).dump
docker run --rm -v outline_data:/data:ro -v "$PWD/backups:/backup" alpine:3 \
  tar czf /backup/outline-data-$(date +%F).tar.gz -C /data .
cp .env backups/outline-env-$(date +%F)
```

ولاحظ أن اسم الـ Volume هنا `outline_data`، والسبب أن Compose يضيف اسم المجلد `outline` قبل اسم الـ Volume، فإذا وضعت الملفات في مجلد آخر فتأكد من الاسم بالأمر `docker volume ls`. واحفظ `.env` في مكان آمن ومنفصل لأن فيه الأسرار، وتستطيع أيضاً تصدير مساحة العمل كلها من **Settings ← Export** بصيغة HTML أو Markdown أو JSON، وهي نسخة إضافية مقروءة تفتحها دون Outline، وتنفعك إذا احتجت إلى إجراء من الويكي في يوم يكون فيه الويكي نفسه متوقفاً.

أما **الاستعادة** على سيرفر جديد فتحتاج إلى الإصدار نفسه من Outline وملف `.env` نفسه، ثم تشغل قاعدة البيانات وRedis وحدهما وتستعيد القاعدة من التفريغ Dump بالأمر [pg\_restore](https://www.postgresql.org/docs/17/app-pgrestore.html?ref=arabroot.io) قبل تشغيل Outline:

```bash
cd /opt/outline
docker compose up -d postgres redis
docker compose exec -T postgres pg_restore -U outline -d outline --clean --if-exists --no-owner < backups/outline-db-2026-09-27.dump
docker run --rm -v outline_data:/data -v "$PWD/backups:/backup" alpine:3 \
  sh -c 'tar xzf /backup/outline-data-2026-09-27.tar.gz -C /data && chown -R 1001:1001 /data'
docker compose up -d outline
```

وفي الأوامر أعلاه لاحظ أن `chown` يعيد ملكية المرفقات إلى المستخدم `nodejs` الذي يعمل به Outline داخل الـ Container ورقمه 1001، والسبب أن الأمر `tar` يعمل بالمستخدم root فتصبح الملفات المستعادة ملكاً له ويفشل رفع الصور بعدها. وإذا أردت أن تتأكد من الرقم فنفذ `docker compose exec outline id`، فإذا كان مختلفاً فاستخدمه في `chown`. وتذكر أن النسخة التي لم تجرب استعادتها لا يعتمد عليها، لذلك جرب الاستعادة على سيرفر تجريبي Staging مرة كل بضعة أشهر.

## التحديث Upgrade إلى إصدار أحدث

1. اقرأ [ملاحظات الإصدار على GitHub](https://github.com/outline/outline/releases?ref=arabroot.io)، وابحث خصوصاً عن أي تغيير في متغيرات البيئة Environment Variables أو في أدنى إصدار يتطلبه من PostgreSQL.
2. خذ نسخة احتياطية من القاعدة والمرفقات.

غير الوسم Tag في `docker-compose.yml`، مثلاً إلى `outlinewiki/outline:1.10.2`، ثم نفذ:

```bash
docker compose pull outline
docker compose up -d outline
docker compose logs -f outline
```

وتعمل الترحيلات تلقائياً عند بدء التشغيل، ولكن بعد أن يرحل الإصدار الأحدث القاعدة لا تقم بالعودة إلى إصدار أقدم، والسبب أن الترحيلات [قد لا تكون قابلة للعكس](https://docs.getoutline.com/s/hosting/doc/backups-KZtPOADCHG?ref=arabroot.io)، فلا رجوع عنها إلا من النسخة الاحتياطية. ويظهر الإصدار الحالي وحالته «Up to date» أسفل قائمة الإعدادات، إلا إذا عطلت `ENABLE_UPDATES`. أما PostgreSQL فلا تقم بترقيته إلى إصدار رئيسي جديد بتغيير الوسم وحده، حتى لو رأيت أن [ملف Compose في توثيق Outline](https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t?ref=arabroot.io) صار يستخدم `postgres:18`، والسبب أن ملفات البيانات لا تقرأ بين الإصدارات الرئيسية، فحدثه [بين الإصدارات الرئيسية](https://www.postgresql.org/docs/17/upgrading.html?ref=arabroot.io) عبر `pg_dump` ثم الاستعادة في Container بالإصدار الجديد، كما في [دليل Mattermost](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mattermost-%D9%88%D8%AA%D8%B1%D9%82%D9%8A%D8%AA%D9%87/).

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

📌

في 2 يونيو 2022 نشرت Atlassian [تحذيراً أمنياً حرجاً](https://confluence.atlassian.com/doc/confluence-security-advisory-2022-06-02-1130377146.html?ref=arabroot.io) عن الثغرة CVE-2022-26134 في Confluence Server وData Center، وهي ثغرة تسمح لأي شخص على الشبكة بتنفيذ كود على السيرفر دون تسجيل دخول، وتشمل كل الإصدارات المدعومة، وقد أبلغت عنها شركة Volexity، وكانت تستغل فعلياً على سيرفرات حقيقية يوم نشر التحذير، أي أن المخترقين سبقوا الإصلاح، وصدرت الإصدارات المصححة بين 2 و3 يونيو، بينما لم تتأثر نسخ Confluence السحابية التي تديرها Atlassian. والدرس أن الويكي الذي تستضيفه بنفسك يصبح تحديثه مسؤوليتك أنت، لذلك تابع ملاحظات إصدارات Outline، ولا تكشفه للإنترنت إلا عبر الـ Reverse Proxy، وحدثه فور صدور إصلاح أمني.

## مشكلات شائعة وحلولها Troubleshooting

### رسالة `Authentication failed – we were unable to sign you in`

افتح سجل Outline وسجل authentik في اللحظة نفسها، ففي سجل authentik تعني «Invalid grant\_type» أن Authorization Code غير مفعل في الـ Provider، وتعني «Redirect URI Error» أن قيمة `URL` في Outline لا تطابق العنوان المسجل. وأما في سجل Outline فتعني رسالة البريد غير المؤكد أن الـ mapping الخاص بـ `email_verified` غير مختار، أو أن الـ mapping الافتراضي ما زال مختاراً معه.

### خطأ في الحصول على التوكن Token بعد العودة من authentik

السبب أن الـ Container الخاص بـ Outline لا يصل إلى `OIDC_TOKEN_URI`، واختبر ذلك بالأمر `docker compose exec outline wget -qO- https://auth.example.com/-/health/live/`، وإذا كان النطاق داخلياً فقط فأضف `extra_hosts` إلى خدمة outline حتى يعرف الـ Container عنوانه.

### الصفحة تعيد التحويل إلى https بلا نهاية، أو لا تحفظ ملفات تعريف الارتباط Cookies

إذا كان الـ Reverse Proxy ينهي TLS فاجعل `FORCE_HTTPS: "false"`، وتأكد أنه يمرر `X-Forwarded-Proto: https`، وأما في بيئة اختبار عبر HTTP فتأكد أن `URL` يبدأ بـ `http://`.

### المستند لا يحفظ، أو تظهر رسالة «Trying to reconnect»

السبب أن اتصال WebSocket لا يمر عبر الـ Reverse Proxy، والحل أن تفعل Websockets Support في الـ Proxy Host.

### فشل رفع الصور

مع التخزين المحلي يكون السبب واحداً من اثنين: إما صلاحيات المجلد، فأعد تنفيذ `chown` على الـ Volume كما في قسم الاستعادة، وإما حد `client_max_body_size` في الـ Reverse Proxy. وأما مع S3 فالسبب إعداد CORS على الـ bucket، أو أن المتصفح لا يصل إلى عنوان `AWS_S3_UPLOAD_BUCKET_URL`.

### لا يوجد مدير بعد الدخول الأول

المدير هو صاحب الحساب الأول الذي أنشأ مساحة العمل، فإذا دخل شخص آخر قبلك فاطلب منه أن يمنحك دور المدير من **Settings ← Users**، وأما على تثبيت جديد لا محتوى فيه فالأسهل أن تحذف Volume القاعدة وتبدأ من جديد.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- المعرفة التي تبقى في المحادثات والملفات المتفرقة تضيع مع أول موظف يغادر، والويكي الداخلي مثل Outline يجمعها في مكان واحد يبحث فيه الجميع ويعدلون فيه معاً.
- Outline منشور برخصة BSL 1.1، وهي تسمح بتشغيله لفريقك ولكنها تمنع تقديمه خدمة مستندات تجارية لجهات أخرى.
- لا يملك Outline كلمات مرور خاصة به، لذلك يحتاج إلى مزود هوية مثل authentik، مع ربط للبريد يرسل `email_verified: true` وعنوان عودة بمطابقة Strict.
- Redis ما زال إلزامياً، واربط المنفذ بالعنوان `127.0.0.1`، وفعل WebSocket في الـ Reverse Proxy، واجعل `URL` يطابق العنوان العام حرفياً.
- انسخ قاعدة البيانات والمرفقات وملف `.env` مع `SECRET_KEY`، وخذ نسخة قبل كل تحديث لأن الترحيلات لا رجوع عنها إلا من النسخة الاحتياطية.

## سجل التحديثات (Changelog)

- سبتمبر 2026: كتابة الدليل واختباره على [Outline 1.10.1](https://github.com/outline/outline/releases/tag/v1.10.1?ref=arabroot.io).
- أكتوبر 2026: مراجعة الدليل على Outline 1.10.1، وهو آخر إصدار حتى الآن: صححنا وصف الرخصة (BSL 1.1 وليست مفتوحة المصدر)، ووضحنا متى يرفض Outline البريد غير المؤكد، وأضفنا أدنى إصدار من PostgreSQL وRedis والحد الأدنى للذاكرة بحسب التوثيق، وشرح `OIDC_LOGOUT_URI` و`OIDC_ISSUER_URL`، وصيغة HTML في التصدير.