← Назад к вопросам
Приведи пример настройки сервиса с нуля
1.7 Middle🔥 232 комментариев
#Linux и администрирование
Комментарии (2)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Пример настройки веб-сервиса с нуля на AWS
Представлю пошаговый пример разворачивания веб-приложения с бэкендом на Node.js, фронтендом на React и базой данных PostgreSQL в облаке AWS. Использую инфраструктуру как код (IaC) через Terraform, контейнеризацию с Docker и оркестрацию через AWS ECS.
1. Архитектурный план
Создам отказоустойчивую среду с:
- VPC с публичными и приватными подсетями в 2 AZ
- Application Load Balancer (ALB) для входящего трафика
- ECS Fargate для контейнеров без управления серверами
- RDS PostgreSQL в приватной подсети
- S3 для статики фронтенда
- CloudWatch для логирования и мониторинга
2. Инфраструктура как код (Terraform)
# main.tf - основная конфигурация
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-west-1"
}
# Создание VPC
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "app-vpc"
cidr = "10.0.0.0/16"
azs = ["eu-west-1a", "eu-west-1b"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
tags = {
Environment = "production"
}
}
# Security Group для ALB
resource "aws_security_group" "alb_sg" {
name_prefix = "alb-sg-"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# RDS PostgreSQL
module "db" {
source = "terraform-aws-modules/rds/aws"
version = "6.0.0"
identifier = "appdb"
engine = "postgres"
engine_version = "15"
family = "postgres15"
instance_class = "db.t3.micro"
allocated_storage = 20
storage_encrypted = true
db_name = "app_production"
username = var.db_username
password = var.db_password
vpc_security_group_ids = [aws_security_group.db_sg.id]
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
tags = {
Environment = "production"
}
}
3. Docker-образы
# backend/Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
# frontend/Dockerfile
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
4. Конфигурация ECS Task Definition
{
"family": "app-task",
"networkMode": "awsvpc",
"executionRoleArn": "arn:aws:iam::account-id:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::account-id:role/ecsTaskRole",
"cpu": "1024",
"memory": "2048",
"requiresCompatibilities": ["FARGATE"],
"containerDefinitions": [
{
"name": "backend",
"image": "account-id.dkr.ecr.eu-west-1.amazonaws.com/backend:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"environment": [
{
"name": "DATABASE_URL",
"value": "postgresql://user:pass@db-host:5432/appdb"
},
{
"name": "NODE_ENV",
"value": "production"
}
],
"secrets": [
{
"name": "API_KEY",
"valueFrom": "arn:aws:secretsmanager:region:account-id:secret:api-key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/app",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "backend"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3
}
}
]
}
5. CI/CD Pipeline (GitHub Actions)
# .github/workflows/deploy.yml
name: Deploy to ECS
on:
push:
branches: [ main ]
env:
AWS_REGION: eu-west-1
ECR_REPOSITORY: backend
ECS_SERVICE: app-service
ECS_CLUSTER: app-cluster
ECS_TASK_DEFINITION: task-definition.json
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
run: |
aws ecr get-login-password --region $AWS_REGION | \
docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com
- name: Build, tag, and push image
run: |
docker build -t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY:latest .
docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY:latest
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION \
--query taskDefinition > task-definition.json
- name: Register new task definition
run: |
aws ecs register-task-definition --cli-input-json file://task-definition.json
- name: Update ECS service
run: |
aws ecs update-service \
--cluster $ECS_CLUSTER \
--service $ECS_SERVICE \
--task-definition $ECS_TASK_DEFINITION \
--force-new-deployment
6. Мониторинг и логирование
# cloudwatch-alarms.yml
Resources:
HighCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: "High-CPU-Utilization"
AlarmDescription: "CPU utilization > 70% for 5 minutes"
MetricName: "CPUUtilization"
Namespace: "AWS/ECS"
Statistic: "Average"
Period: 300
EvaluationPeriods: 1
Threshold: 70
ComparisonOperator: "GreaterThanThreshold"
Dimensions:
- Name: "ClusterName"
Value: "app-cluster"
- Name: "ServiceName"
Value: "app-service"
AlarmActions:
- !Ref CPUAutoScalingPolicy
7. Скрипт инициализации
#!/bin/bash
# deploy.sh - скрипт автоматического развертывания
set -e # Прерывать при ошибках
echo "=== Начало развертывания ==="
# Инициализация Terraform
echo "1. Инициализация Terraform..."
terraform init -backend-config="bucket=my-tfstate-bucket" \
-backend-config="key=app/terraform.tfstate"
# Проверка конфигурации
echo "2. Проверка конфигурации..."
terraform validate
# Планирование изменений
echo "3. План развертывания..."
terraform plan -out=tfplan -var-file="production.tfvars"
# Применение изменений
read -p "Применить изменения? (yes/no): " -r
if [[ $REPLY =~ ^[Yy]es$ ]]
then
echo "4. Применение конфигурации..."
terraform apply tfplan
fi
# Сборка и деплой приложения
echo "5. Сборка Docker образов..."
docker-compose -f docker-compose.prod.yml build
echo "6. Загрузка образов в ECR..."
aws ecr get-login-password --region eu-west-1 | docker login \
--username AWS \
--password-stdin $ACCOUNT_ID.dkr.ecr.eu-west-1.amazonaws.com
docker-compose -f docker-compose.prod.yml push
echo "7. Обновление сервиса ECS..."
aws ecs update-service \
--cluster app-cluster \
--service app-service \
--force-new-deployment
echo "8. Проверка деплоя..."
aws ecs wait services-stable \
--cluster app-cluster \
--services app-service
echo "=== Развертывание завершено ==="
echo "ALB DNS: $(terraform output -raw alb_dns_name)"
Ключевые принципы настройки:
- Идемпотентность - многократное выполнение дает одинаковый результат
- Неизменяемая инфраструктура - вместо изменения, создаем новые ресурсы
- Безопасность по умолчанию - минимальные необходимые права, секреты в менеджерах
- Наблюдаемость - логи, метрики и трейсинг из коробки
- Отказоустойчивость - распределение по AZ, health checks, автоматическое восстановление
Этот пример показывает полный цикл от инфраструктуры до деплоя приложения с учетом лучших практик DevOps: автоматизация, мониторинг, безопасность и масштабируемость.