انتقل إلى المحتوى الرئيسي

الفصل 1: التحضير للإنتاج

مقدمة​

قبل النشر، يجب تحضير تطبيقك. يغطي هذا الفصل التغليف، ملفات التعريف، وإدارة التكوينات.


🎯 أهداف الفصل​

في نهاية هذا الفصل، ستعرف:

  1. ✅ إنشاء JAR قابل للتنفيذ
  2. ✅ تكوين ملفات Spring الشخصية
  3. ✅ استخراج التكوين
  4. ✅ إدارة الأسرار بشكل آمن
  5. ✅ تحسين للإنتاج

1. التغليف: JAR مقابل WAR​

JAR قابل للتنفيذ (موصى به)​

يقوم Spring Boot بإنشاء fat JAR يحتوي على كل شيء:

# Build
mvn clean package

# تشغيل
java -jar target/myapp-1.0.0.jar

المزايا:

  • ✅ خادم Tomcat مدمج
  • ✅ سهل النشر
  • ✅ قابل للنقل
  • ✅ مثالي لـ Docker

WAR (خادم خارجي)​

للنشر على Tomcat/JBoss موجود:

<!-- pom.xml -->
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
// تعديل الفئة الرئيسية
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

التوصية​

JAR لـ:
- Docker / Kubernetes
- السحابة (Heroku, Railway, AWS)
- الخدمات المصغرة

WAR لـ:
- البنية التحتية القديمة
- خوادم التطبيقات الموجودة

2. ملفات Spring الشخصية​

تعريف ملفات التعريف​

src/main/resources/
├── application.properties # تكوين مشترك
├── application-dev.properties # تطوير
├── application-prod.properties # إنتاج
└── application-test.properties # اختبارات

application.properties (مشترك)​

spring.application.name=myapp
server.port=8080

# الملف الشخصي الافتراضي
spring.profiles.active=dev

application-dev.properties​

# قاعدة بيانات H2 في الذاكرة
spring.datasource.url=jdbc:h2:mem:devdb
spring.datasource.driver-class-name=org.h2.Driver
spring.h2.console.enabled=true

# JPA
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

# تسجيل مفصل
logging.level.com.myapp=DEBUG
logging.level.org.hibernate.SQL=DEBUG

# Actuator: كل شيء مكشوف في التطوير
management.endpoints.web.exposure.include=*

application-prod.properties​

# PostgreSQL في الإنتاج
spring.datasource.url=${DATABASE_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}

# JPA
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false

# تسجيل الحد الأدنى
logging.level.root=WARN
logging.level.com.myapp=INFO

# Actuator: آمن
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.health.show-details=when_authorized

# الأمان
server.error.include-stacktrace=never

تفعيل ملف شخصي​

# عبر وسيطة JVM
java -jar myapp.jar --spring.profiles.active=prod

# عبر متغير البيئة
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar

# عبر Docker
docker run -e SPRING_PROFILES_ACTIVE=prod myapp

3. تكوين خارجي​

ترتيب الأولوية​

يقوم Spring Boot بتحميل التكوين بهذا الترتيب (الأولوية المتزايدة):

1. application.properties (داخل JAR)
2. application-{profile}.properties (داخل JAR)
3. application.properties (خارج JAR)
4. application-{profile}.properties (خارج JAR)
5. متغيرات البيئة
6. وسائط سطر الأوامر

متغيرات البيئة​

# application.properties
spring.datasource.url=${DATABASE_URL:jdbc:h2:mem:default}
spring.datasource.username=${DB_USER:sa}
spring.datasource.password=${DB_PASS:}
# تعيين المتغيرات
export DATABASE_URL=jdbc:postgresql://localhost:5432/mydb
export DB_USER=myuser
export DB_PASS=secret

java -jar myapp.jar

تكوين YAML (بديل)​

# application.yml
spring:
application:
name: myapp
profiles:
active: dev

---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:h2:mem:devdb
h2:
console:
enabled: true

---
spring:
config:
activate:
on-profile: prod
datasource:
url: ${DATABASE_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}

4. إدارة الأسرار​

❌ لا تفعل أبداً​

# أبداً في كود المصدر!
spring.datasource.password=MySecretPassword123
api.key=sk-1234567890abcdef

✅ أفضل الممارسات​

الخيار 1: متغيرات البيئة​

export DB_PASSWORD=secret
export API_KEY=sk-xxx

الخيار 2: ملف .env (محلي فقط)​

# .env (أضف إلى .gitignore!)
DATABASE_URL=jdbc:postgresql://localhost:5432/mydb
DB_PASSWORD=secret
API_KEY=sk-xxx

الخيار 3: مدراء الأسرار​

# Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
data:
db-password: c2VjcmV0 # base64

الخيار 4: Spring Cloud Config​

# للأسرار المركزية
spring:
cloud:
config:
uri: http://config-server:8888

.gitignore​

# أسرار
.env
*.pem
*.key
application-local.properties
secrets/

5. تحسينات الإنتاج​

تكوين JVM​

# إعدادات JVM للإنتاج
java -Xms512m -Xmx1024m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-Djava.security.egd=file:/dev/./urandom \
-jar myapp.jar

application-prod.properties​

# ضغط الردود
server.compression.enabled=true
server.compression.mime-types=application/json,text/html,text/css
server.compression.min-response-size=1024

# تجمع الاتصالات المحسن
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000

# تخزين القوالب المؤقت
spring.thymeleaf.cache=true

# تعطيل ميزات التطوير
spring.devtools.restart.enabled=false
spring.h2.console.enabled=false

الإغلاق التدريجي​

# انتظار انتهاء الطلبات الجارية
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

6. بناء للإنتاج​

Maven​

# بناء مع ملف شخصي للإنتاج
mvn clean package -Pprod -DskipTests

# أو مع الملف الشخصي لـ Spring
mvn clean package -Dspring.profiles.active=prod

pom.xml - ملفات Maven الشخصية​

<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>

<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

التحقق من JAR​

# محتوى JAR
jar tf target/myapp-1.0.0.jar

# اختبار محلي
java -jar target/myapp-1.0.0.jar --spring.profiles.active=prod

7. ملخص​

قائمة التحقق للإنتاج​

□ JAR قابل للتنفيذ تم إنشاؤه
□ ملفات شخصية تم تكوينها (dev، prod، test)
□ أسرار مستخرجة (ليست في الكود)
□ متغيرات البيئة موثقة
□ تسجيل تم تكوينه (ليس DEBUG في الإنتاج)
□ Actuator آمن
□ الضغط مفعل
□ تجمع الاتصالات تم تكوينه
□ الإغلاق التدريجي مفعل

ملفات التكوين​

application.properties        → تكوين مشترك
application-dev.properties → H2، DEBUG، كل شيء مكشوف
application-prod.properties → PostgreSQL، WARN، آمن
application-test.properties → H2، للاختبارات

المتغيرات الأساسية​

SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=jdbc:postgresql://...
DB_USERNAME=myuser
DB_PASSWORD=secret
SERVER_PORT=8080

🎯 الخطوة التالية​

التطبيق جاهز. الآن، لنقم بتعبئته باستخدام Docker!

➡️ الفصل 2: تعبئة Docker


⬅️ العودة إلى الوحدة 12