Ви витратили тиждень на налаштування Serverless Framework, а при першому деплої Lambda функції не стартують — помилка 502, в CloudWatch порожньо. Знайомо? Ми розгорнули 50+ serverless-проєктів на AWS, GCP та Azure, і щоразу стикалися з одними й тими ж граблями: криві IAM-ролі, забуті змінні середовища, неоптимальна збірка з гігантським cold start. За нашими даними, правильно налаштований serverless-стек знижує витрати на інфраструктуру в 3–5 разів, але лише якщо конфігурація виконана без помилок. У цій статті ми розберемо кожен крок: від встановлення до CI/CD, з реальними конфігураціями та перевіреними практиками. Ви дізнаєтеся, як уникнути типових помилок, прискорити холодний старт на 40% та організувати безпечне зберігання секретів. Ми спираємося на досвід 50+ проєктів і постійно оновлюємо конфігурації під останні версії плагінів та runtime.
Як налаштувати Serverless Framework за 1 день?
Встановлення та базова структура
npm install -g serverless
serverless --version # 3.x або 4.x
serverless create --template aws-nodejs-typescript --path my-service
cd my-service
npm install
Структура проєкту включає папку src/functions/ з обробниками та src/libs/ для допоміжних модулів. Файл serverless.yml — серце конфігурації.
Що таке холодний старт і як з ним боротися?
Холодний старт — час від першого запиту до виконання handler'а, викликаний ініціалізацією runtime та завантаженням коду. Наші тести показують, що при неоптимальній збірці cold start сягає 500 мс. Використовуйте esbuild з tree shaking — це зменшує бандл на 30% і знижує холодний старт до 100-200 мс. Виключайте вбудовані залежності, такі як @aws-sdk/*, які вже є в оточенні Lambda. Для функцій з високими вимогами до швидкості застосовуйте Provisioned Concurrency (до 300% вартості, але cold start = 0).
serverless.yml — правильна конфігурація
service: my-web-service
frameworkVersion: '3'
plugins:
- serverless-esbuild
- serverless-offline
- serverless-dotenv-plugin
provider:
name: aws
runtime: nodejs20.x
region: eu-west-1
stage: ${opt:stage, 'dev'}
memorySize: 512
timeout: 10
logRetentionInDays: 14
environment:
NODE_ENV: ${self:provider.stage}
DB_PASSWORD: ${ssm:/my-service/${self:provider.stage}/db-password~true}
API_KEY: ${ssm:/my-service/api-key~true}
iam:
role:
statements:
- Effect: Allow
Action: [s3:GetObject, s3:PutObject]
Resource: 'arn:aws:s3:::${self:custom.bucketName}/*'
- Effect: Allow
Action: [dynamodb:Query, dynamodb:PutItem, dynamodb:UpdateItem]
Resource: !GetAtt UsersTable.Arn
httpApi:
cors:
allowedOrigins: ['https://my-site.com', 'http://localhost:3000']
allowedHeaders: ['Content-Type', 'Authorization']
allowedMethods: [GET, POST, PUT, DELETE]
custom:
bucketName: my-service-${self:provider.stage}-assets
esbuild:
bundle: true
minify: ${strToBool(${ssm:/my-service/minify, 'false'})}
sourcemap: true
target: node20
platform: node
concurrency: 10
external:
- '@aws-sdk/*'
- 'pg-native'
serverless-offline:
httpPort: 3001
lambdaPort: 3002
functions:
- ${file(src/functions/api/index.ts)}
- ${file(src/functions/worker/index.ts)}
resources:
Resources:
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${self:provider.stage}-users
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
- AttributeName: sk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
Конфігурація функції та middleware
// src/functions/api/index.ts
import type { AWS } from '@serverless/typescript';
const apiFunction: AWS['functions'] = {
api: {
handler: 'src/functions/api/handler.main',
events: [{
httpApi: {
method: 'ANY',
path: '/api/{proxy+}',
authorizer: {
name: 'jwtAuthorizer',
type: 'jwt',
identitySource: '$request.header.Authorization',
issuerUrl: 'https://cognito-idp.eu-west-1.amazonaws.com/${env:COGNITO_POOL_ID}',
audience: ['${env:COGNITO_CLIENT_ID}'],
},
},
}],
environment: {},
},
};
export default apiFunction;
// src/libs/lambda.ts
import middy from '@middy/core';
import middyJsonBodyParser from '@middy/http-json-body-parser';
import httpErrorHandler from '@middy/http-error-handler';
import cors from '@middy/http-cors';
import type { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2 } from 'aws-lambda';
type Handler = (event: APIGatewayProxyEventV2) => Promise<APIGatewayProxyStructuredResultV2>;
export const middyfy = (handler: Handler) =>
middy(handler)
.use(middyJsonBodyParser())
.use(httpErrorHandler())
.use(cors({ origin: process.env.ALLOWED_ORIGIN ?? '*' }));
Як керувати середовищами ефективно?
Використовуйте різні стейджі та SSM Parameter Store для безпечного зберігання секретів. Параметри з шифруванням додаються суфіксом ~true. Для локальної розробки запускайте serverless offline start, а для тестування окремої функції — serverless invoke local --function. Не зберігайте секрети в Git — це одна з найчастіших помилок, що призводять до витоків.
Чому esbuild — найкращий вибір для збірки?
За даними AWS Serverless Developer Guide, esbuild з tree shaking зменшує розмір бандла до 40% і знижує cold start. На відміну від webpack, він працює в 10-100 разів швидше і не вимагає складної конфігурації. Для native-бібліотек, таких як sharp, створюйте Lambda Layer — це дозволяє тримати їх окремо та оновлювати незалежно.
mkdir -p layer/nodejs
cd layer/nodejs
npm install sharp
Підключення шару:
layers:
sharp:
path: layer
compatibleRuntimes: [nodejs20.x]
Порівняння Serverless vs VPS
| Критерій | Serverless (Lambda) | VPS (Nginx + Node) |
|---|---|---|
| Масштабування | Автоматичне | Ручне (auto-scaling) |
| Вартість на простої | ~0 | Оплата за ресурси |
| Cold start | 100-500 мс | 0 мс |
| Макс час виконання | 15 хв | Без обмежень |
| Обслуговування інфраструктури | Провайдер | Ви самі |
При нестабільному навантаженні serverless економить до 5 разів порівняно з VPS. Для постійного трафіку >1000 запитів/с VPS може бути дешевшим.
Популярні плагіни Serverless Framework
| Плагін | Призначення |
|---|---|
| serverless-esbuild | Швидка збірка з tree shaking |
| serverless-offline | Локальна емуляція Lambda та API Gateway |
| serverless-dotenv-plugin | Підвантаження .env-файлів |
| serverless-ssm-fetch | Автоматичне отримання параметрів із SSM |
CI/CD для Serverless Framework
Налаштуйте GitHub Actions або GitLab CI для автоматичного деплою на різні стейджі. У workflow вкажіть кроки: checkout, встановлення залежностей, деплой через npx serverless deploy --stage prod. Секрети зберігайте в GitHub Secrets або GitLab CI Variables. Типовий pipeline dev → staging → prod займає 2-3 хвилини.
Що входить у налаштування під ключ?
- Конфігурація
serverless.ymlз IAM, VPC, середовищами - Оптимізація збірки (esbuild, tree shaking, Lambda Layers)
- CI/CD (GitHub Actions / GitLab CI) для dev/staging/prod
- Управління секретами через SSM або Secrets Manager
- Документація з архітектурною схемою
- Навчання команди
- Підтримка після деплою
Строки
Базова налаштування з однією функцією та деплоєм — 1 день. Повноцінна інфраструктура з кількома функціями, DynamoDB, SSM та CI/CD — 3–4 дні. Міграція з Express — 1–2 тижні. Вартість розраховується індивідуально залежно від складності та обсягу робіт.
Зв'яжіться з нами для аудиту вашої serverless-архітектури. Отримайте консультацію з налаштування Serverless Framework — ми допоможемо уникнути типових помилок і прискорити розробку.







