تخيل هذا السيناريو: أنت مطور Flutter، تقضي ساعات طويلة في بناء واجهة مستخدم رائعة، ثم تصل إلى مرحلة ربط التطبيق بالخادم (Backend). فجأة، تجد نفسك مضطراً لتعلم لغة جديدة، أو التعامل مع إطارات عمل معقدة، أو كتابة مئات الأسطر من أكواد الـ Boilerplate فقط لإنشاء نقطة اتصال (Endpoint) بسيطة. ناهيك عن مشاكل عدم تطابق البيانات بين العميل والخادم. هذه المعاناة اليومية تستهلك وقتك وطاقتك، وتؤخر إطلاق مشروعك.
هنا يأتي دور Serverpod كحل جذري لهذه المشكلة. في هذا المقال، سنقدم لك شرح Serverpod الشامل، وكيف يمكن لهذا الإطار أن يغير طريقة بناء تطبيقاتك بالكامل، من خلال توحيد لغة البرمجة (Dart) بين العميل والخادم.
ما هو Serverpod؟
Serverpod هو إطار عمل Backend مفتوح المصدر ومصمم خصيصاً لمطوري Flutter. الفكرة الأساسية بسيطة لكنها قوية: كتابة كود الخادم بالكامل باستخدام لغة Dart.
يتيح لك Serverpod تعريف نقاط الاتصال (Endpoints) على الخادم، ثم استدعاءها مباشرة من تطبيق Flutter الخاص بك كما لو كنت تستدعي دالة محلية، دون الحاجة لكتابة أي كود إضافي للربط. الأداة تقوم بتحليل كود الخادم وتوليد واجهة Dart للعميل وكلاسات البيانات تلقائياً.
لماذا تهتم بـ Serverpod؟
إذا كنت تتساءل عما يميز Serverpod عن غيره من الحلول، فإليك الأسباب التي تجعله يستحق وقتك:
- لغة واحدة للجميع: استخدام Dart في كامل الـ Stack يعني تقليل التشتت (Context-switching) ومشاركة النماذج (Models) بسهولة بين التطبيق والخادم.
- قابلية التوسع (Scalability): الإطار مصمم لينمو مع مشروعك، بدءاً من مشاريع الهواة وحتى التطبيقات التي تخدم ملايين المستخدمين النشطين، دون الحاجة لتغيير سطر واحد من الكود.
- ORM متكامل: تعامل مع قاعدة البيانات بلغة Dart الأصيلة بدلاً من كتابة استعلامات SQL معقدة. كل شيء Type-safe مع دعم كامل لميزة Null-safety.
- بيانات آنية (Real-time): يمكنك دفع البيانات من الخادم باستخدام Dart Streams دون القلق حول تعقيدات دورة حياة WebSocket.
- مفتوح ومجاني: تجنب الارتباط بمزود واحد (Vendor lock-in). يمكنك نشر خادمك في أي مكان يدعم تشغيل Dart.
كيف تبدأ؟
قبل البدء، تأكد من تثبيت Flutter و Docker على جهازك (حيث نستخدم Docker لتشغيل قاعدة بيانات PostgreSQL محلياً).
لتثبيت Serverpod CLI، افتح الـ Terminal ونفذ الأمر التالي:
dart pub global activate serverpod_cli
هذا الأمر يقوم بتثبيت أداة سطر الأوامر الخاصة بـ Serverpod عالمياً على جهازك.
تحقق من نجاح التثبيت:
$ serverpod
إذا ظهرت قائمة المساعدة فالتثبيت ناجح.
إضافة VS Code (موصى بها)
إضافة Serverpod لـ VS Code تتيح تشخيصاً فورياً وتلوين صياغي لملفات النماذج في مشروعك. يمكنك تثبيتها من VS Code Marketplace أو البحث عن Serverpod مباشرةً داخل VS Code.
تثبيت Serverpod Insights (موصى به)
Serverpod Insights تطبيق مرافق يتيح لك الوصول إلى سجلات السيرفر ومؤشرات الصحة. متاح لـ Mac وWindows حالياً.
لإنشاء مشروع جديد، استخدم الأمر:
serverpod create my_project
هذا الأمر سينشئ بنية المشروع التي تتضمن كود الخادم، كود التواصل (Client)، وتطبيق Flutter جاهز للاتصال بالخادم المحلي.
نصيحة
يجب أن يكون اسم المشروع اسم Dart package صالحاً: يبدأ بحرف صغير ويحتوي فقط على حروف صغيرة وأرقام وشرطات سفلية. مثلاً
my_projectصالح، أماMyCounterفغير صالح.
بعد تشغيل الأمر ستُنشأ البنية التالية:
my_project/
├── my_project_server/ # كود السيرفر
├── my_project_client/ # كود التواصل بين التطبيق والسيرفر
└── my_project_flutter/ # تطبيق Flutter جاهز للاتصال بالسيرفر المحلي
لتشغيل قاعدة البيانات والخادم، انتقل إلى مجلد الخادم ونفذ الأوامر التالية:
cd my_project/my_project_server
docker compose up -d
dart run bin/main.dart --apply-migrations
تشغيل قاعدة البيانات
ابدأ قاعدة البيانات عبر Docker:
$ cd my_project/my_project_server
$ docker compose up
لتشغيلها في الخلفية:
$ docker compose up -d
تشغيل السيرفر
عند أول تشغيل نحتاج لتطبيق الـ migrations على قاعدة البيانات:
$ cd my_project/my_project_server
$ dart run bin/main.dart --apply-migrations
السيرفر الآن متاح على http://localhost:8080 وخادم الويب على http://localhost:8082.
تشغيل تطبيق Flutter
$ cd my_project/my_project_flutter
$ flutter run -d chrome
هذه الأوامر تقوم بتشغيل قاعدة البيانات في الخلفية باستخدام Docker، ثم تشغيل الخادم وتطبيق التحديثات (Migrations) الأولية على قاعدة البيانات.
نصائح ومزالق يجب تجنبها
- تسمية المشاريع: تأكد من أن اسم مشروعك يتبع قواعد تسمية حزم Dart (حروف صغيرة، أرقام، وشرطات سفلية فقط). اسم مثل
MyProjectسيؤدي إلى خطأ. - إدارة الحالة (State Management): تذكر أن دوال الخادم يجب أن تكون عديمة الحالة (Stateless). تجنب استخدام المتغيرات العامة (Global variables) لتخزين البيانات بين الطلبات.
- استخدم الإضافات: نوصي بشدة بتثبيت إضافة Serverpod لـ VS Code للحصول على تلوين صياغي وتشخيص فوري لملفات النماذج (
.spy.yaml).
إنشاء Endpoint Methods
مع Serverpod، استدعاء endpoint method على السيرفر بسيط مثل استدعاء دالة محلية في تطبيقك.
إنشاء مشروع جديد
serverpod create magic_recipe
💡 نصيحة
افتح دائماً المجلد الجذري للمشروع في IDE الخاص بك. هذا يُسهّل التنقل بين حزم السيرفر والتطبيق ويمنع خروج المحلل عن المزامنة عند توليد الكود.
إضافة Gemini API للمشروع
سنستخدم Google Gemini API المجاني لتوليد الوصفات. أنشئ مفتاح API من هذه الصفحة وأضفه إلى ملف config/passwords.yaml:
# config/passwords.yaml
# هذا الملف لا يُضاف إلى git. يمكنك إضافة مفاتيح API هنا بأمان.
development:
geminiApiKey: '--- Your Gemini Api Key ---'
أضف حزمة dartantic_ai كاعتمادية للسيرفر:
$ cd magic_recipe_server
$ dart pub add dartantic_ai
إنشاء Endpoint جديد
أنشئ ملفاً جديداً في magic_recipe_server/lib/src/recipes/ باسم recipe_endpoint.dart:
import 'package:dartantic_ai/dartantic_ai.dart';
import 'package:serverpod/serverpod.dart';
/// هذا الـ endpoint يولد وصفات باستخدام Google Gemini API
class RecipeEndpoint extends Endpoint {
/// مرر نصاً يحتوي على المكونات واحصل على وصفة
Future<String> generateRecipe(Session session, String ingredients) async {
final geminiApiKey = session.passwords['geminiApiKey'];
if (geminiApiKey == null) {
throw Exception('Gemini API key not found');
}
final agent = Agent.forProvider(
GoogleProvider(apiKey: geminiApiKey),
chatModelName: 'gemini-2.5-flash-lite',
);
final prompt = 'Generate a recipe using: $ingredients';
final response = await agent.send(prompt);
final responseText = response.output;
if (responseText.isEmpty) {
throw Exception('No response from Gemini API');
}
return responseText;
}
}
ℹ️ معلومة
كي تتعرف Serverpod على الـ methods، يجب أن تُعيد Future أو Stream مع نوع محدد، وأن يكون أول بارامتر هو Session.
توليد الكود
$ cd magic_recipe_server
$ serverpod generate
استدعاء الـ Endpoint من العميل
بعد التوليد، استدعاء الـ endpoint من Flutter أصبح هكذا:
final result = await client.recipe.generateRecipe(
_textEditingController.text,
);
تشغيل التطبيق
💡 نصيحة
قبل تشغيل السيرفر، تأكد أنه لا يوجد سيرفر Serverpod آخر يعمل وأن حاويات Docker من مشاريع أخرى متوقفة لتجنب تعارض المنافذ.
$ cd magic_recipe_server
$ docker compose up -d
$ dart bin/main.dart --apply-migrations
$ cd magic_recipe_flutter
$ flutter run -d chrome
النماذج والبيانات
Serverpod يأتي مع نظام نمذجة بيانات قوي يستخدم ملفات YAML سهلة القراءة. يُولّد كلاسات Dart مع كامل كود الـ serialization والـ deserialization والاتصال بقاعدة البيانات.
إنشاء نموذج جديد
أنشئ ملفاً جديداً باسم recipe.spy.yaml في magic_recipe_server/lib/src/recipes/. استخدم اللاحقة .spy.yaml للدلالة على أنه Serverpod YAML:
### وصفة مولَّدة بالذكاء الاصطناعي
class: Recipe
fields:
### كاتب الوصفة
author: String
### نص الوصفة
text: String
### تاريخ الإنشاء
date: DateTime
### المكونات التي أدخلها المستخدم
ingredients: String
يمكنك استخدام معظم أنواع Dart الأصيلة أو أي نماذج أخرى عرّفتها في ملفات YAML أخرى، بالإضافة إلى List وMap وSet مع تحديد النوع.
توليد الكود
$ cd magic_recipe_server
$ serverpod generate
سيُنشئ هذا الملف recipe.dart في مجلد lib/src/generated ويحدّث كود العميل أيضاً.
استخدام النموذج في السيرفر
حدّث الـ endpoint ليعيد كائن Recipe بدلاً من String:
import 'package:magic_recipe_server/src/generated/protocol.dart';
class RecipeEndpoint extends Endpoint {
Future<Recipe> generateRecipe(Session session, String ingredients) async {
// ... كود توليد الوصفة ...
final recipe = Recipe(
author: 'Gemini',
text: responseText,
date: DateTime.now(),
ingredients: ingredients,
);
return recipe;
}
}
استخدام النموذج في التطبيق
بعد إعادة تشغيل serverpod generate، يمكنك استخدام النموذج في Flutter:
final result = await client.recipe.generateRecipe(
_textEditingController.text,
);
setState(() {
_resultMessage = '${result.author} on ${result.date}:\n${result.text}';
});
الأنواع المدعومة
| النوع | الوصف |
|---|---|
bool | قيمة منطقية |
int | عدد صحيح |
double | عدد عشري |
String | نص |
DateTime | تاريخ ووقت |
ByteData | بيانات ثنائية |
UuidValue | معرّف UUID |
List<T> | قائمة من نوع محدد |
Map<K,V> | قاموس من نوعين محددين |
نماذج مخصصة | كلاسات معرَّفة بـ .spy.yaml |
العمل مع قاعدة البيانات
Serverpod يستخدم PostgreSQL للتخزين الدائم ويوفر ORM متكاملاً يتيح لك التعامل مع قاعدة البيانات بلغة Dart بالكامل.
ربط النموذج بجدول في قاعدة البيانات
لربط نموذج بجدول، أضف خاصية table إلى ملف الـ YAML:
class: Recipe
table: recipe
fields:
author: String
text: String
date: DateTime
ingredients: String
بعد تشغيل serverpod generate، ولد الـ migration:
$ cd magic_recipe_server
$ serverpod create-migration
عمليات CRUD الأساسية
إدراج سجل
var recipe = Recipe(
author: 'Gemini',
text: recipeText,
date: DateTime.now(),
ingredients: ingredients,
);
recipe = await Recipe.db.insertRow(session, recipe);
البحث بالمعرّف
var found = await Recipe.db.findById(session, recipe.id!);
البحث بشرط
var recipes = await Recipe.db.find(
session,
where: (r) => r.author.equals('Gemini'),
);
التحديث
recipe.text = 'نص محدَّث';
await Recipe.db.updateRow(session, recipe);
الحذف
await Recipe.db.deleteRow(session, recipe);
Transactions
await session.db.transaction((transaction) async {
await Recipe.db.insertRow(session, recipe, transaction: transaction);
await Ingredient.db.insertRow(session, ingredient, transaction: transaction);
});
نشر Serverpod
بعد بناء مشروعك محلياً، حان وقت النشر على بيئة الإنتاج.
خيارات النشر
Serverpod Cloud
نشر بصفر إعدادات. حالياً في مرحلة قائمة انتظار. انضم للقائمة.
Docker
كل مشروع يأتي بحاوية Docker جاهزة للنشر على أي خادم.
AWS / Google Cloud
سكريبتات Terraform جاهزة للنشر على AWS أو Google Cloud Platform.
نشر بـ Docker
إبنِ صورة Docker:
$ cd my_project_server
$ docker build -t my_project_server .
شغّل الحاوية:
$ docker run -p 8080:8080 my_project_server
نظرة عامة
Serverpod إطار عمل backend مفتوح المصدر لتطبيقات Flutter مكتوب بـ Dart. يهدف إلى تقليل الـ boilerplate ودمج كثير من مهام الـ backend المشتركة خارج الصندوق.
القدرات الرئيسية
توليد الكود التلقائي
يحلل Serverpod كود السيرفر ويولد تلقائياً واجهة Dart للعميل وكلاسات البيانات. استدعاء endpoint بعيد يصبح بسيطاً مثل استدعاء دالة محلية.
تسجيل بمستوى عالمي
أدوات تسجيل ومراقبة مدمجة تتيح لك تحديد الاستثناءات واستعلامات قاعدة البيانات البطيئة عبر واجهة سهلة الاستخدام.
Caching مدمج
تخزين مؤقت عالي الأداء وموزّع مدمج. أي كائن يمكن تخزينه مؤقتاً (primitives وlists وmaps ونماذج قابلة للتسلسل) في الذاكرة أو موزَّعاً بـ Redis.
ORM سهل الاستخدام
يوفر Serverpod ORM يستخدم أنواع Dart الأصيلة ومع null-safety لاستعلامات قاعدة البيانات. تكتب Dart بدلاً من SQL.
Migrations لقاعدة البيانات
نظام migration مدمج يحافظ على تزامن schema قاعدة البيانات مع تطور مشروعك.
رفع الملفات
دعم أصيل لرفع الملفات إلى التخزين السحابي أو قاعدة البيانات: Amazon S3 أو Google Cloud Storage أو PostgreSQL.
المصادقة
مصادقة المستخدمين جاهزة للاستخدام فوراً مع دعم تسجيل الدخول بـ Google وApple وFirebase والبريد الإلكتروني/كلمة المرور وآليات مخصصة.
بث البيانات في الوقت الفعلي
دعم للاتصالات الفورية عبر Dart streams. ادفع كائنات مُسلسَلة عبر اتصالات WebSocket آمنة للتحديثات الحية (مثل الدردشات والألعاب).
جدولة المهام
استدعاءات المستقبل في Serverpod تحل محل cron jobs المعقدة. استدعِ method في أي وقت مستقبلاً أو بعد تأخير محدد، والاستدعاءات تستمر حتى بعد إعادة تشغيل السيرفر.
خادم ويب مدمج
Serverpod يأتي مع خادم ويب حديث عالي الأداء يُسمى Relic لبناء REST APIs والـ webhooks وصفحات الويب.
تعريف Endpoints
الـ endpoints هي نقاط الدخول التي يستدعيها العملاء لتنفيذ منطق السيرفر. يُعرَّف الـ endpoint بإنشاء كلاس يمتد من Endpoint وإضافة methods غير متزامنة إليه:
import 'package:serverpod/serverpod.dart';
class GreetingEndpoint extends Endpoint {
Future<String> hello(Session session, String name) async {
return 'Hello $name';
}
}
على جانب العميل:
final result = await client.greeting.hello('World');
نماذج البيانات والتسلسل
تُعرَّف نماذج البيانات في ملفات YAML بامتداد .spy.yaml وتُولَّد منها كلاسات Dart مشتركة بين السيرفر والتطبيق:
class: Company
fields:
name: String
foundedDate: DateTime?
التكامل مع قاعدة البيانات والـ ORM
لربط النموذج بجدول في قاعدة البيانات أضف اسم الجدول:
class: Company
table: company
fields:
name: String
foundedDate: DateTime?
// إدراج سجل جديد
var company = Company(name: 'Serverpod Inc.', foundedDate: DateTime.now());
company = await Company.db.insertRow(session, company);
// استرجاع بالمعرّف
var stored = await Company.db.findById(session, company.id);
المرجع: العمل مع Endpoints
الـ endpoints هي العمود الفقري لتطبيق Serverpod. هنا المرجع الشامل لكيفية تعريفها واستخدامها.
بنية الـ Endpoint
class MyEndpoint extends Endpoint {
// يجب أن تعيد Future أو Stream
Future<String> myMethod(Session session, String param) async {
return 'result';
}
// Stream للبيانات الآنية
Stream<String> myStream(Session session) async* {
yield 'update 1';
yield 'update 2';
}
}
كائن Session
كائن Session يوفر الوصول إلى موارد السيرفر:
| الخاصية | الوصف |
|---|---|
session.db | الوصول المباشر لقاعدة البيانات |
session.caches | الوصول إلى الـ cache |
session.auth | معلومات المصادقة |
session.passwords | كلمات المرور والمفاتيح من passwords.yaml |
session.log | التسجيل |
التحكم في الصلاحيات
class SecureEndpoint extends Endpoint {
// يتطلب تسجيل دخول
@override
bool get requireLogin => true;
Future<String> secureMethod(Session session) async {
return 'secure data';
}
}
المرجع: نماذج البيانات
دليل شامل لتعريف النماذج في ملفات .spy.yaml.
كلاس بسيط
class: UserProfile
fields:
name: String
age: int
email: String? # nullable
كلاس مع جدول قاعدة البيانات
class: UserProfile
table: user_profile
fields:
name: String
age: int
email: String?
العلاقات (Relations)
class: Post
table: post
fields:
title: String
content: String
# علاقة مع مستخدم
authorId: int
author: UserProfile?, relation(field: authorId)
القوائم والأنواع المركبة
class: ShoppingCart
fields:
items: List<CartItem>
tags: List<String>
metadata: Map<String, String>
التحكم في الظهور (Scopes)
class: User
table: user
fields:
email: String
# مخفية عن العميل
passwordHash: String, scope: serverOnly
المرجع: قاعدة البيانات والـ ORM
دليل شامل للتعامل مع PostgreSQL عبر ORM الخاص بـ Serverpod.
الاتصال بقاعدة البيانات
إعدادات الاتصال في config/development.yaml:
database:
host: localhost
port: 5432
name: my_project
user: postgres
password: 'my_password'
عمليات الاستعلام المتقدمة
الترتيب والتحديد
var recipes = await Recipe.db.find(
session,
where: (r) => r.author.equals('Gemini'),
orderBy: (r) => r.date,
orderDescending: true,
limit: 10,
offset: 0,
);
الانضمام للعلاقات (Joins)
var posts = await Post.db.find(
session,
include: Post.include(
author: UserProfile.includeIfNotNull(),
),
);
العمليات الجماعية
// إدراج متعدد
await Recipe.db.insert(session, [recipe1, recipe2, recipe3]);
// حذف بشرط
await Recipe.db.delete(
session,
where: (r) => r.date.isBefore(DateTime.now().subtract(
const Duration(days: 30),
)),
);
Migrations
عند تغيير النماذج:
# إنشاء migration جديد
$ serverpod create-migration
# تطبيق الـ migrations عند تشغيل السيرفر
$ dart run bin/main.dart --apply-migrations
المرجع: المصادقة (Authentication)
Serverpod يوفر نظام مصادقة شامل جاهز للاستخدام مع عدة موفرين.
موفرو المصادقة المدعومون
تسجيل دخول بحساب Google
Apple
تسجيل دخول بـ Apple ID
Firebase
استخدام Firebase Auth
بريد إلكتروني + كلمة مرور
إعداد المصادقة
أضف حزمة المصادقة:
$ dart pub add serverpod_auth_server
التحقق من تسجيل الدخول في Endpoint
class UserEndpoint extends Endpoint {
@override
bool get requireLogin => true;
Future<String> getProfile(Session session) async {
final userId = await session.auth.authenticatedUserId();
return 'User ID: $userId';
}
}
المرجع: Streams والوقت الفعلي
Serverpod يدعم بث البيانات في الوقت الفعلي عبر Dart streams واتصالات WebSocket آمنة.
إنشاء Streaming Endpoint
class ChatEndpoint extends Endpoint {
Stream<ChatMessage> messageStream(Session session, int roomId) async* {
await for (final message in _getMessageStream(roomId)) {
yield message;
}
}
Future<void> sendMessage(
Session session,
int roomId,
String text,
) async {
final msg = ChatMessage(roomId: roomId, text: text);
await session.messages.postMessage('room_$roomId', msg);
}
}
الاستماع للـ Stream في Flutter
final stream = client.chat.messageStream(roomId);
stream.listen((message) {
setState(() {
messages.add(message);
});
});
المرجع: التخزين المؤقت (Caching)
Serverpod يوفر تخزيناً مؤقتاً عالي الأداء في الذاكرة أو موزَّعاً بـ Redis.
Cache محلي
// تخزين
await session.caches.local.put(
'user:$userId',
userData,
lifetime: const Duration(minutes: 5),
);
// استرجاع
final cached = await session.caches.local.get<UserData>('user:$userId');
// حذف
await session.caches.local.invalidateKey('user:$userId');
Cache موزَّع (Redis)
// تخزين في Redis
await session.caches.distributed.put(
'global:key',
data,
lifetime: const Duration(hours: 1),
);
إعداد Redis
redis:
host: localhost
port: 6379
المرجع: التسجيل والمراقبة
Serverpod يوفر أدوات تسجيل قوية لمراقبة سلوك السيرفر وتشخيص المشكلات.
التسجيل اليدوي
// تسجيل معلومة
session.log('Processing request for user: $userId');
// تسجيل خطأ
session.log(
'Failed to process payment',
level: LogLevel.error,
exception: e,
stackTrace: stackTrace,
);
مراقبة الاستعلامات البطيئة
Serverpod يسجل تلقائياً جميع استعلامات قاعدة البيانات التي تستغرق وقتاً طويلاً. يمكنك مشاهدة هذه السجلات في Serverpod Insights.
إعدادات التسجيل
logging:
# تسجيل الاستعلامات التي تستغرق أكثر من 100ms
slowQueryDurationMs: 100
# الحد الأقصى لحجم رسالة التسجيل بالبايت
maxLogMessageSize: 10000
استراتيجية النشر
Serverpod يوفر عدة خيارات للنشر تناسب مختلف الاحتياجات.
المقارنة بين خيارات النشر
| الخيار | السهولة | التحكم | التكلفة |
|---|---|---|---|
| Serverpod Cloud | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | متغيرة |
| Docker (VPS) | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | منخفضة |
| AWS (Terraform) | ⭐⭐ | ⭐⭐⭐⭐⭐ | متغيرة |
| Google Cloud | ⭐⭐ | ⭐⭐⭐⭐⭐ | متغيرة |
متطلبات الإنتاج
- سيرفر يدعم Docker
- قاعدة بيانات PostgreSQL (الإصدار 14 أو أحدث)
- Redis (اختياري، للـ distributed caching)
- شهادة SSL/TLS للنطاق
النشر بـ Docker
كل مشروع Serverpod يأتي بـ Dockerfile و docker-compose.yaml جاهزين.
بنية ملفات Docker
my_project_server/
├── Dockerfile
├── docker-compose.yaml
└── config/
├── development.yaml
├── staging.yaml
└── production.yaml
Dockerfile النموذجي
FROM dart:stable AS build
WORKDIR /app
COPY . .
RUN dart pub get
RUN dart compile exe bin/main.dart -o bin/server
FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/bin/server /app/bin/
ENTRYPOINT ["/app/bin/server"]
docker-compose للإنتاج
version: '3'
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: my_project
POSTGRES_USER: postgres
POSTGRES_PASSWORD: my_password
volumes:
- postgres_data:/var/lib/postgresql/data
server:
build: .
ports:
- "8080:8080"
depends_on:
- postgres
volumes:
postgres_data:
Serverpod Insights
تطبيق مرافق قوي لمراقبة سيرفرك وتشخيص المشكلات في الوقت الفعلي.
الميزات الرئيسية
مؤشرات الصحة
مراقبة استخدام CPU والذاكرة وأداء قاعدة البيانات.
سجلات مباشرة
عرض سجلات السيرفر في الوقت الفعلي مع تصفية وبحث متقدم.
الاستعلامات البطيئة
تحديد استعلامات قاعدة البيانات التي تبطئ التطبيق.
تتبع الأخطاء
عرض الاستثناءات وstack traces بشكل مفصل.
الأنظمة المدعومة
- macOS متاح
- Windows متاح
- Linux (قادم قريباً)
الاتصال بالسيرفر
Insights يتصل بسيرفرك عبر المنفذ 8081 افتراضياً. تأكد أن هذا المنفذ متاح في إعدادات الـ firewall الخاصة بك.
Serverpod Mini
نسخة مخففة من Serverpod مثالية للمشاريع الصغيرة والنماذج الأولية.
ما هو Serverpod Mini؟
Serverpod Mini هو نسخة مصغرة تعمل بدون قاعدة بيانات PostgreSQL. مثالي للـ prototyping السريع أو عندما لا تحتاج إلى استمرارية البيانات.
إنشاء مشروع Mini
$ serverpod create my_mini_project --mini
الفروقات عن Serverpod الكامل
| الميزة | Serverpod | Serverpod Mini |
|---|---|---|
| Endpoints | ✅ | ✅ |
| توليد الكود | ✅ | ✅ |
| PostgreSQL ORM | ✅ | ❌ |
| Migrations | ✅ | ❌ |
| المصادقة | ✅ | ❌ |
| Docker مطلوب | ✅ | ❌ |
💡 متى تستخدم Mini؟
استخدم Mini عندما تريد اختبار فكرة سريعاً، أو عند بناء API بسيط لا يحتاج لتخزين دائم. عند توسع المشروع يمكنك الترقية إلى Serverpod الكامل بسهولة.
الدعم والمجتمع
Serverpod لديه مجتمع نشط ومتنامٍ من المطورين حول العالم.
قنوات الدعم
Discord
انضم إلى خادم Discord الرسمي للحصول على المساعدة والتحدث مع المجتمع.
GitHub Issues
أبلغ عن الأخطاء أو اقترح ميزات جديدة على GitHub.
Stack Overflow
اطرح أسئلتك بوسم serverpod.
Serverpod Academy
دروس ومقاطع فيديو للتعلم من الصفر.
خارطة الطريق والمساهمة
Serverpod مشروع مفتوح المصدر ويرحب بمساهمات المجتمع.
كيفية المساهمة
1- Fork المستودع
انسخ مستودع serverpod/serverpod على GitHub.
2- أنشئ branch جديد
أنشئ branch لميزتك أو إصلاح الخطأ.
3- اكتب الاختبارات
تأكد من كتابة اختبارات تغطي التغييرات. Serverpod لديه أكثر من 5000 اختبار آلي.
4- افتح Pull Request
قدّم PR مع وصف واضح للتغييرات.
ميزات قادمة
- Serverpod Cloud — نشر بصفر إعدادات (قائمة انتظار مفتوحة)
- دعم Serverpod Insights على Linux
- تحسينات على نظام الـ migrations
- دعم موفرين مصادقة إضافيين
ℹ️ معلومة
تحقق من قائمة الـ issues على GitHub لرؤية أحدث خارطة الطريق والمهام المتاحة للمساهمة.
الخلاصة :
بعد هذا الشرح، يمكن القول إن Serverpod ليس مجرد أداة أخرى، بل هو تغيير جذري في طريقة تفكير مطوري Flutter. إذا كنت تعمل ضمن فريق صغير أو مطور مستقل (Solo Developer)، فإن استخدام Serverpod سيوفر عليك مئات الساعات من كتابة الأكواد المكررة ويقلل من احتمالية الأخطاء.
هل يستحق التجربة؟ بالتأكيد. أنصحك باستخدامه في مشروعك القادم، خاصة إذا كنت تبحث عن سرعة في التطوير دون التضحية بقابلية التوسع.

