如何通过Bitbucket Pipelines将多容器Docker-Compose部署至ECR/ECS?
多容器Docker-Compose项目推送至ECS的实现方案及流程优化
一、解决多镜像批量推送ECR的问题
当前配置中atlassian/aws-ecr-push-image管道仅支持单个镜像推送,无法处理docker-compose构建的多服务镜像。需修改推送步骤,通过脚本遍历所有服务镜像完成批量打标与推送:
1. 修正Docker-Compose配置错误
先修复docker-compose.yml中service2的容器名冲突问题:
version: '3.8' services: service1: container_name: service1 build: context: https://my-git-repo.git env_file: - .env networks: - my-app-network expose: - 3001 ports: - 3001:3001 restart: on-failure service2: container_name: service2 # 原配置为service1,此处修正 build: context: https://my-service1-git-repo.git env_file: - .env networks: - my-app-network expose: - 3002 ports: - 3002:3002 restart: on-failure volumes: my-data: external: false networks: my-app-network: external: false driver: bridge
2. 修改Bitbucket Pipeline推送步骤
替换原Push Image to Registry步骤,用脚本批量处理所有服务镜像:
- step: name: Push Images to ECR image: atlassian/pipelines-awscli services: - docker script: # 登录ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com # 获取所有服务名 - SERVICES=$(docker-compose config --services) # 遍历服务,打标并推送 - for SERVICE in $SERVICES; do # 获取本地镜像名 LOCAL_IMAGE=$(docker-compose images -q $SERVICE | xargs docker inspect -f '{{.RepoTags}}' | cut -d'[' -f2 | cut -d']' -f1) # 构建ECR镜像标签 ECR_IMAGE="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$APPLICATION_NAME:$SERVICE-$BITBUCKET_COMMIT" # 打标签 docker tag $LOCAL_IMAGE $ECR_IMAGE # 推送至ECR docker push $ECR_IMAGE done
需在Bitbucket仓库变量中添加
AWS_ACCOUNT_ID(你的AWS账号ID)。
二、适配跨仓库触发的部署流程
你已实现从service repo触发deployment repo的Pipeline,接下来优化为增量部署:
1. Service Repo触发时传递关键参数
在service repo的Pipeline中,触发deployment repo时传递当前服务名和提交哈希:
# service repo的bitbucket-pipelines.yml pipelines: branches: develop: - step: name: Trigger Deployment Pipeline script: - pipe: atlassian/trigger-pipeline:5.0.0 variables: BITBUCKET_USERNAME: $BITBUCKET_USERNAME BITBUCKET_APP_PASSWORD: $BITBUCKET_APP_PASSWORD REPOSITORY: <你的deployment仓库名> BRANCH: develop CUSTOM_PIPELINE_NAME: deploy-service VARIABLES: > { "SERVICE_NAME": "service1", "IMAGE_TAG": "$BITBUCKET_COMMIT" }
2. Deployment Repo接收参数并增量处理
在deployment repo中定义自定义管道,仅处理指定服务:
# deployment repo的bitbucket-pipelines.yml pipelines: custom: deploy-service: - step: name: Build & Push Target Service image: python:3.8.1 services: - docker script: - pip install docker-compose # 仅构建指定服务 - docker-compose build $SERVICE_NAME # 登录ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com # 打标并推送 - LOCAL_IMAGE=$(docker-compose images -q $SERVICE_NAME | xargs docker inspect -f '{{.RepoTags}}' | cut -d'[' -f2 | cut -d']' -f1) - ECR_IMAGE="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$APPLICATION_NAME:$SERVICE_NAME-$IMAGE_TAG" - docker tag $LOCAL_IMAGE $ECR_IMAGE - docker push $ECR_IMAGE - step: name: Update ECS Service deployment: Production image: atlassian/pipelines-awscli script: # 更新ECS服务,使用新镜像 - aws ecs update-service --cluster $ECS_CLUSTER_NAME --service $SERVICE_NAME --force-new-deployment --region $AWS_DEFAULT_REGION
三、流程优化建议
- 镜像标签规范化:用
服务名-提交哈希作为ECR镜像标签,避免镜像覆盖,便于追溯与回滚。 - 缓存优化:构建步骤启用Docker层缓存,减少重复构建时间:
services: - docker caches: - docker - 环境分离:为dev、staging、prod环境分别创建
docker-compose.dev.yml、docker-compose.staging.yml、docker-compose.prod.yml,配合对应.env文件,避免配置混淆。 - 权限最小化:为Bitbucket的AWS IAM用户分配最小权限,仅允许ECR推送和ECS更新相关操作,避免过度授权。
- 错误处理与通知:添加Pipeline失败通知(如Slack),配置ECS服务回滚策略,确保部署失败时快速恢复。
- 全量部署触发:在deployment repo中添加手动触发的全量部署管道,用于首次部署或批量更新所有服务。
内容的提问来源于stack exchange,提问作者power-cut
相关产品推荐
相关产品推荐

