الفصل 4: النشر السحابي
مقدمة
تطبيقك جاهز، تم تكوين Docker، وتم إعداد CI/CD. حان الوقت لوضعه على الإنترنت! يغطي هذا الفصل الخيارات الرئيسية للنشر السحابي.
🎯 أهداف الفصل
في نهاية هذا الفصل، ستعرف:
- ✅ النشر على Railway
- ✅ النشر على Heroku
- ✅ فهم خيارات AWS
- ✅ تكوين قاعدة بيانات مُدارة
- ✅ اختيار المنصة المناسبة
1. مقارنة المنصات
| المنصة | الصعوبة | التكلفة | مثالي لـ |
|---|---|---|---|
| Railway | ⭐ سهل | مجاني → $5/شهر | مشاريع شخصية، شركات ناشئة |
| Heroku | ⭐ سهل | $7/شهر | تطبيقات بسيطة |
| Render | ⭐ سهل | مجاني → $7/شهر | بديل Heroku |
| AWS ECS | ⭐⭐⭐ معقد | متغير | الشركات |
| Kubernetes | ⭐⭐⭐⭐ متقدم | متغير | الخدمات المصغرة |
2. Railway (موصى به للمبتدئين)
لماذا Railway؟
- ✅ واجهة بسيطة
- ✅ النشر من GitHub
- ✅ PostgreSQL مدمج
- ✅ مجاني للبدء
- ✅ يدعم Docker
النشر
الخيار 1: من GitHub
- اذهب إلى railway.app
- "New Project" → "Deploy from GitHub repo"
- اختر المستودع الخاص بك
- يكتشف Railway تلقائيًا Spring Boot
الخيار 2: مع Docker
# تثبيت Railway CLI
npm i -g @railway/cli
# تسجيل الدخول
railway login
# إنشاء مشروع
railway init
# النشر
railway up
التكوين
# متغيرات البيئة (في لوحة تحكم Railway)
SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=${{Postgres.DATABASE_URL}}
إضافة PostgreSQL
- في مشروع Railway: "New" → "Database" → "PostgreSQL"
- يتم حقن المتغيرات تلقائيًا
railway.json
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "Dockerfile"
},
"deploy": {
"startCommand": "java -jar app.jar",
"healthcheckPath": "/actuator/health",
"restartPolicyType": "ON_FAILURE"
}
}
3. Heroku
التحضير
Procfile (في الجذر):
web: java -Dserver.port=$PORT -jar target/*.jar
system.properties:
java.runtime.version=17
النشر
# تثبيت Heroku CLI
# https://devcenter.heroku.com/articles/heroku-cli
# تسجيل الدخول
heroku login
# إنشاء التطبيق
heroku create my-spring-app
# إضافة PostgreSQL
heroku addons:create heroku-postgresql:mini
# النشر
git push heroku main
# عرض السجلات
heroku logs --tail
متغيرات البيئة
heroku config:set SPRING_PROFILES_ACTIVE=prod
heroku config:set JWT_SECRET=your-secret-key
# عرض جميع المتغيرات
heroku config
مع Docker
# تسجيل الدخول إلى سجل Heroku
heroku container:login
# البناء والدفع
heroku container:push web
# النشر
heroku container:release web
4. Render
النشر
- اذهب إلى render.com
- "New" → "Web Service"
- ربط GitHub
- التكوين:
- Build Command:
mvn clean package -DskipTests - Start Command:
java -jar target/*.jar
- Build Command:
render.yaml
services:
- type: web
name: my-spring-app
env: docker
dockerfilePath: ./Dockerfile
envVars:
- key: SPRING_PROFILES_ACTIVE
value: prod
- key: DATABASE_URL
fromDatabase:
name: mydb
property: connectionString
databases:
- name: mydb
plan: free
5. AWS (خيارات)
Elastic Beanstalk (بسيط)
# تثبيت EB CLI
pip install awsebcli
# التهيئة
eb init
# إنشاء البيئة
eb create production
# النشر
eb deploy
ECS مع Fargate (Docker)
# إنشاء مجموعة
aws ecs create-cluster --cluster-name my-cluster
# إنشاء تعريف المهمة (JSON)
aws ecs register-task-definition --cli-input-json file://task-definition.json
# إنشاء خدمة
aws ecs create-service \
--cluster my-cluster \
--service-name my-service \
--task-definition my-task \
--desired-count 2
task-definition.json
{
"family": "my-spring-app",
"containerDefinitions": [
{
"name": "app",
"image": "myuser/myapp:latest",
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080
}
],
"environment": [
{
"name": "SPRING_PROFILES_ACTIVE",
"value": "prod"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app",
"awslogs-region": "us-east-1"
}
}
}
],
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512"
}
6. قاعدة بيانات مُدارة
Railway PostgreSQL
# تم تكوينه تلقائيًا
spring.datasource.url=${DATABASE_URL}
Heroku Postgres
# يوفر Heroku DATABASE_URL تلقائيًا
spring.datasource.url=${DATABASE_URL}
AWS RDS
spring.datasource.url=jdbc:postgresql://mydb.xxx.us-east-1.rds.amazonaws.com:5432/mydb
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
تحليل DATABASE_URL
بعض المنصات توفر URL بالتنسيق:
postgres://user:password@host:5432/dbname
تكوين Spring للتحليل:
@Configuration
public class DatabaseConfig {
@Bean
@Profile("prod")
public DataSource dataSource() {
String databaseUrl = System.getenv("DATABASE_URL");
if (databaseUrl != null && databaseUrl.startsWith("postgres://")) {
// تحليل تنسيق Heroku/Railway
URI uri = URI.create(databaseUrl);
String username = uri.getUserInfo().split(":")[0];
String password = uri.getUserInfo().split(":")[1];
String jdbcUrl = "jdbc:postgresql://" + uri.getHost() + ":" + uri.getPort() + uri.getPath();
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(jdbcUrl);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
// بديل
return DataSourceBuilder.create().build();
}
}
7. قائمة التحقق من النشر
قبل النشر
□ الاختبارات تمر محليًا
□ تكوين ملف الإنتاج
□ الأسرار خارجية
□ تم اختبار Dockerfile
□ تم تكوين فحص الصحة
□ تم تكوين السجلات
متغيرات البيئة
# أساسية
SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=...
JWT_SECRET=...
# اختيارية
SERVER_PORT=8080
JAVA_OPTS="-Xmx512m"
بعد النشر
□ التطبيق متاح
□ فحص الصحة OK
□ السجلات مرئية
□ قاعدة البيانات متصلة
□ المراقبة في مكانها
8. المراقبة في الإنتاج
Actuator
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.health.show-details=when_authorized
تسجيل السحابة
# سجلات JSON للسحابة
logging.pattern.console={"timestamp":"%d","level":"%p","logger":"%c","message":"%m"}%n
خدمات المراقبة
- Railway: مقاييس مدمجة
- Heroku: مقاييس Heroku
- AWS: CloudWatch
- خارجية: Datadog, New Relic
9. ملخص
توصيات حسب حالة الاستخدام
مشروع شخصي / POC:
→ Railway (مجاني، بسيط)
شركة ناشئة / MVP:
→ Railway أو Render ($5-20/شهر)
شركة صغيرة / إنتاج:
→ Heroku أو AWS Elastic Beanstalk
شركة كبيرة / توسع:
→ AWS ECS / Kubernetes
النشر السريع (Railway)
# 1. امتلاك Dockerfile
# 2. الدفع على GitHub
# 3. على railway.app:
# - مشروع جديد → GitHub
# - إضافة PostgreSQL
# - تكوين المتغيرات
# 4. تم! 🚀
🎯 الخطوة التالية
حان وقت الممارسة! دعونا نقوم بتدوير ونشر تطبيق.