دليل نشر AWS EC2 لتطبيقات الويب
يظل EC2 خيار الحوسبة الأكثر مرونة في AWS لتطبيقات الويب التي تحتاج إلى أداء ثابت ومجموعات برامج مخصصة وأسعار يمكن التنبؤ بها. في حين أن ECS وEKS وLambda تحظى بمزيد من الاهتمام في عالم السحابة الأصلية، فإن EC2 تمنحك خادمًا تتحكم فيه بالكامل - لا يوجد تعقيد في تنسيق الحاويات، ولا زمن استجابة لبدء التشغيل البارد، ولا توجد تكاليف استدعاء مفاجئة.
يغطي هذا الدليل نشر تطبيق ويب Node.js للإنتاج على EC2: اختيار المثيل، وتكوين مجموعة الأمان، ونشر التطبيق، والوكيل العكسي Nginx، وSSL مع Cloudflare، والمراقبة باستخدام CloudWatch، وأنماط الصيانة المستمرة التي تحافظ على نشر EC2 بشكل سليم.
الوجبات الرئيسية
- t3.large هو نقطة البداية الصحيحة لنشر Node.js + PostgreSQL الكامل
- استخدم Ubuntu 24.04 LTS - مدعوم حتى عام 2029، وموثق على نطاق واسع، وتوافر ممتاز للحزم
- عنوان IP المرن إلزامي - يتغير عنوان IP EC2 الخاص بك عند كل توقف/بدء بدونه
- مجموعات الأمان ذات حالة - ما عليك سوى القواعد الواردة؛ عادةً ما يكون الصادر مسموحًا للجميع
- قم بتخزين مفتاح SSH للنشر في ملف
.pemمنفصل؛ لا تلزمه أبدًا بـ git- استخدم اتصال مثيل EC2 أو مدير الجلسة بدلاً من SSH المباشر عندما يكون ذلك ممكنًا (إدارة المفاتيح صفر)
- يوفر لك وكيل CloudWatch مقاييس الذاكرة والقرص (غير متوفرة افتراضيًا)
- تعمل المثيلات المحجوزة أو خطط التوفير على تقليل تكاليف EC2 بنسبة 40-60% مقابل عند الطلب
اختيار المثيل
يعتمد نوع المثيل الصحيح على حجم العمل لديك:
| عبء العمل | المثيل الموصى به | وحدة المعالجة المركزية الافتراضية | ذاكرة الوصول العشوائي | التكلفة/الشهر |
|---|---|---|---|---|
| لايت (مدونة، تطبيق صغير) | t3.small | 2 | 2 جيجا | ~ 18 دولارًا |
| متوسط (تطبيق مكدس كامل) | t3.medium | 2 | 4 جيجا | ~ 35 دولارًا |
| الإنتاج (متعدد الخدمات) | t3.كبير | 2 | 8 جيجا | ~ 70 دولارًا |
| ثقيل (واجهة برمجة التطبيقات ذات حركة مرور عالية) | c6i.xlarge | 4 | 8 جيجا | ~ 140 دولارًا |
| الذاكرة ثقيلة (ML/ذاكرة التخزين المؤقت) | r6i.large | 2 | 16 جيجا | ~120 دولارًا |
بالنسبة إلى monorepo الذي يحتوي على 5 تطبيقات Node.js (Next.js وNestJS وDocusaurus وموقعين للعلامة التجارية) بالإضافة إلى البنية الأساسية لـ Docker (PostgreSQL وRedis وAuthentik)، فإن t3.large هو الحد الأدنى من التكوين القابل للتطبيق. تستخدم عائلة t3 أداءً "قابلاً للاندفاع" - حيث يكون الأداء ممتازًا أثناء التشغيل العادي ولكن وحدة المعالجة المركزية العالية المستمرة تؤدي إلى الاختناق.
بالنسبة لأحمال عمل وحدة المعالجة المركزية العالية باستمرار (معالجة الفيديو، واستدلال تعلم الآلة، والتشفير الثقيل)، استخدم مثيلات c6i (المُحسَّنة للحوسبة) بدلاً من ذلك.
الإعداد الأولي للخادم
بعد تشغيل مثيل EC2 الخاص بك مع Ubuntu 24.04:
# Connect via SSH
ssh -i your-key.pem [email protected]
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install essential tools
sudo apt install -y \
git curl wget unzip \
build-essential \
nginx \
certbot python3-certbot-nginx \
docker.io docker-compose-plugin \
htop ncdu iotop
# Install Node.js via NVM (allows easy version management)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
nvm alias default 22
# Install pnpm
curl -fsSL https://get.pnpm.io/install.sh | sh -
source ~/.bashrc
# Install PM2 globally
npm install -g pm2
# Install PM2 log rotation immediately
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
تكوين مجموعة الأمان
مجموعة الأمان هي جدار الحماية الخاص بمثيل EC2 الخاص بك. قم بتكوينه بعناية:
Inbound Rules:
┌─────────┬──────────┬─────────────┬──────────────────────────────────┐
│ Type │ Protocol │ Port Range │ Source │
├─────────┼──────────┼─────────────┼──────────────────────────────────┤
│ SSH │ TCP │ 22 │ Your IP only (not 0.0.0.0/0!) │
│ HTTP │ TCP │ 80 │ 0.0.0.0/0 (Cloudflare IPs only) │
│ HTTPS │ TCP │ 443 │ 0.0.0.0/0 (Cloudflare IPs only) │
└─────────┴──────────┴─────────────┴──────────────────────────────────┘
Note: Internal app ports (3000, 3001, 3002, etc.) should NOT be
in the security group — traffic goes through Nginx only
بالنسبة للنطاقات الوكيلة لـ Cloudflare، قم بتقييد HTTP/HTTPS بنطاقات Cloudflare IP:
# Cloudflare IPv4 ranges — restrict port 80/443 source to these
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
104.16.0.0/13
104.24.0.0/14
108.162.192.0/18
131.0.72.0/22
141.101.64.0/18
162.158.0.0/15
172.64.0.0/13
173.245.48.0/20
188.114.96.0/20
190.93.240.0/20
197.234.240.0/22
198.41.128.0/17
وهذا يمنع الوصول المباشر إلى الخادم الخاص بك، متجاوزًا حماية WAF وDDoS الخاصة بـ Cloudflare.
نشر التطبيق
# Create application directory
sudo mkdir -p /opt/ecosire/app
sudo chown ubuntu:ubuntu /opt/ecosire/app
# Clone the repository
git clone https://github.com/your-org/your-repo.git /opt/ecosire/app
cd /opt/ecosire/app
# Create .env.local from template
cp .env.example .env.local
# Edit with production values
nano .env.local
# Install dependencies
pnpm install --frozen-lockfile
# Build everything
npx turbo run build
# Run database migrations
pnpm --filter @ecosire/db db:migrate
# Start infrastructure (PostgreSQL, Redis, Authentik)
docker compose -f infrastructure/docker-compose.dev.yml up -d
# Wait for services to be healthy
sleep 30
# Start Node.js applications
pm2 start ecosystem.config.cjs
# Save process list for reboot persistence
pm2 save
# Configure PM2 to start on system boot
pm2 startup
# Run the command it outputs
IP و DNS المرن
يتغير عنوان IP العام لمثيل EC2 في كل مرة تقوم فيها بإيقافه وتشغيله. يوفر عنوان IP المرن عنوان IP دائمًا:
# In AWS Console:
# 1. EC2 > Network & Security > Elastic IPs
# 2. Allocate Elastic IP address
# 3. Associate it with your instance
# Your IP is now permanent — update Cloudflare DNS to point to it
# A record: ecosire.com → 13.223.116.181 (your Elastic IP)
# A record: api.ecosire.com → 13.223.116.181
# A record: auth.ecosire.com → 13.223.116.181
في Cloudflare، قم بتعيين هذه السجلات على "Proxyed" (السحابة البرتقالية) لحركة مرور الويب. يخفي وكيل Cloudflare عنوان IP الفعلي لـ EC2 الخاص بك، مما يوفر حماية ضد DDoS.
التخزين: إدارة حجم EBS
تتضمن مثيلات EC2 وحدة تخزين EBS الجذرية. للإنتاج، تحتاج إلى مساحة كافية لإنشاء العناصر والسجلات وبيانات Docker:
# Check current disk usage
df -h
# Check which directories are consuming space
ncdu /
# Typical space requirements for a 5-app monorepo:
# - /opt/ecosire/app: ~2GB (code + node_modules + .next builds)
# - Docker data (/var/lib/docker): ~5GB
# - PM2 logs (/var/log/pm2): ~1GB (with rotation)
# - System: ~5GB
# Total: ~13GB minimum, recommend 30GB+ root volume
# If you need to resize an EBS volume (no downtime needed):
# 1. In AWS Console: EC2 > Volumes > Modify Volume
# 2. After resize completes, grow the filesystem:
sudo growpart /dev/xvda 1
sudo resize2fs /dev/xvda1
مراقبة CloudWatch
يوفر EC2 مقاييس أساسية لوحدة المعالجة المركزية والشبكة بشكل افتراضي. بالنسبة لمقاييس الذاكرة والقرص، قم بتثبيت وكيل CloudWatch:
# Download and install CloudWatch agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb
# Create configuration
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
// /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"mem": {
"measurement": ["mem_used_percent"],
"metrics_collection_interval": 60
},
"disk": {
"measurement": ["used_percent"],
"metrics_collection_interval": 60,
"resources": ["/", "/opt/ecosire"]
}
}
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/pm2/ecosire-api.err.log",
"log_group_name": "/ec2/ecosire/api-errors",
"log_stream_name": "{instance_id}"
},
{
"file_path": "/var/log/nginx/ecosire-error.log",
"log_group_name": "/ec2/ecosire/nginx-errors",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
# Start the agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
النسخ الاحتياطية الآلية
قم بإعداد نسخ احتياطية تلقائية لـ PostgreSQL إلى S3:
# Create backup script
cat > /opt/ecosire/scripts/backup-db.sh << 'EOF'
#!/bin/bash
set -e
DATE=$(date +%Y-%m-%d-%H%M%S)
BACKUP_FILE="/tmp/ecosire-db-${DATE}.sql.gz"
S3_BUCKET="s3://your-backups-bucket/postgres"
# Dump the database (connects via Docker network)
docker exec ecosire-postgres pg_dump \
-U ecosire \
-d ecosire_dev \
--no-owner \
--no-privileges \
| gzip > "$BACKUP_FILE"
# Upload to S3
aws s3 cp "$BACKUP_FILE" "$S3_BUCKET/"
# Clean up local file
rm "$BACKUP_FILE"
# Delete backups older than 30 days from S3
aws s3 ls "$S3_BUCKET/" \
| awk '{print $4}' \
| sort \
| head -n -30 \
| xargs -I {} aws s3 rm "$S3_BUCKET/{}" 2>/dev/null || true
echo "Backup complete: ${DATE}"
EOF
chmod +x /opt/ecosire/scripts/backup-db.sh
# Schedule daily backups at 3 AM UTC
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/ecosire/scripts/backup-db.sh >> /var/log/db-backup.log 2>&1") | crontab -
تكوين دور IAM
قم بإرفاق دور IAM بمثيل EC2 الخاص بك للوصول إلى خدمة AWS (S3، CloudWatch، SES):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-products-bucket",
"arn:aws:s3:::your-products-bucket/*",
"arn:aws:s3:::your-backups-bucket",
"arn:aws:s3:::your-backups-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
من خلال دور IAM المرتبط بمثيلك، تستخدم مكالمات AWS SDK بيانات اعتماد المثيل تلقائيًا - لا حاجة إلى مفتاح وصول/مفتاح سري في متغيرات البيئة الخاصة بك.
المخاطر والحلول الشائعة
المأزق 1: لا يوجد عنوان IP مرن — يتغير عنوان IP عند إعادة التشغيل
يؤدي إيقاف مثيل EC2 وبدء تشغيله (وليس إعادة التشغيل) إلى تعيين عنوان IP عام جديد. بدون عنوان IP مرن، ينقطع نظام أسماء النطاقات (DNS) الخاص بك. قم بتخصيص وربط عنوان IP المرن فورًا بعد تشغيل المثيل الخاص بك.
المأزق 2: تم إغلاق الوصول إلى SSH
إذا فقدت مفتاح SSH الخاص بك أو أغلقت نفسك عن طريق تكوين مجموعات الأمان بشكل خاطئ، فاستخدم EC2 Instance Connect (SSH المستند إلى المستعرض) من وحدة تحكم AWS، أو Session Manager (يتطلب تثبيت وكيل SSM، والذي يأتي مع Ubuntu افتراضيًا). كحل أخير، قم بفصل وحدة تخزين EBS الجذرية، وإرفاقها بمثيل آخر، وإصلاح ملف المفاتيح المعتمدة، ثم إعادة التوصيل.
المأزق 3: نفاد مساحة القرص أثناء النشر
تنمو ذاكرة التخزين المؤقت للبناء .next وnode_modules بشكل كبير أثناء التطوير. راقب استخدام القرص باستخدام df -h واضبط منبه CloudWatch على disk_used_percent > 80%. يحدد الأمر ncdu (ncdu /) الدلائل التي تستهلك مساحة.
المأزق 4: استنفاد الذاكرة من Node.js OOM
لدى Node.js حد افتراضي للذاكرة (1.4 جيجابايت على 64 بت) يمكن أن يتسبب في تعطل OOM في التطبيقات الكبيرة. قم بتعيين node_args: '--max-old-space-size=1024' في ملف النظام البيئي PM2 الخاص بك لتحديد الحد الأقصى لاستخدام الذاكرة بشكل صريح. اضبط max_memory_restart أعلى هذا بقليل لإعادة التشغيل التلقائي إذا تم تجاوزه.
المأزق 5: اختناق وحدة المعالجة المركزية T3 تحت الحمل المستمر
تستخدم مثيلات T3 "أرصدة وحدة المعالجة المركزية" للحصول على أداء قابل للاندفاع. تؤدي العمليات الممتدة لوحدة المعالجة المركزية (CPU) العالية (الإصدارات الكبيرة، واستعلامات قاعدة البيانات الثقيلة) إلى استنفاد الاعتمادات، مما يتسبب في اختناق الأداء "الأساسي". مراقبة CPUCreditBalance في CloudWatch. إذا تم استنفاد الأرصدة باستمرار، فقم بالترقية إلى مثيل c6i أو قم بتمكين الوضع "غير المحدود" (تكلفة إضافية لكل ساعة وحدة المعالجة المركزية أعلى من خط الأساس).
الأسئلة المتداولة
هل يجب علي استخدام EC2 أو خدمة مُدارة مثل AWS Elastic Beanstalk؟
يمنحك EC2 التحكم الكامل: إصدار Node.js الدقيق، والوصول إلى نظام الملفات، والقدرة على تشغيل حاويات Docker الجانبية، وتكوين Nginx المخصص. تدير Elastic Beanstalk البنية الأساسية ولكنها تقيد خياراتك وتضيف تعقيدًا لاستكشاف الأخطاء وإصلاحها. بالنسبة لفريق مريح في إدارة خادم Linux، يعد EC2 مع PM2 + Nginx أبسط وأكثر قابلية للتنبؤ به من الأنظمة الأساسية المُدارة. استخدم Beanstalk إذا كنت تريد أن يتعامل النظام الأساسي مع القياس وإدارة الصحة تلقائيًا.
كيف أتعامل مع عمليات النشر بدون توقف على EC2؟
يوفر الأمر PM2 pm2 reload فترة توقف صفرية لعمليات وضع المجموعة (NestJS API). بالنسبة إلى Next.js (وضع التفرع)، أنشئ الإصدار الجديد أولاً، ثم أعد تحميل PM2. خلال الثواني القليلة التي يستغرقها PM2 لتبديل العمليات، يقوم Nginx بوضع الطلبات الواردة في قائمة الانتظار (مع مهلة قصيرة). للحصول على وقت توقف صفري حقيقي، استخدم مثيلين EC2 خلف ALB (Application Load Balancer) وانشرهما في أحدهما بينما يخدم الآخر حركة المرور.
متى يجب علي استخدام القياس التلقائي؟
يضيف القياس التلقائي تعقيدًا تشغيليًا كبيرًا - عمليات التحقق من الصحة، وقوالب التشغيل، وموازنات التحميل، واعتبارات تقارب الجلسة. بالنسبة للتطبيقات ذات حركة المرور التي يمكن التنبؤ بها، يكون مثيل EC2 ذو الحجم المناسب مع المقياس الرأسي (نوع المثيل الأكبر) أبسط وغالبًا ما يكون أرخص من المقياس التلقائي الأفقي. فكر في القياس التلقائي عندما يكون لديك زيادة في حركة المرور تزيد عن 5 أضعاف خط الأساس وتكلفة تشغيل مثيل أكبر بشكل دائم تتجاوز تعقيد القياس التلقائي.
كيف يمكنني الترحيل من EC2 إلى الحاويات لاحقًا؟
ابدأ بوضع تطبيقك في حاوية باستخدام Docker (اكتب ملف Dockerfile لكل تطبيق). اختبره محليًا باستخدام Docker Compose. ثم اختر بين ECS Fargate (حاويات بدون خادم، أبسط) أو EKS (Kubernetes، أكثر قوة ولكن معقدة). لا يكون الترحيل مزعجًا إذا قمت بالترحيل بشكل متزايد - قم بتشغيل الإصدار المحتوي على حاوية خلف نفس إعداد Nginx/Cloudflare، وتحقق من السلوك، ثم اقطعه.
ما هي الطريقة الأكثر فعالية من حيث التكلفة لتشغيل EC2 في الإنتاج؟
قم بشراء مثيل محجوز لمدة عام واحد (بدون دفعة مقدمة أو دفعة مقدمة جزئية) لمثيلك الأساسي — أرخص بنسبة 40% من المثيل عند الطلب. للحصول على سعة إضافية أثناء ارتفاع حركة المرور، استخدم مثيلات Spot (أرخص بنسبة تصل إلى 90%) إذا كان تطبيقك قادرًا على التعامل مع الانقطاعات. قم بإعداد منبه فواتير CloudWatch بنسبة 80% من ميزانيتك الشهرية حتى يتم اكتشاف الزيادات غير المتوقعة في التكلفة مبكرًا. بالنسبة لتطبيقات الويب الخاصة بالإنتاج، توفر المثيلات المحجوزة أفضل توازن بين التكلفة والموثوقية.
الخطوات التالية
يتطلب تشغيل تطبيق ويب الإنتاج على EC2 اهتمامًا تشغيليًا مستمرًا - تصحيحات الأمان وإدارة الأقراص ومراقبة الأداء وأتمتة النشر. تدير ECOSIRE مثيل إنتاج EC2 t3.large يخدم 5 تطبيقات عبر مجالات متعددة، مع نسخ احتياطية تلقائية ومراقبة CloudWatch وعمليات نشر PM2 بدون توقف.
سواء كنت بحاجة إلى استشارات البنية التحتية لـ AWS، أو إعداد نشر EC2، أو دعم DevOps الكامل لتطبيق Node.js الخاص بك، استكشف خدماتنا لترى كيف يمكننا مساعدتك.
بقلم
ECOSIRE Research and Development Team
بناء منتجات رقمية بمستوى المؤسسات في ECOSIRE. مشاركة رؤى حول تكاملات Odoo وأتمتة التجارة الإلكترونية وحلول الأعمال المدعومة بالذكاء الاصطناعي.
مقالات ذات صلة
Cloud Hosting for ERP: AWS vs Azure vs Google Cloud
A detailed comparison of AWS, Azure, and Google Cloud for ERP hosting in 2026. Covers performance, cost, regional availability, managed services, and ERP-specific recommendations.
Cloud vs On-Premise ERP in 2026: The Definitive Guide
Cloud vs on-premise ERP in 2026: total cost analysis, security comparison, scalability, compliance, and the right deployment model for your business.
Docker Compose for Development: Local Infrastructure
Docker Compose for local development: PostgreSQL, Redis, Authentik, networking, health checks, volume management, and environment-specific configurations for TypeScript monorepos.