If you’re building containerized apps and want zero-downtime deployments, GitLab CI/CD with Amazon ECS Fargate and Blue/Green deployments is a powerful combo. In this step-by-step guide, we’ll show you how to deploy a Docker app using GitLab pipelines, Amazon CodeDeploy, and ECS Fargate — with smooth traffic shifting and health-based validation.


Why ECS Fargate with GitLab?

  • No server management – Fargate is fully managed.
  • GitLab CI/CD automates your build and deployment pipeline.
  • Blue/Green deployment ensures zero-downtime updates with rollback safety.

Project Overview

We’ll create a simple Flask app, containerize it, push it to Amazon ECR, and use GitLab to deploy it to ECS Fargate with CodeDeploy Blue/Green.

deploy docker ecs blue green from gitlab
deploy docker ecs blue green from gitlab

What you’ll get:

  • Docker app with /health check
  • .gitlab-ci.yml pipeline
  • Blue/Green deployment with ALB test listener
  • Automatic traffic shifting after health validation

Step 1: Project Structure

Your project might look like this:

ecs-fargate-app/
├── Dockerfile
├── app.py
├── taskdef.json
├── .gitlab-ci.yml

Step 2: Dockerize the App

Dockerfile

FROM python:3.9-slim
COPY app.py .
RUN pip install flask
CMD ["python", "app.py"]

app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
return "Hello from ECS!"

@app.route('/health')
def health():
return "OK", 200

if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

Step 3: Task Definition (taskdef.json)

Update the image placeholder later in the GitLab pipeline.

{
"family": "my-task",
"containerDefinitions": [
{
"name": "my-container",
"image": "<IMAGE_URI>",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"essential": true
}
]
}

Step 4: GitLab CI/CD Pipeline

Create .gitlab-ci.yml in your root directory:

stages:
- build
- deploy
- validate

image: docker:24.0.5

services:
- docker:24.0.5-dind

variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
AWS_DEFAULT_REGION: us-east-1
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
ECR_URI: $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$ECR_REPO

before_script:
- apk add --no-cache curl bash python3 py3-pip jq
- pip3 install awscli
- aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_URI

build:
stage: build
script:
- docker build -t $ECR_REPO:$IMAGE_TAG .
- docker tag $ECR_REPO:$IMAGE_TAG $ECR_URI:$IMAGE_TAG
- docker push $ECR_URI:$IMAGE_TAG

deploy:
stage: deploy
script:
- |
sed "s|<IMAGE_URI>|$ECR_URI:$IMAGE_TAG|g" taskdef.json > rendered-taskdef.json

- |
TASK_DEF_ARN=$(aws ecs register-task-definition --cli-input-json file://rendered-taskdef.json | jq -r '.taskDefinition.taskDefinitionArn')

- |
cat <<EOF > appspec.json
{
"version": 1,
"Resources": [
{
"TargetService": {
"Type": "AWS::ECS::Service",
"Properties": {
"TaskDefinition": "$TASK_DEF_ARN",
"LoadBalancerInfo": {
"ContainerName": "my-container",
"ContainerPort": 80
}
}
}
}
]
}
EOF

- |
APPSPEC_CONTENT=$(jq -Rs . < appspec.json)
aws deploy create-deployment \
--application-name "$CODEDEPLOY_APP" \
--deployment-group-name "$CODEDEPLOY_GROUP" \
--revision revisionType=AppSpecContent,appSpecContent="{\"content\": $APPSPEC_CONTENT, \"sha256\": \"\"}"

validate:
stage: validate
script:
- |
echo "Validating health endpoint on test listener..."
for i in {1..10}; do
curl -f http://$TEST_LB_DNS/health && break || sleep 5
done
echo "App passed health check"

Step 5: GitLab CI/CD Environment Variables

Go to your GitLab project ➝ Settings ➝ CI/CD ➝ Variables and add:

KeyDescription
AWS_ACCESS_KEY_IDYour IAM access key
AWS_SECRET_ACCESS_KEYYour IAM secret key
AWS_ACCOUNT_IDYour AWS account number
ECR_REPOYour ECR repo name (e.g., ecs-app)
CODEDEPLOY_APPCodeDeploy Application Name
CODEDEPLOY_GROUPDeployment Group Name
TEST_LB_DNSALB test listener DNS name

Step 6: How Blue/Green Works with Fargate

  • GitLab pipeline pushes a new Docker image to ECR
  • Registers a new ECS Task Definition
  • Creates a new deployment via CodeDeploy
  • ECS launches new task behind the test target group
  • ALB health checks the new version via /health
  • If healthy, CodeDeploy shifts traffic to green version
CodeDeploy Blue Green Validation
CodeDeploy Blue Green Validation

No downtime. No stress.


Conclusion

By combining GitLab CI/CD with ECS Fargate and Blue/Green deployments, you get a modern, scalable, and safe deployment pipeline. Even though Fargate limits lifecycle hooks, its simplicity and scalability make it perfect for most workloads.