This guide explains how to build and deploy the Bento Collector Docker image to AWS ECR for use with ECS.
- AWS Account with ECR repository created
- AWS CLI installed and configured
- Docker installed and running
- Git for commit hash tagging
First, create an ECR repository in AWS:
aws ecr create-repository \
--repository-name bento-collector \
--region us-east-1 \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256Add the following to your .env file (copy from env.example):
ECR_REGISTRY=123456789012.dkr.ecr.us-east-1.amazonaws.com
ECR_REPOSITORY=bento-collector
AWS_REGION=us-east-1Replace 123456789012 with your AWS account ID.
For automated builds via GitHub Actions, configure the following:
Go to your GitHub repository → Settings → Secrets and variables → Actions → Variables, and add:
ECR_REGISTRY: Your ECR registry URL (e.g.,123456789012.dkr.ecr.us-east-1.amazonaws.com)ECR_REPOSITORY: Your ECR repository name (e.g.,bento-collector)AWS_REGION: AWS region (e.g.,us-east-1)
Add the following secret:
AWS_ROLE_ARN: ARN of the IAM role for GitHub Actions OIDC authentication
Example: arn:aws:iam::123456789012:role/github-actions-ecr-role
Create an IAM role with the following trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:YOUR_ORG/YOUR_REPO:*"
}
}
}
]
}Attach the following policy to the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "*"
}
]
}The easiest way to build and push manually:
./scripts/build_and_push_ecr.sh [tag]Examples:
# Use commit hash as tag
./scripts/build_and_push_ecr.sh
# Use custom tag
./scripts/build_and_push_ecr.sh v1.0.0
# Use branch name
./scripts/build_and_push_ecr.sh developIf you prefer to run commands manually:
# 1. Login to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# 2. Build the image
docker buildx build \
--platform linux/arm64 \
--load \
-t YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/bento-collector:latest \
-f Dockerfile.ecs .
# 3. Push the image
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/bento-collector:latestThe workflow (.github/workflows/deploy.yml) automatically:
- Builds and pushes on pushes to
mainordevelopbranches - Tags images appropriately:
mainbranch →latesttagdevelopbranch →developtag- Tags (v*) → version tag
- All commits → commit hash tag
- Uses OIDC for secure authentication (no long-lived credentials)
- Caches Docker layers for faster builds
You can trigger the workflow manually from GitHub Actions tab:
- Go to Actions → "Build and Push to ECR"
- Click "Run workflow"
- Optionally provide a custom tag
Create an ECS task definition that uses the ECR image. The image supports command overrides to run different collectors.
{
"family": "bento-collector",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "bento-collector",
"image": "YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/bento-collector:latest",
"essential": true,
"command": [
"-c",
"/app/examples/kafka/consume-from-kafka.yaml"
],
"environment": [
{
"name": "FLEXPRICE_API_HOST",
"value": "api.cloud.flexprice.io"
},
{
"name": "FLEXPRICE_API_KEY",
"value": "your_api_key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/bento-collector",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}aws ecs register-task-definition \
--cli-input-json file://task-definition.jsonYou can run different collectors by overriding the command in the task definition:
# Kafka consumer
-c /app/examples/kafka/consume-from-kafka.yaml
# Kafka consumer with DLQ
-c /app/examples/kafka/consume-from-kafka-with-dlq.yaml
# Dummy events generator
-c /app/examples/dummy-events-to-flexprice.yamlTo use your own YAML configuration:
- Option 1: Mount a volume with your config file
- Option 2: Build a custom image with your configs included
- Option 3: Use ECS task definition to override the command with a config from S3 or mounted volume
Example with S3 (requires additional setup):
{
"command": [
"-c",
"/app/config/my-custom-collector.yaml"
],
"mountPoints": [
{
"sourceVolume": "config",
"containerPath": "/app/config"
}
]
}The workflow and script create multiple tags:
- Branch-based:
latest(main),develop(develop branch) - Version tags:
v1.0.0,v1.2.3, etc. (from git tags) - Commit hash: Short commit hash (e.g.,
a1b2c3d)
This allows you to:
- Use
latestfor production - Use
developfor staging - Pin to specific versions or commits for reproducibility
- OIDC Authentication: GitHub Actions uses OIDC (no long-lived credentials)
- Non-root user: Container runs as non-root user (
bento) - Minimal base image: Uses Alpine Linux for smaller attack surface
- Image scanning: Enable ECR image scanning (configured in repository setup)
- Secrets management: Use AWS Secrets Manager or ECS task secrets for sensitive data
- Check AWS credentials:
aws sts get-caller-identity - Verify ECR repository exists and you have permissions
- Ensure you're logged in:
aws ecr get-login-password --region us-east-1 | docker login ...
- Verify
ECR_REGISTRYandECR_REPOSITORYare correct - Ensure repository exists:
aws ecr describe-repositories
- Check repository variables are set correctly
- Verify IAM role ARN in secrets
- Check OIDC provider is configured in AWS
- Review workflow logs for detailed error messages
- Verify image URI is correct
- Check task definition command override
- Review CloudWatch logs for container errors
- Ensure environment variables are set correctly