You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS CDK部署Node-Express应用时栈卡最后阶段无报错但功能正常

问题描述

本人是AWS/CDK新手,正在将Node-Express应用构建至ECR并部署。应用功能正常,可正常访问端点,但CDK部署(本地或流水线执行)均卡在最后阶段,无报错信息。

相关CDK代码

import * as cdk from 'aws-cdk-lib';
import { CfnOutput, Duration } from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';
import { Networking } from '../imports/Networking';

interface DatabaseProps extends cdk.StackProps {
  databaseName: string,
  databasePass: string
}

export class WebApiStack extends cdk.Stack {

  constructor(scope: Construct, id: string, props: DatabaseProps) {
    super(scope, id, props);

    const vpc = Networking.createVpc(this);

    const executionRolePolicy = new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      resources: ['*'],
      actions: [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ]
    });

    const repository = ecr.Repository.fromRepositoryName(this, 'nodejs-repo', 'api')

    //Find a way to make it a generic object
    const cluster = new ecs.Cluster(this, 'Cluster', { vpc });

    // Add capacity to it
    cluster.addCapacity('DefaultAutoScalingGroupCapacity', {
      instanceType: new ec2.InstanceType("t2.micro"),
    });

    const taskDefinition = new ecs.Ec2TaskDefinition(this, 'TaskDef');

    const container = taskDefinition.addContainer('fullstack', {
      image: new ecs.Ec2Image(repository, 'latest'),
      cpu: 128,
      memoryReservationMiB: 256,
      logging: ecs.LogDrivers.awsLogs({ streamPrefix: 'nodejs' }),
      environment: {
        DatabasePassword: props.databasePass,
        DatabaseName: props.databaseName,
        ME_CONFIG_MONGODB_URL: "mongodb+srv://fake.mongodb.net/",
        SECRET_API:"fakeszzz",
        SECRET_COOKIE:'fakezz'
      }
    });

    // Instantiate an Amazon ECS Service
    const ecsService = new ecs.Ec2Service(this, 'Service', {
      cluster,
      taskDefinition,
    });

    taskDefinition.addToExecutionRolePolicy(executionRolePolicy);
    container.addPortMappings({
      containerPort: 3000
    });

    // Setup AutoScaling policy
    const scaling = ecsService.autoScaleTaskCount({ maxCapacity: 3, minCapacity: 1 });
    scaling.scaleOnCpuUtilization('CpuScaling', {
      targetUtilizationPercent: 90,
      scaleInCooldown: Duration.seconds(60),
      scaleOutCooldown: Duration.seconds(60)
    });

    const lb = new elbv2.ApplicationLoadBalancer(this, 'ALB', {
      vpc,
      internetFacing: true
    });
    
    const listener = lb.addListener('Listener', {
      port: 80,
    });

    listener.addTargets('Target', {
      port: 80,
      targets: [ecsService],
      healthCheck: { path: '/api/' }
    });

    listener.connections.allowDefaultPortFromAnyIpv4('Open to the world');

    new CfnOutput(this, 'webApi', { value: container.imageName });
  }
}

部署日志

WebApiStack | 48/53 | 3:27:26 AM | CREATE_COMPLETE      | AWS::SNS::Subscription                      | Cluster/DefaultAutoScalingGroupCapacity/DrainECSHook/Function/Topic (ClusterDefaultAutoScalingGroupCapacityDrainECSHookFunctionTopicC6667F16) 
WebApiStack | 49/53 | 3:27:35 AM | CREATE_COMPLETE      | AWS::Lambda::Permission                     | Cluster/DefaultAutoScalingGroupCapacity/DrainECSHook/Function/AllowInvoke:WebApiStackClusterDefaultAutoScalingGroupCapacityLifecycleHookDrainHookTopic27A34C51 (ClusterDefaultAutoScalingGroupCapacityDrainECSHookFunctionAllowInvokeWebApiStackClusterDefaultAutoScalingGroupCapacityLifecycleHookDrainHookTopic27A34C51E27DA75C) 
49/53 Currently in progress: WebApiStack, ServiceD69D759B

排查与解决方案

部署卡在ECS Service创建阶段,按以下方向排查修复:

  1. 端口映射不匹配
    ALB目标组配置的端口是80,但容器监听的是3000,导致健康检查失败,ECS服务无法完成部署。修改listener.addTargets的port参数为3000,或者在容器端口映射中添加主机端口80的配置:

    container.addPortMappings({
      containerPort: 3000,
      hostPort: 80
    });
    
  2. 检查任务启动日志
    到CloudWatch日志组中查找前缀为nodejs的日志流,查看容器启动时的具体报错,比如环境变量错误、依赖缺失、MongoDB连接失败等问题。

  3. EC2实例资源不足
    t2.micro实例资源有限,检查实例的CPU、内存使用率,若资源耗尽会导致任务无法启动。可尝试升级实例类型,或降低任务的CPU/内存配额。

  4. 安全组与网络配置

    • 确保EC2实例安全组允许ALB访问容器端口(3000),同时允许实例出站访问ECR、CloudWatch和MongoDB的网络。
    • 若使用私有子网,需配置NAT网关让实例能拉取ECR镜像;公有子网需确保实例有公网IP。
  5. 补充ECS服务部署配置
    添加部署策略参数,避免因默认配置导致的部署卡住:

    const ecsService = new ecs.Ec2Service(this, 'Service', {
      cluster,
      taskDefinition,
      deploymentConfiguration: {
        minHealthyPercent: 50,
        maxHealthyPercent: 200
      }
    });
    

内容的提问来源于stack exchange,提问作者calimses

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:42:41