🚀 Wdrażanie aplikacji Spring Boot na AWS z Fargate i ECS - Kompleksowy przewodnik
Chcesz przenieść swoją aplikację Spring Boot do chmury AWS, ale nie wiesz od czego zacząć? W tym kompletnym przewodniku przeprowadzimy Cię przez cały proces wdrażania aplikacji Spring Boot za pomocą usług AWS Fargate i ECS. Niezależnie od tego, czy jesteś doświadczonym deweloperem, czy dopiero zaczynasz przygodę z chmurą, ten przewodnik dostarczy Ci wszystkich niezbędnych informacji.
⚡ Ekspresowe Podsumowanie:
- Konteneryzacja Spring Boot: Tworzenie obrazu Docker dla aplikacji Spring Boot, optymalnie skonfigurowanego do wdrożenia w chmurze.
- Konfiguracja AWS ECS i Fargate: Ustawienie klastra, definicji zadań, usług i innych niezbędnych elementów infrastruktury.
- Bezpieczne wdrożenie: Implementacja strategii bezpiecznego wdrażania z uwzględnieniem najlepszych praktyk bezpieczeństwa.
- Automatyzacja procesu CI/CD: Konfiguracja pipeline'u do ciągłej integracji i wdrażania aplikacji.
🗺️ Spis Treści - Twoja Mapa Drogowa
📋 Wprowadzenie do AWS Fargate i ECS
AWS Elastic Container Service (ECS) to w pełni zarządzana usługa orkiestracji kontenerów, która ułatwia wdrażanie, zarządzanie i skalowanie aplikacji kontenerowych. AWS Fargate jest technologią serverless, która eliminuje potrzebę zarządzania infrastrukturą podstawową (serwerami), pozwalając Ci skupić się na kodzie i aplikacji.
Połączenie Spring Boot, kontenera Docker oraz usług AWS Fargate/ECS tworzy potężne środowisko, które zapewnia:
- Skalowalność i elastyczność - automatyczne skalowanie w zależności od obciążenia
- Redukcję kosztów - płacisz tylko za to, co faktycznie używasz
- Prostotę zarządzania - bez konieczności zajmowania się serwerami
- Wysoką dostępność - rozproszenie aplikacji w wielu strefach dostępności
🔧 Przygotowanie aplikacji Spring Boot
Zanim przejdziemy do konfiguracji AWS, musimy przygotować naszą aplikację Spring Boot do konteneryzacji.
Utworzenie prostej aplikacji Spring Boot
Jeśli jeszcze nie masz aplikacji Spring Boot, możesz szybko utworzyć ją za pomocą Spring Initializr. Wybierz zależności takie jak Spring Web, Actuator (do monitorowania), oraz inne potrzebne dla Twojej aplikacji.
curl https://start.spring.io/starter.tgz \
-d dependencies=web,actuator \
-d type=maven-project \
-d bootVersion=3.2.0 \
-d baseDir=spring-boot-aws-example | tar -xzvf -
Dodanie endpointów diagnostycznych
Dodajmy prosty kontroler REST, który posłuży nam do testowania aplikacji:
@RestController
public class HealthController {
@GetMapping("/")
public String home() {
return "Spring Boot AWS Example is running!";
}
@GetMapping("/health")
public Map<String, Object> health() {
Map<String, Object> healthStatus = new HashMap<>();
healthStatus.put("status", "UP");
healthStatus.put("timestamp", new Date().toString());
return healthStatus;
}
}
Konfiguracja aplikacji do pracy w kontenerze
Zmodyfikujmy plik application.properties
(lub application.yml
), aby aplikacja była gotowa do pracy w środowisku kontenerowym:
# Port serwera
server.port=8080
# Monitoring i metryki
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
# Konfiguracja logowania
logging.level.root=INFO
logging.level.org.springframework.web=INFO
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
✨ Pro Tip: Zawsze uwzględniaj endpoint /health
w aplikacji wdrażanej w chmurze. AWS ECS używa go do sprawdzania, czy kontener działa poprawnie.
🐳 Konteneryzacja aplikacji Spring Boot
Teraz przystąpimy do przygotowania Dockerfile, który przekształci naszą aplikację w kontener.
Tworzenie Dockerfile
Utwórz plik Dockerfile
w głównym katalogu projektu:
FROM eclipse-temurin:17-jdk as build
WORKDIR /app
# Kopiowanie plików projektu
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
# Budowanie aplikacji (z pominięciem testów dla szybszego buildu)
RUN ./mvnw package -DskipTests
# Druga faza - utworzenie mniejszego obrazu końcowego
FROM eclipse-temurin:17-jre
WORKDIR /app
# Kopiowanie zbudowanego JAR-a z poprzedniej fazy
COPY --from=build /app/target/*.jar app.jar
# Konfiguracja zmiennych środowiskowych
ENV JAVA_OPTS="-Xms256m -Xmx512m"
# Uruchomienie aplikacji
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
# Informacja o porcie, na którym działa aplikacja
EXPOSE 8080
Budowanie i testowanie obrazu lokalnie
Przed przesłaniem obrazu do AWS, warto najpierw sprawdzić, czy działa poprawnie lokalnie:
# Budowanie obrazu
docker build -t spring-boot-aws-example .
# Uruchomienie kontenera
docker run -p 8080:8080 spring-boot-aws-example
Po uruchomieniu kontenera, aplikacja powinna być dostępna pod adresem http://localhost:8080/
Uwaga: Upewnij się, że Docker jest zainstalowany i działa na Twoim komputerze przed wykonaniem powyższych komend.
☁️ Konfiguracja konta AWS
Zanim przejdziemy do wdrażania aplikacji, musimy skonfigurować konto AWS i ustawić niezbędne usługi.
Podstawowe ustawienia
-
Utwórz konto AWS (jeśli jeszcze nie masz) na aws.amazon.com
-
Zainstaluj i skonfiguruj AWS CLI:
# Instalacja AWS CLI pip install awscli # Konfiguracja AWS CLI aws configure
Podczas konfiguracji, wprowadź swój Access Key ID, Secret Access Key, region (np. eu-central-1) i preferowany format wyjścia (np. json).
-
Zainstaluj EB CLI (opcjonalnie, przydatne do zarządzania Elastic Beanstalk):
pip install awsebcli
Utworzenie repozytorium ECR
Amazon Elastic Container Registry (ECR) to w pełni zarządzane repozytorium kontenerów, które umożliwia przechowywanie, zarządzanie i wdrażanie obrazów Docker.
# Tworzenie repozytorium ECR
aws ecr create-repository --repository-name spring-boot-aws-example
# Logowanie do ECR
aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin ACCOUNT_ID.dkr.ecr.eu-central-1.amazonaws.com
Zastąp ACCOUNT_ID
swoim identyfikatorem konta AWS.
Przesłanie obrazu do ECR
# Tagowanie obrazu
docker tag spring-boot-aws-example:latest ACCOUNT_ID.dkr.ecr.eu-central-1.amazonaws.com/spring-boot-aws-example:latest
# Przesłanie obrazu
docker push ACCOUNT_ID.dkr.ecr.eu-central-1.amazonaws.com/spring-boot-aws-example:latest
🚢 Wdrożenie aplikacji na AWS Fargate
Teraz nadszedł czas na wdrożenie naszej aplikacji za pomocą AWS Fargate i ECS.
Utworzenie klastra ECS
Klaster ECS to logiczne grupowanie zadań lub usług. Z Fargate, nie musisz zarządzać jakimikolwiek serwerami.
# Tworzenie klastra
aws ecs create-cluster --cluster-name spring-boot-cluster
Utworzenie definicji zadania (Task Definition)
Definicja zadania określa, jak ma wyglądać kontener i jakie ma parametry. Utwórz plik task-definition.json
:
{
"family": "spring-boot-task",
"networkMode": "awsvpc",
"executionRoleArn": "arn:aws:iam::ACCOUNT_ID:role/ecsTaskExecutionRole",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "spring-boot-container",
"image": "ACCOUNT_ID.dkr.ecr.eu-central-1.amazonaws.com/spring-boot-aws-example:latest",
"essential": true,
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/spring-boot-task",
"awslogs-region": "eu-central-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}
]
}
Zarejestruj definicję zadania:
aws ecs register-task-definition --cli-input-json file://task-definition.json
✨ Pro Tip: Dostosuj wartości CPU i pamięci w zależności od wymagań Twojej aplikacji. Fargate oferuje różne kombinacje, które wpływają na koszt usługi.
Utworzenie usługi ECS
Usługa ECS utrzymuje określoną liczbę instancji definicji zadania uruchomionych w klastrze. Przed utworzeniem usługi, potrzebujemy ustawić kilka dodatkowych zasobów.
1. Utwórz VPC i podsieci
# Utworzenie VPC
VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query 'Vpc.VpcId' --output text)
# Utworzenie podsieci
SUBNET1_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.1.0/24 --availability-zone eu-central-1a --query 'Subnet.SubnetId' --output text)
SUBNET2_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.2.0/24 --availability-zone eu-central-1b --query 'Subnet.SubnetId' --output text)
2. Utwórz grupę zabezpieczeń
# Utworzenie grupy zabezpieczeń
SG_ID=$(aws ec2 create-security-group --group-name spring-boot-sg --description "Security group for Spring Boot app" --vpc-id $VPC_ID --query 'GroupId' --output text)
# Dodanie reguły umożliwiającej ruch HTTP
aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 8080 --cidr 0.0.0.0/0
3. Utwórz usługę ECS
Teraz możemy utworzyć usługę ECS, która uruchomi nasze zadanie:
aws ecs create-service \
--cluster spring-boot-cluster \
--service-name spring-boot-service \
--task-definition spring-boot-task:1 \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET1_ID,$SUBNET2_ID],securityGroups=[$SG_ID],assignPublicIp=ENABLED}" \
--deployment-configuration "minimumHealthyPercent=100,maximumPercent=200" \
--deployment-controller "type=ECS"
Utworzenie Load Balancera (opcjonalnie)
Dla aplikacji produkcyjnych warto dodać Load Balancer, który rozłoży ruch między instancjami aplikacji.
# Utworzenie Load Balancera
LB_ARN=$(aws elbv2 create-load-balancer \
--name spring-boot-lb \
--subnets $SUBNET1_ID $SUBNET2_ID \
--security-groups $SG_ID \
--query 'LoadBalancers[0].LoadBalancerArn' \
--output text)
# Utworzenie grupy docelowej
TG_ARN=$(aws elbv2 create-target-group \
--name spring-boot-targets \
--protocol HTTP \
--port 8080 \
--vpc-id $VPC_ID \
--target-type ip \
--health-check-path /health \
--query 'TargetGroups[0].TargetGroupArn' \
--output text)
# Utworzenie nasłuchiwacza
aws elbv2 create-listener \
--load-balancer-arn $LB_ARN \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=$TG_ARN
Po utworzeniu Load Balancera, musimy zaktualizować naszą usługę ECS, aby go używała:
aws ecs update-service \
--cluster spring-boot-cluster \
--service spring-boot-service \
--load-balancers "targetGroupArn=$TG_ARN,containerName=spring-boot-container,containerPort=8080"
🔄 Automatyzacja wdrażania z CI/CD
Ostatnim krokiem jest automatyzacja procesu wdrażania przy użyciu CI/CD, co pozwoli na automatyczne aktualizacje aplikacji po zmianach w kodzie.
Konfiguracja CI/CD z GitHub Actions
Jeśli korzystasz z GitHub, możesz użyć GitHub Actions do automatyzacji procesu wdrażania. Utwórz plik .github/workflows/aws-deploy.yml
:
name: Deploy to AWS
on:
push:
branches: [ main ]
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Build with Maven
run: ./mvnw clean package -DskipTests
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push the image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: spring-boot-aws-example
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Update ECS service
run: |
aws ecs update-service --cluster spring-boot-cluster --service spring-boot-service --force-new-deployment
Aby powyższy workflow działał, musisz dodać swoje klucze AWS jako sekrety w repozytorium GitHub:
- Przejdź do repozytorium na GitHub → Settings → Secrets
- Dodaj
AWS_ACCESS_KEY_ID
iAWS_SECRET_ACCESS_KEY
⚠️ Ostrzeżenie: Zawsze używaj zasady najmniejszych uprawnień przy tworzeniu kluczy dostępu dla CI/CD. Stwórz oddzielnego użytkownika IAM z uprawnieniami tylko do zasobów, które są potrzebne do wdrożenia.
🔒 Bezpieczeństwo i najlepsze praktyki
Wdrażając aplikacje w AWS, nie można zapominać o bezpieczeństwie:
✅ Twoja Checklista Bezpieczeństwa:
- 🔐 Użyj IAM Roles zamiast kluczy dostępu gdy tylko to możliwe
- 🧩 Zastosuj segmentację sieci - umieść aplikację w prywatnej podsieci i użyj NAT Gateway do komunikacji z internetem
- 📊 Włącz monitoring i logowanie - użyj CloudWatch do monitorowania aplikacji
- 🔄 Regularne aktualizacje - utrzymuj obraz Docker i zależności aplikacji aktualne
- 🔍 Skanuj obrazy Docker pod kątem luk bezpieczeństwa przed wdrożeniem
- 🚧 Ogranicz ruch sieciowy do niezbędnego minimum w grupach zabezpieczeń
📈 Monitorowanie i zarządzanie
Monitorowanie aplikacji jest kluczowe dla zapewnienia jej niezawodności.
CloudWatch Logs
ECS automatycznie wysyła logi do CloudWatch, jeśli skonfigurowałeś logConfiguration
w definicji zadania. Możesz przejrzeć logi w konsoli AWS lub za pomocą AWS CLI:
aws logs get-log-events --log-group-name /ecs/spring-boot-task --log-stream-name ecs/spring-boot-container/abc123
Alarmy CloudWatch
Warto skonfigurować alarmy, które powiadomią Cię o problemach z aplikacją:
aws cloudwatch put-metric-alarm \
--alarm-name spring-boot-cpu-high \
--alarm-description "CPU utilization high" \
--metric-name CPUUtilization \
--namespace AWS/ECS \
--statistic Average \
--period 60 \
--threshold 70 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=ClusterName,Value=spring-boot-cluster Name=ServiceName,Value=spring-boot-service \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:eu-central-1:ACCOUNT_ID:my-notifications
Auto Scaling
Skonfiguruj auto scaling, aby automatycznie zwiększać liczbę zadań w odpowiedzi na wzrost obciążenia:
# Utworzenie polityki skalowania
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/spring-boot-cluster/spring-boot-service \
--min-capacity 2 \
--max-capacity 10
# Polityka skalowania oparta na wykorzystaniu CPU
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/spring-boot-cluster/spring-boot-service \
--policy-name cpu-tracking-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
"ScaleOutCooldown": 60,
"ScaleInCooldown": 60
}'
💰 Optymalizacja kosztów
AWS Fargate rozlicza Cię na podstawie użytych zasobów (CPU i pamięć). Oto kilka wskazówek, jak zoptymalizować koszty:
- Dostosuj rozmiar zadania - używaj tylko tyle CPU i pamięci, ile faktycznie potrzebuje Twoja aplikacja
- Korzystaj z Reserved Instances dla przewidywalnych obciążeń
- Używaj Auto Scaling by dostosować liczbę zadań do aktualnego obciążenia
- Monitoruj i analizuj koszty za pomocą AWS Cost Explorer
- Rozważ użycie Spot Instances dla zadań niewrażliwych na przerwy w działaniu
✨ Pro Tip: Użyj AWS Compute Optimizer do otrzymania rekomendacji dotyczących optymalnych ustawień Fargate dla Twojej aplikacji.
❓ FAQ - Odpowiedzi na Twoje Pytania
Jaka jest różnica między ECS EC2 a ECS Fargate?
W ECS EC2 musisz zarządzać instancjami EC2, na których działają kontenery. W Fargate nie zarządzasz żadnymi serwerami - AWS zajmuje się tym za Ciebie. Fargate jest prostszy w użyciu, ale może być droższy przy dużych obciążeniach.
Czy mogę używać Fargate do aplikacji produkcyjnych?
Tak, Fargate jest w pełni gotowy do obsługi aplikacji produkcyjnych. Wiele firm używa go do swoich krytycznych aplikacji.
Jak mogę debugować problemy z aplikacją na Fargate?
CloudWatch Logs jest głównym narzędziem do debugowania. Upewnij się, że Twoja aplikacja wysyła szczegółowe logi. Możesz też użyć AWS X-Ray do śledzenia żądań.
Czy mogę wdrożyć aplikację wielokontenerową na Fargate?
Tak, definicja zadania może zawierać wiele kontenerów, które będą działać na tej samej instancji Fargate.
Jakie są zalecane praktyki zabezpieczania mojej aplikacji Spring Boot na AWS?
Użyj HTTPS, ogranicz dostęp za pomocą grup zabezpieczeń, przechowuj sekrety w AWS Secrets Manager, używaj IAM Roles, regularnie aktualizuj zależności Spring Boot, aby chronić się przed znanymi podatnościami.
🏁 Podsumowanie - Gotowy na Sukces?
W tym przewodniku omówiliśmy kompleksowy proces wdrażania aplikacji Spring Boot na AWS przy użyciu kontenerów Docker, ECS i Fargate. Poznałeś kluczowe kroki od przygotowania aplikacji, przez konteneryzację, konfigurację usług AWS, aż po automatyzację wdrażania i monitorowanie.
Wdrożenie w tej architekturze daje Ci skalowalność, wysoką dostępność i elastyczność, które są niezbędne w dzisiejszym szybko zmieniającym się środowisku IT. Zaczynając od tych podstaw, możesz dalej rozwijać swoją infrastrukturę o bardziej zaawansowane funkcje, takie jak CI/CD, zarządzanie sekretami czy monitoring aplikacji.
🚀 Czas na Działanie
Sprawdź nasze usługi hostingowe z pełnym wsparciem dla deweloperów
Nie czekaj i przenieś swoją aplikację do chmury już dziś, korzystając z profesjonalnego wsparcia zespołu IQHost!
Czy ten artykuł był pomocny?
Twoja strona WordPress działa wolno?
Sprawdź nasz hosting WordPress z ultraszybkimi dyskami NVMe i konfiguracją serwera zoptymalizowaną pod kątem wydajności. Doświadcz różnicy już dziś!
Sprawdź ofertę hostingu