> ## 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.

# تثبيت OpenProject لمكتب إدارة المشاريع PMO
- URL: https://arabroot.io/articles/تثبيت-openproject-لمكتب-إدارة-المشاريع/
- Published: 2026-10-22T20:45:00.000Z
- Updated: 2026-10-23T08:06:39.000Z
- Description: دليل عملي لتشغيل OpenProject Community على سيرفرك بمخطط Gantt والميزانيات وتتبع الوقت، مع ما يبقى في Enterprise واختبار فعلي للعربية.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الاستضافة الذاتية والتطبيقات, الاستضافة الذاتية, OpenProject

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

في [دليل Plane](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-plane-%D9%84%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9/) ثبتنا أداة صممت للفريق الذي يعمل بالسبرنتات واللوحات، وفي هذا الدليل سوف نثبت [**OpenProject**](https://www.openproject.org/?ref=arabroot.io)، وهي أداة مفتوحة المصدر برخصة [GPLv3](https://github.com/opf/openproject/blob/dev/COPYRIGHT?ref=arabroot.io) صممت حول ما يحتاجه مكتب المشاريع: حزم العمل Work Packages بتسلسل هرمي، ومخطط Gantt بالاعتماديات Dependencies والجدولة التلقائية، والميزانيات Budgets، وتتبع الوقت والتكاليف Time and Costs، والاجتماعات ومحاضرها، ومعها لوحات Kanban وBacklogs لفرق Scrum. وإذا كنت ما زلت تختار بين الأدوات فابدأ بالمقالين التاليين:

[![](https://arabroot.io/content/images/2026/10/pm-choose-cover-cover.webp)دليلكيف تختار أداة إدارة المشاريع Project Management لفريقك؟قبل أن تشتري Jira أو تثبت أداة مفتوحة المصدر، حدد طريقة عمل فريقك ومن سيستخدم الأداة وأين تبقى بياناتك، ثم جرب على مشروع حقيقي.](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D8%AA%D8%AE%D8%AA%D8%A7%D8%B1-%D8%A7%D8%AF%D8%A7%D8%A9-%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%84%D9%81%D8%B1%D9%8A%D9%82%D9%83/)[![](https://arabroot.io/content/images/2026/10/pm-tools-compare-cover-cover.webp)دليلأدوات إدارة المشاريع مفتوحة المصدر بديلاً عن Jira وAsanaمقارنة بين أدوات إدارة المشاريع مفتوحة المصدر والأدوات التجارية بالرخصة والسعر ونشاط التطوير، مع اختبار حقيقي للعربية في خمس منها.](https://arabroot.io/articles/%D8%A7%D8%AF%D9%88%D8%A7%D8%AA-%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D8%A8%D8%AF%D9%8A%D9%84%D8%A7-%D8%B9%D9%86-jira/)

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

- ما الذي تحصل عليه في Community Edition المجانية، وما الذي يبقى في خطط Enterprise، بالتحقق من شاشات التثبيت نفسه.
- التثبيت بحزمة Docker Compose الرسمية مع تثبيت الإصدارات وتوليد الأسرار، ومشكلتان ظهرتا في التشغيل الأول وحلهما.
- المشروع وحزم العمل ومخطط Gantt وأيام العمل، ثم اللوحات Boards والوقت والتكاليف والميزانيات.
- الدخول الموحد عبر LDAP وOIDC، والربط مع GitHub وGitLab، والترحيل من Jira، وال API.
- اختبار الواجهة العربية والتصدير، ثم النسخ الاحتياطي والاستعادة بالتجربة والتحديث.

## ماذا تعطيك Community وما الذي يبقى في Enterprise؟

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

| الميزة                                                      | Community            | Enterprise                                                   |
| ----------------------------------------------------------- | -------------------- | ------------------------------------------------------------ |
| حزم العمل والتسلسل الهرمي والعلاقات Relations               | متاحة                |                                                              |
| مخطط Gantt والجدولة التلقائية وأيام العمل والعطل            | متاحة                |                                                              |
| اللوحات Boards بأنواعها الستة، وBacklogs                    | متاحة                |                                                              |
| الوقت والتكاليف وأنواع التكاليف Cost Types وتقارير التكاليف | متاحة                | قيود تسجيل الوقت Time Entry Restrictions من خطة Professional |
| الميزانيات Budgets                                          | متاحة                |                                                              |
| الاجتماعات Meetings وWiki والمستندات                        | متاحة                |                                                              |
| اتصالات LDAP والتحقق بخطوتين 2FA                            | متاحة                | مزامنة مجموعات LDAP من خطة Premium                           |
| الدخول الموحد عبر OpenID Connect وSAML، وSCIM               |                      | OpenID Connect من خطة Professional                           |
| وحدتا GitHub وGitLab                                        | متاحة                |                                                              |
| أداة الترحيل Jira Migrator                                  | متاحة (تجريبية Beta) |                                                              |
| مخطط الفريق Team Planner وإدارة الموارد Resource Management |                      | بشارة Enterprise                                             |

وأما الأسعار فحسب [صفحة الأسعار](https://www.openproject.org/pricing/?ref=arabroot.io) في أكتوبر 2026 للتثبيت على سيرفرك: خطة Basic بسعر 5.95 يورو للمستخدم شهرياً بحد أدنى 25 مستخدماً، وProfessional بسعر 10.95 يورو بحد أدنى 25، وPremium بسعر 15.95 يورو بحد أدنى 100، وCorporate بالطلب. وهذا يعني أن مؤسسة تريد الدخول الموحد عبر OIDC مع مئة مستخدم تحتاج خطة Professional، فاحسب هذا قبل أن تعد الإدارة بأن الأداة مجانية بالكامل.

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

- حسب [متطلبات النظام الرسمية](https://www.openproject.org/docs/installation-and-operations/system-requirements/?ref=arabroot.io): أربعة معالجات CPU وذاكرة RAM بحجم 4 GB ومساحة 20 GB لما يصل إلى 200 مستخدم، وثمانية معالجات و8 GB لحوالي 500 مستخدم. وفي اختبارنا استهلكت خدمة `web` وحدها قرابة 2 GB من الذاكرة وخدمة `worker` قرابة 950 MB، فلا تبدأ بأقل من 4 GB.
- مساحة للـ Images: حوالي 1.5 GB لـ `openproject/openproject` و650 MB لـ PostgreSQL و500 MB لخدمة التحرير المشترك `hocuspocus`.
- PostgreSQL بالإصدار 16 أو أحدث، فهذا ما يدعمه المشروع رسمياً، وسوف نرى بعد قليل لماذا تحتاج أن تحدده بنفسك.
- Docker Engine وDocker Compose كما في [دليل تثبيت Docker على Ubuntu](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-docker-%D8%B9%D9%84%D9%89-ubuntu/)، و`git`.
- نطاق فرعي Subdomain مثل `pm.example.com` يشير إلى السيرفر (`203.0.113.10`)، وحساب SMTP للإشعارات.

## مكونات OpenProject وما يفعله كل جزء منها Architecture

![مخطط مكونات OpenProject: المتصفح ثم proxy ثم خدمات التطبيق ثم قاعدة البيانات ومجلد المرفقات](https://arabroot.io/content/images/2026/10/openproject-01-architecture.webp)

مكونات حزمة Docker Compose الرسمية

| الخدمة     | الدور                                                                                            |
| ---------- | ------------------------------------------------------------------------------------------------ |
| proxy      | Caddy يبنى محلياً من مجلد proxy/، ويوجه /hocuspocus إلى خدمة التحرير المشترك وكل ما عداه إلى web |
| web        | تطبيق Rails نفسه مع ال API، وله فحص صحة Health Check على /health\_checks/default                 |
| worker     | المهام في الخلفية Background Jobs: البريد والتصدير وإعادة الجدولة                                |
| cron       | المهام المجدولة، مثل استقبال البريد إذا فعلته                                                    |
| seeder     | ينشئ قاعدة البيانات ويطبق التعديلات Migrations ويضيف البيانات الأولية عند كل تشغيل ثم يخرج       |
| hocuspocus | سيرفر WebSocket للتحرير المشترك في المستندات                                                     |
| db         | قاعدة البيانات PostgreSQL                                                                        |
| cache      | memcached للتخزين المؤقت Cache، ولا يحتاج نسخاً احتياطياً                                        |
| autoheal   | يعيد تشغيل web إذا فشل فحص الصحة، ويحتاج الوصول إلى /var/run/docker.sock                         |

لاحظ أن `web` و`worker` و`cron` و`seeder` هي نفس ال Image بأوامر تشغيل مختلفة، لذلك يكفي متغير واحد اسمه `TAG` لتحديد إصدارها كلها، ولاحظ أيضاً أن `autoheal` يملك الوصول إلى Docker socket، أي إلى التحكم بكل Containers السيرفر، فإذا كانت سياسة مؤسستك تمنع ذلك فاحذفه من الملف وراقب `web` بأداة المراقبة لديك.

## تثبيت OpenProject خطوة بخطوة Installation

### تنزيل المستودع الرسمي

هناك ثلاث طرق رسمية لتشغيل OpenProject: حزم Linux، وContainer واحد يضم كل شيء All-in-one، و[Docker Compose](https://www.openproject.org/docs/installation-and-operations/installation/docker-compose/?ref=arabroot.io). والطريقة الثالثة هي التي يوصي بها المشروع للإنتاج، والسبب أن كل خدمة فيها مستقلة، فتستطيع تحديث قاعدة البيانات أو نقلها بدون أن تلمس التطبيق. والملفات موجودة في مستودع منفصل له فرع Branch لكل إصدار رئيسي:

```bash
cd /opt
sudo git clone https://github.com/opf/openproject-docker-compose.git --depth=1 --branch=stable/17 openproject
cd openproject
sudo cp .env.example .env
```

### ملف .env: الإصدار والأسرار وقاعدة البيانات

افتح `.env` وعدل القيم التالية، وقبل ذلك قم بتوليد الأسرار، ثم ضع كل قيمة مكان `CHANGE_ME` المقابل لها:

```bash
openssl rand -hex 64   # SECRET_KEY_BASE
openssl rand -hex 32   # COLLABORATIVE_SERVER_SECRET
openssl rand -hex 16   # POSTGRES_PASSWORD
```

```ini
TAG=17.9.3-slim
OPENPROJECT_HTTPS=true
SECRET_KEY_BASE=CHANGE_ME_HEX_64
OPENPROJECT_HOST__NAME=pm.example.com
PORT=127.0.0.1:8080
POSTGRES_VERSION=17.11
POSTGRES_PASSWORD=CHANGE_ME_HEX_16
DATABASE_URL=postgres://postgres:CHANGE_ME_HEX_16@db/openproject?pool=20&encoding=unicode&reconnect=true
PGDATA=pgdata
OPDATA=opdata
COLLABORATIVE_SERVER_URL=wss://pm.example.com/hocuspocus
COLLABORATIVE_SERVER_SECRET=CHANGE_ME_HEX_32
```

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

- `TAG=17.9.3-slim`: الملف الأصلي يستخدم `17-slim`، أي آخر إصدار من السلسلة 17 في لحظة السحب Pull، ونحن نثبته على رقم كامل حتى لا يتغير الإصدار عند إعادة بناء السيرفر.
- `POSTGRES_VERSION`: ملف Compose يستخدم `postgres:13` إذا لم تحدد القيمة، وقد كتب المشروع في الملف نفسه أن هذا للحفاظ على التثبيتات القديمة، بينما التوثيق يقول إن الدعم الرسمي يبدأ من الإصدار 16، لذلك حددناه على 17.11.
- `POSTGRES_PASSWORD` و`DATABASE_URL`: كلمة المرور الافتراضية في الملف هي `p4ssw0rd` ومنشورة للجميع، وإذا غيرت واحدة دون الأخرى فلن يتصل التطبيق بقاعدة البيانات، فاكتبهما معاً.
- `PGDATA` و`OPDATA`: الملف المثال يضعهما مجلدين على السيرفر هما `/var/lib/postgresql/data` و`/var/openproject/assets`، وفي هذه الحالة يطلب التوثيق أن تنشئ مجلد المرفقات وتعطيه المالك `1000:1000`. ونحن استخدمنا Volumes باسمين، فيديرها Docker ولا تحتاج إلى ضبط الصلاحيات.
- `PORT=127.0.0.1:8080`: الافتراضي في ملف Compose هو `8080` على كل الواجهات، أي أن OpenProject يصبح مفتوحاً للإنترنت مباشرة بدون TLS، لذلك ربطناه بالواجهة المحلية فقط ليصل إليه ال Reverse Proxy وحده.
- `OPENPROJECT_HOST__NAME`: هو الاسم الوحيد المقبول في الطلبات، وسوف نرى أثره في قسم المشكلات الشائعة.

وأما memcached فالملف يستخدم `memcached` بدون إصدار، لذلك ثبتناه في ملف `docker-compose.override.yml` بجانب الملف الأصلي، وبهذا الشكل لا تعدل الملف الأصلي ويبقى `git pull` سهلاً عند التحديث:

```yaml
services:
  cache:
    image: memcached:1.6.45-alpine
```

### التشغيل الأول بالترتيب الصحيح

التوثيق يكتفي بالأمر `docker compose up -d --build --pull always`، وهذا يشغل كل الخدمات في نفس اللحظة، وعند تشغيله على سيرفر قرصه بطيء ظهرت لنا مشكلة: خدمة `seeder` بدأت قبل أن تجهز قاعدة البيانات، ثم فشلت في إنشاء الجداول ودخلت في حلقة إعادة تشغيل، وفي سجلاتها الخطأ التالي يتكرر:

```bash
psql:/app/db/structure.sql:255: ERROR:  relation "ar_internal_metadata" already exists
rake aborted!
PG::DuplicateTable: ERROR:  relation "announcements" already exists
```

وفي نفس الوقت كانت خدمة `web` تعيد التشغيل لأن التعديلات لم تطبق، وفي سجلاتها `ActiveRecord::PendingMigrationError` و`You have 154 pending migrations`. والسبب أن أول تهيئة لقاعدة البيانات انقطعت في منتصفها، فبقيت جداول ناقصة تمنع كل محاولة بعدها. لذلك الحل الأسلم في التثبيت الجديد أن تشغل قاعدة البيانات أولاً، ثم `seeder` وحده حتى ينتهي، ثم بقية الخدمات:

```bash
cd /opt/openproject
sudo docker compose pull
sudo docker compose up -d db cache
until sudo docker compose exec -T db pg_isready -U postgres -h localhost; do sleep 3; done
sudo docker compose run --rm --no-deps seeder
sudo docker compose up -d --build
```

وعندما ينتهي `seeder` سوف تجد آخر سطر في مخرجه كما يلي، وقد أخذ في اختبارنا 211 ثانية:

```bash
*** Seeding MCP configuration
```

وإذا وقعت في الحلقة السابقة في تثبيت جديد ليس فيه بيانات، فاحذف ال Volumes بالأمر `docker compose down -v` ثم اتبع الترتيب أعلاه. ولا تفعل ذلك أبداً في تثبيت فيه بيانات حقيقية، والسبب أن `-v` يحذف قاعدة البيانات والمرفقات معاً. وبعد أقل من دقيقتين تصبح حالة `web` صحية:

```bash
sudo docker compose ps -a --format '{{.Service}} {{.Status}}'
```

```bash
autoheal Up About a minute (healthy)
cache Up 5 minutes
cron Up About a minute
db Up 5 minutes
hocuspocus Up About a minute
proxy Up About a minute
seeder Exited (0) 16 seconds ago
web Up About a minute (healthy)
worker Up About a minute
```

## الإعداد الأول

### حساب المدير واللغة العربية

الدخول الأول باسم المستخدم `admin` وكلمة المرور `admin`، وسوف يطلب منك OpenProject تغييرها فوراً بكلمة لا تقل عن عشرة أحرف فيها حرف كبير وصغير ورقم ورمز. وبعد الدخول لاحظ أمرين:

- صفحة الدخول تعرض رابط Create a new account، أي أن التسجيل الذاتي Self-registration ظاهر، فراجع إعداده من Administration ثم Authentication ثم Login and registration، وقرر من يحق له إنشاء حساب.
- أنشأ `seeder` مشروعين تجريبيين باسم Demo project وScrum project، وهما مفيدان للتعرف على الأداة، ولكن احذفهما أو أرشفهما قبل دعوة الموظفين.

والعربية موجودة في OpenProject، ولكنها غير مفعلة افتراضياً، فقائمة اختيار اللغة في أول دخول لا تعرضها، وتفعيلها يكون من Administration ثم System settings ثم Languages، وبعدها يختارها كل مستخدم لنفسه من My account ثم Language and region:

![قائمة اللغات المتاحة في إعدادات OpenProject مع تفعيل العربية](https://arabroot.io/content/images/2026/10/openproject-02-languages.webp)

تفعيل العربية في اللغات المتاحة

### المشروع ووحداته Modules

لكل مشروع وحدات Modules تفعلها من Project settings ثم Modules، والصورة التالية تبين الوحدات في Community Edition، ولاحظ الشارة البرتقالية بجانب Resource management وTeam planners، فهما من Enterprise، وأما Gantt والميزانيات والوقت والتكاليف وGitHub وGitLab فبدون شارة:

![وحدات المشروع في OpenProject مع شارة Enterprise بجانب Resource management وTeam planners](https://arabroot.io/content/images/2026/10/openproject-03-modules.webp)

وحدات المشروع، والشارة البرتقالية تعني Enterprise

## التخطيط بمخطط Gantt

### حزم العمل والعلاقات Relations

كل شيء في OpenProject حزمة عمل Work Package: المرحلة، والمهمة، والحدث الرئيسي Milestone، ولكل حزمة نوع Type وحالة Status وتواريخ، ويمكن أن تكون لها حزمة أب Parent. وقد بنينا مشروعاً بمرحلتين، في كل مرحلة مهام، وبينهما حدثان رئيسيان هما «اعتماد التصميم» و«الإطلاق»، ثم ربطنا كل حزمة بالتي قبلها بعلاقة Follows، أي «تبدأ بعد انتهاء»:

![مخطط Gantt في OpenProject لمشروع بمرحلتين ومهام عربية وحدثين رئيسيين مع خطوط الاعتماديات](https://arabroot.io/content/images/2026/10/openproject-04-gantt.webp)

مخطط Gantt بالمراحل والمهام والأحداث الرئيسية والاعتماديات

والفكرة المهمة هنا هي الجدولة التلقائية Automatic Scheduling: عندما تربط حزمة بأخرى بعلاقة Follows، يحسب OpenProject تاريخ بدايتها من تاريخ انتهاء التي قبلها، فإذا تأخرت مهمة «جمع المتطلبات» يومين، تحركت كل المهام بعدها يومين حتى «الإطلاق»، وهذا بالضبط ما يحتاجه مكتب المشاريع ليرى أثر التأخير قبل وقوعه.

### أيام العمل Working Days: أول ما تضبطه

هناك مشكلة رئيسية سوف تواجهها إذا كان أسبوع العمل في مؤسستك يبدأ يوم الأحد، فإعداد OpenProject الافتراضي يعتبر السبت والأحد عطلة، والجدولة التلقائية تتخطى أيام العطلة، وبالتالي فكل تاريخ يحسبه سوف يكون خاطئاً بالنسبة لك. والإعداد في Administration ثم Calendars and dates ثم Working days and hours:

![إعداد أيام العمل في OpenProject: من الأحد إلى الخميس](https://arabroot.io/content/images/2026/10/openproject-05-working-days.webp)

أسبوع عمل من الأحد إلى الخميس

ولكي ترى الأثر، هذه تواريخ نفس المشروع قبل التغيير وبعده، وقد أعاد OpenProject جدولة كل الحزم المرتبطة تلقائياً:

| حزمة العمل                       | الاثنين إلى الجمعة (الافتراضي) | الأحد إلى الخميس       |
| -------------------------------- | ------------------------------ | ---------------------- |
| المرحلة الثانية: التطوير (بداية) | 13 نوفمبر 2026، وهو يوم جمعة   | 15 نوفمبر 2026         |
| الربط مع الدخول الموحد SSO       | 30 نوفمبر إلى 9 ديسمبر         | 30 نوفمبر إلى 9 ديسمبر |
| الإطلاق                          | 18 ديسمبر 2026                 | 20 ديسمبر 2026         |

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

## اللوحات Boards

إذا كان مكتب المشاريع يتابع الجدول، فالفريق يتابع اللوحة، وفي OpenProject ستة أنواع من اللوحات كلها متاحة في Community: لوحة Basic تبنيها يدوياً، ولوحة Kanban بأعمدة الحالة، ولوحات تبني أعمدتها تلقائياً حسب المسؤول Assignee أو الإصدار Version أو المشروع الفرعي Subproject أو الحزمة الأب Parent-child. ولاحظ أن لوحة Kanban تبدأ بعمود New فقط، وتضيف بقية الأعمدة من Add list to board، وسحب البطاقة إلى عمود آخر يغير حالتها:

![لوحة Kanban في OpenProject بثلاثة أعمدة New وIn progress وClosed](https://arabroot.io/content/images/2026/10/openproject-06-board.webp)

لوحة Kanban لنفس المشروع

## الوقت والتكاليف والميزانيات

هذا هو القسم الذي يفرق OpenProject عن أغلب أدوات المهام، فأنت تسجل الوقت على حزمة العمل، ولكل مستخدم سعر ساعة Hourly Rate، ولكل مشروع ميزانية فيها تكاليف عمالة Labor وتكاليف وحدات Unit Costs، فيعرض لك OpenProject المصروف والمتبقي من كل ميزانية. والترتيب الذي يعمل كما يلي:

1. فعل وحدتي Time and costs وBudgets في المشروع.
2. حدد سعر الساعة لكل مستخدم من Administration ثم Users ثم Rate history، وفي مثالنا 50 للساعة.
3. أنشئ أنواع التكاليف Cost Types من Administration ثم Time and costs ثم Cost types، مثل «رخص برمجية» بسعر 120 للرخصة.
4. أنشئ الميزانية من وحدة Budgets في المشروع: 10 رخص و120 ساعة عمل.
5. اربط حزم العمل بالميزانية من حقل Budget في كل حزمة، ثم سجل الوقت عليها.

وقد يتساءل البعض: لماذا رفض OpenProject حفظ الميزانية بالخطأ `Planned labor costs is invalid` رغم أن الأرقام صحيحة؟ والإجابة أن سطر تكاليف العمالة يجب أن يكون لمستخدم عضو في المشروع، وفي مثالنا أنشأنا المشروع بحساب المدير عبر ال API فلم يصبح عضواً فيه، وبعد إضافته عضواً في المشروع قبلت الميزانية مباشرة. والصورة التالية تبين الميزانية بعد تسجيل 20 ساعة على مهمة «تطوير نموذج الطلب»:

![صفحة ميزانية في OpenProject: المخطط 7200 والمصروف 1000 والمتبقي 6200](https://arabroot.io/content/images/2026/10/openproject-07-budget.webp)

ميزانية المرحلة الثانية: المخطط والمصروف والمتبقي

المخطط 7,200 يورو (1,200 للرخص و6,000 لـ 120 ساعة)، والمصروف 1,000 أي 20 ساعة بسعر 50، والمتبقي 6,200، ونسبة الصرف 14%. ولاحظ أن الصفحة تعرض المصروف بإشارة سالبة `-1,000.00 €` بينما الحساب نفسه صحيح. وأما تقرير التكاليف Cost Report فيجمع الساعات حسب حزمة العمل والأسبوع، ومنه تصدر XLS أو PDF:

![تقرير الوقت في OpenProject: الساعات لكل حزمة عمل في ثلاثة أسابيع بمجموع 33.5 ساعة](https://arabroot.io/content/images/2026/10/openproject-08-cost-report.webp)

تقرير الساعات حسب الحزمة والأسبوع

والعملة الافتراضية هي اليورو، وتغيرها من Administration ثم Time and costs. ولاحظ أن قيود تسجيل الوقت، مثل منع تسجيل أكثر من عدد معين من الساعات في اليوم أو إلزام وقت البداية والنهاية، تحمل في نفس الصفحة عبارة Available starting with the Professional enterprise plan.

## الدخول الموحد: LDAP وOpenID Connect

في المؤسسات يكون الدخول الموحد شرطاً قبل أي شيء آخر، وهنا يجب أن تعرف الحدود بدقة:

- [اتصالات LDAP](https://www.openproject.org/docs/system-admin-guide/authentication/ldap-connections/?ref=arabroot.io) متاحة في Community، فتربط OpenProject بـ Active Directory أو OpenLDAP، ويدخل الموظف باسم مستخدمه وكلمة مروره في الشبكة، ويمكن إنشاء الحسابات تلقائياً عند أول دخول.
- مزامنة مجموعات LDAP مع مجموعات OpenProject، أي أن ينضم الموظف إلى فريق المشروع تلقائياً لأنه في مجموعة معينة في AD، من خطة Premium.
- [OpenID Connect](https://www.openproject.org/docs/system-admin-guide/authentication/openid-providers/?ref=arabroot.io) وSAML، أي الربط مع Keycloak أو Microsoft Entra ID أو [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/)، من خطة Professional، والصفحة نفسها في Community تعرض الرسالة التالية:

![صفحة OpenID providers في OpenProject مع رسالة أنها متاحة من خطة Professional، والشارات بجانب SAML وLDAP group synchronization وSCIM](https://arabroot.io/content/images/2026/10/openproject-09-oidc-enterprise.webp)

OpenID Connect وSAML ومزامنة مجموعات LDAP بشارة Enterprise

لذلك إذا كانت مؤسستك تستخدم AD فالحل الأنسب في Community هو LDAP، وإذا كان لديك مزود هوية Identity Provider يعمل بـ OIDC فقط فأنت تحتاج خطة Professional. ولم نربط سيرفر LDAP حقيقياً في هذا الاختبار، وإنما تحققنا أن صفحة LDAP connections تعمل في Community بدون شارة.

## GitHub وGitLab والترحيل من Jira

وحدتا GitHub وGitLab متاحتان في Community، وفكرتهما أن يكتب المطور `OP#43` في وصف ال Pull Request أو ال Merge Request، فيظهر في حزمة العمل رقم 43 تبويب فيه حالة الطلب ونتائج ال Checks. والربط مع GitHub يتم بـ [Webhook](https://www.openproject.org/docs/system-admin-guide/integrations/github-integration/?ref=arabroot.io) في كل مستودع يرسل إلى `https://pm.example.com/webhooks/github?key=API_KEY`، وضع له سراً Webhook Secret، والسبب أن التوثيق يقول إن الطلبات بدون سر تقبل بدون التحقق من التوقيع. ولم نختبر الربط مع مستودع حقيقي لأنه يحتاج سيرفراً يصل إليه GitHub من الإنترنت.

وأما الترحيل من Jira فالأداة موجودة في Community في Administration ثم Import ثم Jira Migrator، ولكن انتبه لثلاثة قيود تظهر في الصفحة نفسها و[في التوثيق](https://www.openproject.org/docs/installation-and-operations/jira-migration/?ref=arabroot.io): الأداة تجريبية Beta وينصح باستخدامها في بيئة تجربة فقط، وتدعم Jira Server وData Center بالإصدارين 10 و11 فقط ولا تدعم Jira Cloud، وتحتاج تفعيل المعرفات النصية للمشاريع Project-based semantic identifiers مثل `PRJ-123` قبل البدء. وتنقل المشاريع والإصدارات وال Issues بوصفها وتاريخها وتعليقاتها ومرفقاتها، أما العلاقات بين ال Issues وتوزيعها على السبرنتات فقادمة:

![صفحة Jira Migrator في OpenProject: البيانات المدعومة والقادمة وتحذير المعرفات النصية](https://arabroot.io/content/images/2026/10/openproject-10-jira-migrator.webp)

أداة Jira Migrator في Community Edition

ولم نختبر الترحيل نفسه لأنه يحتاج سيرفر Jira Data Center، ولكن إذا كنت ممن يشغلون Jira Data Center وتبحث عن بديل قبل [نهاية عمره في مارس 2029](https://www.atlassian.com/licensing/data-center-end-of-life?ref=arabroot.io)، فهذه الأداة هي أول ما تجربه على نسخة من بياناتك.

### ال API بمفتاح Token

كل ما سبق متاح عبر [API v3](https://www.openproject.org/docs/api/?ref=arabroot.io)، وتنشئ المفتاح من My account ثم Access tokens ثم API token، ولاحظ أن المفتاح يبدأ بـ `opapi-`، وأن الواجهة تعرضه مرة واحدة فقط. ويرسل باسم المستخدم `apikey`:

```bash
TOKEN=opapi-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl -s -u apikey:$TOKEN "https://pm.example.com/api/v3/projects/portal/work_packages?pageSize=20" \
  | jq -r '._embedded.elements[] | "\(.id) \(._links.type.title) \(.startDate // "") \(.dueDate // .date) \(.subject)"'
```

والمخرج سوف يكون كما يلي، وهو نفس الجدول بعد ضبط أيام العمل:

```bash
38 Summary task 2026-11-02 2026-11-11 المرحلة الأولى: التحليل
40 Task 2026-11-08 2026-11-11 اعتماد وثيقة المتطلبات
41 Milestone  2026-11-12 اعتماد التصميم
42 Summary task 2026-11-15 2026-12-17 المرحلة الثانية: التطوير
43 Task 2026-11-15 2026-11-29 تطوير نموذج الطلب
44 Task 2026-11-30 2026-12-09 الربط مع الدخول الموحد SSO
45 Task 2026-12-10 2026-12-17 اختبار القبول
46 Milestone  2026-12-20 الإطلاق
```

وهذا مفيد لمكتب المشاريع الذي يريد لوحة مؤشرات خاصة به، أو تقريراً أسبوعياً يرسل تلقائياً بدل جمع الأرقام يدوياً.

## هل تعمل العربية في OpenProject؟

الترجمة العربية موجودة ولكنها غير مكتملة، وقد قسناها من ملفات اللغة في الإصدار 17.9.3 نفسه: من 5,550 نصاً في ملف الواجهة الخلفية [ar.yml](https://github.com/opf/openproject/blob/v17.9.3/config/locales/crowdin/ar.yml?ref=arabroot.io) يختلف عن الإنجليزية 1,539 نصاً فقط، أي حوالي 28%، ومن 922 نصاً في ملف الواجهة الأمامية يختلف 422، أي حوالي 46%، والباقي يظهر بالإنجليزية. والنتيجة في الواجهة كما يلي:

![قائمة حزم العمل في OpenProject بالواجهة العربية: عناوين عربية وأجزاء كثيرة بالإنجليزية والتخطيط من اليسار](https://arabroot.io/content/images/2026/10/openproject-11-ar-work-packages.webp)

الواجهة العربية: ترجمة جزئية والتخطيط يبقى من اليسار إلى اليمين

| ما اختبرناه                         | النتيجة                                                                                                                                                                                                                    |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| اتجاه الواجهة                       | يبقى من اليسار إلى اليمين حتى مع اختيار العربية، فالقائمة الجانبية على اليسار والأعمدة تقرأ من اليسار                                                                                                                      |
| الترجمة                             | العناوين والأزرار الرئيسية عربية، وكثير من القوائم إنجليزية مثل Latest activity وInclude projects وBaseline وAdd list to board، وبعض المصطلحات غريبة، مثل «مجموعات العمل» لـ Work packages، و«رمزالوصول المميز» بدون مسافة |
| الأنواع والحالات والأولويات         | تبقى Task وNew وNormal بالإنجليزية لأنها بيانات أنشأها seeder بالإنجليزية، ويستطيع المدير إعادة تسميتها                                                                                                                    |
| عناوين حزم العمل العربية            | تظهر صحيحة في القائمة واللوحة وGantt، والعنوان الطويل يقطع من جهة اليسار                                                                                                                                                   |
| Gantt بالواجهة العربية              | التواريخ بجانب الأشرطة تظهر بترتيب مختلط مثل 2/2026/11                                                                                                                                                                     |
| تصدير PDF لقائمة الحزم ولحزمة واحدة | الحروف العربية متصلة ومقروءة، والجدول يبقى من اليسار، وتذييل الصفحة يعرض مربعات بدل اسم المشروع                                                                                                                            |
| تصدير CSV                           | UTF-8 مع BOM، فيفتح في Excel بالعربية مباشرة                                                                                                                                                                               |

![مخطط Gantt في الواجهة العربية مع تواريخ بترتيب مختلط بجانب الأشرطة](https://arabroot.io/content/images/2026/10/openproject-12-ar-gantt.webp)

Gantt بالواجهة العربية: لاحظ ترتيب التواريخ بجانب الأشرطة

![لوحة Kanban في الواجهة العربية مع تواريخ بأسماء الأشهر العربية](https://arabroot.io/content/images/2026/10/openproject-13-ar-board.webp)

اللوحة بالواجهة العربية

![ملف PDF صدره OpenProject لقائمة حزم العمل بعناوين عربية مقروءة ومربعات في التذييل](https://arabroot.io/content/images/2026/10/openproject-14-pdf-export.webp)

تصدير PDF: العربية مقروءة، والتذييل فيه مربعات

والخلاصة العملية: البيانات العربية والتقارير المصدرة تعمل بشكل جيد، وهذا أهم ما يحتاجه مكتب المشاريع لتقارير الإدارة، أما الواجهة العربية فنصفها بالإنجليزية واتجاهها من اليسار، فأغلب الفرق التقنية سوف تفضل الواجهة الإنجليزية مع بيانات عربية، وتستطيع أن تساهم في تحسين الترجمة من [مشروع الترجمة على Crowdin](https://crowdin.com/project/openproject?ref=arabroot.io).

## ربط النطاق مع شهادة TLS

ضع أمام OpenProject Reverse Proxy مثل [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/) يوجه `pm.example.com` إلى `http://127.0.0.1:8080` مع دعم WebSocket، والسبب أن خدمة `hocuspocus` تعمل عبر WebSocket على المسار `/hocuspocus`. وتأكد من ثلاث قيم في `.env`: `OPENPROJECT_HTTPS=true`، و`OPENPROJECT_HOST__NAME` بنفس النطاق، و`COLLABORATIVE_SERVER_URL` يبدأ بـ `wss://`، ثم شغل `docker compose up -d`. ولم نختبر إصدار شهادة حقيقية لأنه يحتاج نطاقاً عاماً، وإنما اختبرنا الوصول عبر HTTP محلياً مع `OPENPROJECT_HTTPS=false`.

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

1. `docker compose ps`: حالة `web` هي `(healthy)` و`seeder` هي `Exited (0)`.
2. أنشئ حزمة عمل وارفع لها مرفقاً، ثم نزله من جهاز آخر، فهذا يختبر Volume المرفقات.
3. صدر قائمة الحزم PDF، فإذا وصل الملف فخدمة `worker` تعمل، لأن التصدير مهمة في الخلفية.
4. غير تاريخ انتهاء حزمة لها حزم تتبعها، وتأكد أن الحزم التالية تحركت، فهذا يختبر الجدولة التلقائية وأيام العمل.
5. من ال API: `curl -u apikey:$TOKEN https://pm.example.com/api/v3/projects` يرجع JSON بالمشاريع.

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

المستودع فيه ملف `docker-compose.control.yml` بخدمة اسمها `backup`، وهي تضغط مجلد قاعدة البيانات ومجلد المرفقات كما هما، ويطلب التوثيق إيقاف الخدمات قبلها، لأن نسخ ملفات PostgreSQL وهي تعمل قد ينتج نسخة غير متسقة. والطريقة التي نفضلها هي التي يشرحها [توثيق النسخ الاحتياطي](https://www.openproject.org/docs/installation-and-operations/operation/backing-up/?ref=arabroot.io) نفسه: `pg_dump` لقاعدة البيانات وهي تعمل، وأرشيف لـ Volume المرفقات:

```bash
cd /opt/openproject
mkdir -p backups
docker compose exec -T db pg_dump -U postgres -d openproject -x -O > backups/openproject.sql
docker run --rm -v openproject_opdata:/data:ro -v "$PWD/backups":/backup alpine:3.22 \
  tar czf /backup/opdata.tar.gz -C /data .
cp .env backups/
```

في الأوامر أعلاه لاحظ أن اسم ال Volume يبدأ باسم المجلد، فمع المجلد `openproject` يكون `openproject_opdata`، وأن نسخ `.env` ضروري، فتغيير `SECRET_KEY_BASE` يلغي كل الجلسات Sessions، ومعه كلمة مرور قاعدة البيانات. ثم جربنا أسوأ حالة كما في [توثيق الاستعادة](https://www.openproject.org/docs/installation-and-operations/operation/restoring/?ref=arabroot.io): حذفنا كل الخدمات وال Volumes، ثم شغلنا قاعدة البيانات وحدها، واستعدنا البيانات قبل تشغيل الباقي:

```bash
docker compose down -v
docker compose up -d db
until docker compose exec -T db pg_isready -U postgres -h localhost; do sleep 3; done
docker compose exec -T db psql -U postgres -d openproject -q < backups/openproject.sql
docker run --rm -v openproject_opdata:/data -v "$PWD/backups":/backup alpine:3.22 \
  sh -c 'tar xzf /backup/opdata.tar.gz -C /data && chown -R 1000:1000 /data'
docker compose up -d
```

ولاحظ أننا استعدنا قبل تشغيل `seeder`، والسبب أنه لو عمل على قاعدة فارغة لأنشأ قاعدة جديدة ومشاريع تجريبية. وبعد الاستعادة طابقت الأرقام ما قبل الحذف تماماً: 46 حزمة عمل، و6 تسجيلات وقت بمجموع 33.5 ساعة، و9 مرفقات، ونزلنا المرفق `requirements.txt` بمحتواه العربي، واشتغل مفتاح ال API القديم بدون تغيير، وأصبحت حالة `web` صحية بعد 65 ثانية.

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

1. اقرأ [ملاحظات الإصدار](https://www.openproject.org/docs/release-notes/?ref=arabroot.io)، وانتبه للإصدار الرئيسي القادم 18، فقد كتب المشروع في ملف Compose أن قيمة PostgreSQL الافتراضية سوف تتغير معه.
2. خذ نسخة احتياطية كما في القسم السابق.
3. داخل نفس السلسلة: غير `TAG` إلى الإصدار الجديد، مثل `17.9.4-slim` عند صدوره، ثم شغل `git pull origin stable/17` و`docker compose pull` و`docker compose up -d --build`، وسوف يطبق `seeder` التعديلات على قاعدة البيانات قبل أن تعمل `web`.
4. إلى سلسلة جديدة: انتقل إلى الفرع الجديد مثل `stable/18` واتبع خطوات [صفحة التثبيت](https://www.openproject.org/docs/installation-and-operations/installation/docker-compose/?ref=arabroot.io) في قسم التحديث.

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

### seeder يعيد التشغيل مع DuplicateTable

انقطعت أول تهيئة لقاعدة البيانات في منتصفها. في التثبيت الجديد فقط: `docker compose down -v` ثم شغل `db` أولاً ثم `seeder` وحده ثم الباقي، كما في قسم التشغيل الأول.

### الخطأ 400 مع Invalid host\_name configuration

فتحت OpenProject بعنوان غير المكتوب في `OPENPROJECT_HOST__NAME`، فمثلاً إذا كانت القيمة `localhost:8080` وفتحت `http://127.0.0.1:8080` يرد السيرفر بالرمز 400 والنص `Invalid host_name configuration`. افتحه بنفس الاسم، أو أضف الاسم الآخر في `OPENPROJECT_ADDITIONAL__HOST__NAMES` مع الإبقاء على القيمة `web` فيه، مثل `web,203.0.113.10`، والسبب أن خدمة `hocuspocus` تتصل بالتطبيق بهذا الاسم.

### Planned labor costs is invalid عند حفظ الميزانية

المستخدم في سطر تكاليف العمالة ليس عضواً في المشروع. أضفه من Members ثم احفظ الميزانية مرة أخرى.

### ال API يرد بأن بيانات الاعتماد غير صحيحة

عندما تكون الواجهة بالعربية تأتي الرسالة بالعربية: «لم تقدم بيانات الاعتماد الصحيحة.»، وأكثر سبب لها أن المفتاح نسخ بدون البادئة `opapi-`، فالمفتاح الكامل هو الذي يبدأ بها.

## الخلاصة

- OpenProject Community تعطي مكتب المشاريع ما يحتاجه فعلاً بدون ترخيص: Gantt بالاعتماديات والجدولة التلقائية، والميزانيات، والوقت والتكاليف، واللوحات بأنواعها، وLDAP.
- OpenID Connect وSAML من خطة Professional، ومزامنة مجموعات LDAP من Premium، ومخطط الفريق وإدارة الموارد من Enterprise، فاحسب ذلك قبل القرار.
- ثبت `TAG` وPostgreSQL على أرقام كاملة، وغير كلمة مرور قاعدة البيانات في `POSTGRES_PASSWORD` و`DATABASE_URL` معاً، واربط المنفذ بـ `127.0.0.1`.
- اضبط أيام العمل في اليوم الأول، لأن الجدولة كلها تعتمد عليها.
- العربية تعمل في البيانات والتصدير، والواجهة العربية مترجمة جزئياً واتجاهها من اليسار.
- انسخ قاعدة البيانات بـ `pg_dump` ومعها Volume المرفقات و`.env`، وجرب الاستعادة.

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

- أكتوبر 2026: كتابة الدليل واختباره على OpenProject Community 17.9.3.