I am deploying a compose docker to AWS ECS. The compose contains two services: one postgres and our api running on port 8000.
$ compose-ecs up
ApiService ServiceSchedulerInitiated: Task failed ELB health checks in (target-group arn:aws:elasticloadbalancing:us-east-1:821470956622:targetgroup/laclie-ApiTC-HTNTTIBU9DVM/03d34a43d358c4b5)
compose.yaml
services:
api:
image: outsidethecode/la-client-api
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000" # Map API app port to host
depends_on:
- database # Make sure the API app starts after the database is ready
environment:
DATABASE_URL: "postgresql://postgres:postgres@database/laclient"
ROCKET_ADDRESS: 0.0.0.0
ROCKET_ENV: release
nginx:
image: nginx:latest
ports:
- "80:80"
depends_on:
- api
database:
image: postgres:latest # Use the official PostgreSQL image
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: laclient
ports:
- "5432:5432" # Map PostgreSQL port to host
As to my understanding, to pass the health check we have to have a GET / resource to return 200. I've done that but that resource is on port 8000 similar to the rest of api resources.
Here is the convert version of the cloudformation:
AWSTemplateFormatVersion: 2010-09-09
Resources:
ApiService:
DependsOn:
- ApiTCP8000Listener
- DatabaseService
Properties:
Cluster:
Fn::GetAtt:
- Cluster
- Arn
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentController:
Type: ECS
DesiredCount: 1
LaunchType: FARGATE
LoadBalancers:
- ContainerName: api
ContainerPort: 8000
TargetGroupArn:
Ref: ApiTCP8000TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- Ref: DefaultNetwork
Subnets:
- subnet-0bd97383cdf4d5896
- subnet-0a52cf89f7c027b20
- subnet-0ffafc731067a7d01
- subnet-0de9ebed3a873fccf
- subnet-00ae1e792af0e2e1d
- subnet-0095a287059d86962
PlatformVersion: 1.4.0
PropagateTags: SERVICE
SchedulingStrategy: REPLICA
ServiceRegistries:
- RegistryArn:
Fn::GetAtt:
- ApiServiceDiscoveryEntry
- Arn
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: api
TaskDefinition:
Ref: ApiTaskDefinition
Type: AWS::ECS::Service
ApiServiceDiscoveryEntry:
Properties:
Description: '"api" service discovery entry in Cloud Map'
DnsConfig:
DnsRecords:
- TTL: 60
Type: A
RoutingPolicy: MULTIVALUE
HealthCheckCustomConfig:
FailureThreshold: 1
Name: api
NamespaceId:
Ref: CloudMap
Type: AWS::ServiceDiscovery::Service
ApiTCP8000Listener:
Properties:
DefaultActions:
- ForwardConfig:
TargetGroups:
- TargetGroupArn:
Ref: ApiTCP8000TargetGroup
Type: forward
LoadBalancerArn:
Ref: LoadBalancer
Port: 8000
Protocol: TCP
Type: AWS::ElasticLoadBalancingV2::Listener
ApiTCP8000TargetGroup:
Properties:
Port: 8000
Protocol: TCP
Tags:
- Key: com.docker.compose.project
Value: laclientapi
TargetType: ip
VpcId: vpc-08cccbaf3a61d85bf
Type: AWS::ElasticLoadBalancingV2::TargetGroup
ApiTaskDefinition:
Properties:
ContainerDefinitions:
- Command:
- us-east-1.compute.internal
- laclientapi.local
Essential: false
Image: docker/ecs-searchdomain-sidecar:1.0
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: Api_ResolvConf_InitContainer
- DependsOn:
- Condition: SUCCESS
ContainerName: Api_ResolvConf_InitContainer
Environment:
- Name: DATABASE_URL
Value: postgresql://postgres:postgres@database/laclient
- Name: ROCKET_ADDRESS
Value: 0.0.0.0
- Name: ROCKET_ENV
Value: release
Essential: true
Image: docker.io/outsidethecode/la-client-api:latest@sha256:9768ba65e9a2d1aa5055960cf90003f8181ed99ca85043d494a762538789b161
LinuxParameters: {}
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: api
PortMappings:
- ContainerPort: 8000
HostPort: 8000
Protocol: tcp
Cpu: "256"
ExecutionRoleArn:
Ref: ApiTaskExecutionRole
Family: laclientapi-api
Memory: "512"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Type: AWS::ECS::TaskDefinition
ApiTaskExecutionRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Condition: {}
Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: api
Type: AWS::IAM::Role
CloudMap:
Properties:
Description: Service Map for Docker Compose project laclientapi
Name: laclientapi.local
Vpc: vpc-08cccbaf3a61d85bf
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Cluster:
Properties:
ClusterName: laclientapi
Tags:
- Key: com.docker.compose.project
Value: laclientapi
Type: AWS::ECS::Cluster
DatabaseService:
DependsOn:
- DatabaseTCP5432Listener
Properties:
Cluster:
Fn::GetAtt:
- Cluster
- Arn
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentController:
Type: ECS
DesiredCount: 1
LaunchType: FARGATE
LoadBalancers:
- ContainerName: database
ContainerPort: 5432
TargetGroupArn:
Ref: DatabaseTCP5432TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- Ref: DefaultNetwork
Subnets:
- subnet-0bd97383cdf4d5896
- subnet-0a52cf89f7c027b20
- subnet-0ffafc731067a7d01
- subnet-0de9ebed3a873fccf
- subnet-00ae1e792af0e2e1d
- subnet-0095a287059d86962
PlatformVersion: 1.4.0
PropagateTags: SERVICE
SchedulingStrategy: REPLICA
ServiceRegistries:
- RegistryArn:
Fn::GetAtt:
- DatabaseServiceDiscoveryEntry
- Arn
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: database
TaskDefinition:
Ref: DatabaseTaskDefinition
Type: AWS::ECS::Service
DatabaseServiceDiscoveryEntry:
Properties:
Description: '"database" service discovery entry in Cloud Map'
DnsConfig:
DnsRecords:
- TTL: 60
Type: A
RoutingPolicy: MULTIVALUE
HealthCheckCustomConfig:
FailureThreshold: 1
Name: database
NamespaceId:
Ref: CloudMap
Type: AWS::ServiceDiscovery::Service
DatabaseTCP5432Listener:
Properties:
DefaultActions:
- ForwardConfig:
TargetGroups:
- TargetGroupArn:
Ref: DatabaseTCP5432TargetGroup
Type: forward
LoadBalancerArn:
Ref: LoadBalancer
Port: 5432
Protocol: TCP
Type: AWS::ElasticLoadBalancingV2::Listener
DatabaseTCP5432TargetGroup:
Properties:
Port: 5432
Protocol: TCP
Tags:
- Key: com.docker.compose.project
Value: laclientapi
TargetType: ip
VpcId: vpc-08cccbaf3a61d85bf
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DatabaseTaskDefinition:
Properties:
ContainerDefinitions:
- Command:
- us-east-1.compute.internal
- laclientapi.local
Essential: false
Image: docker/ecs-searchdomain-sidecar:1.0
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: Database_ResolvConf_InitContainer
- DependsOn:
- Condition: SUCCESS
ContainerName: Database_ResolvConf_InitContainer
Environment:
- Name: POSTGRES_DB
Value: laclient
- Name: POSTGRES_PASSWORD
Value: postgres
- Name: POSTGRES_USER
Value: postgres
Essential: true
Image: docker.io/library/postgres:latest@sha256:f1aaf6f8be5552bef66c5580efbd2942c37d7277cd0416ef4939fa34bf0baf31
LinuxParameters: {}
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: database
PortMappings:
- ContainerPort: 5432
HostPort: 5432
Protocol: tcp
Cpu: "256"
ExecutionRoleArn:
Ref: DatabaseTaskExecutionRole
Family: laclientapi-database
Memory: "512"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Type: AWS::ECS::TaskDefinition
DatabaseTaskExecutionRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Condition: {}
Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: database
Type: AWS::IAM::Role
Default8000Ingress:
Properties:
CidrIp: 0.0.0.0/0
Description: api:8000/tcp on default network
FromPort: 8000
GroupId:
Ref: DefaultNetwork
IpProtocol: TCP
ToPort: 8000
Type: AWS::EC2::SecurityGroupIngress
Default80Ingress:
Properties:
CidrIp: 0.0.0.0/0
Description: nginx:80/tcp on default network
FromPort: 80
GroupId:
Ref: DefaultNetwork
IpProtocol: TCP
ToPort: 80
Type: AWS::EC2::SecurityGroupIngress
Default5432Ingress:
Properties:
CidrIp: 0.0.0.0/0
Description: database:5432/tcp on default network
FromPort: 5432
GroupId:
Ref: DefaultNetwork
IpProtocol: TCP
ToPort: 5432
Type: AWS::EC2::SecurityGroupIngress
DefaultNetwork:
Properties:
GroupDescription: laclientapi Security Group for default network
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.network
Value: laclientapi_default
VpcId: vpc-08cccbaf3a61d85bf
Type: AWS::EC2::SecurityGroup
DefaultNetworkIngress:
Properties:
Description: Allow communication within network default
GroupId:
Ref: DefaultNetwork
IpProtocol: "-1"
SourceSecurityGroupId:
Ref: DefaultNetwork
Type: AWS::EC2::SecurityGroupIngress
LoadBalancer:
Properties:
LoadBalancerAttributes:
- Key: load_balancing.cross_zone.enabled
Value: "true"
Scheme: internet-facing
Subnets:
- subnet-0bd97383cdf4d5896
- subnet-0a52cf89f7c027b20
- subnet-0ffafc731067a7d01
- subnet-0de9ebed3a873fccf
- subnet-00ae1e792af0e2e1d
- subnet-0095a287059d86962
Tags:
- Key: com.docker.compose.project
Value: laclientapi
Type: network
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
LogGroup:
Properties:
LogGroupName: /docker-compose/laclientapi
Type: AWS::Logs::LogGroup
NginxService:
DependsOn:
- NginxTCP80Listener
- ApiService
Properties:
Cluster:
Fn::GetAtt:
- Cluster
- Arn
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentController:
Type: ECS
DesiredCount: 1
LaunchType: FARGATE
LoadBalancers:
- ContainerName: nginx
ContainerPort: 80
TargetGroupArn:
Ref: NginxTCP80TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- Ref: DefaultNetwork
Subnets:
- subnet-0bd97383cdf4d5896
- subnet-0a52cf89f7c027b20
- subnet-0ffafc731067a7d01
- subnet-0de9ebed3a873fccf
- subnet-00ae1e792af0e2e1d
- subnet-0095a287059d86962
PlatformVersion: 1.4.0
PropagateTags: SERVICE
SchedulingStrategy: REPLICA
ServiceRegistries:
- RegistryArn:
Fn::GetAtt:
- NginxServiceDiscoveryEntry
- Arn
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: nginx
TaskDefinition:
Ref: NginxTaskDefinition
Type: AWS::ECS::Service
NginxServiceDiscoveryEntry:
Properties:
Description: '"nginx" service discovery entry in Cloud Map'
DnsConfig:
DnsRecords:
- TTL: 60
Type: A
RoutingPolicy: MULTIVALUE
HealthCheckCustomConfig:
FailureThreshold: 1
Name: nginx
NamespaceId:
Ref: CloudMap
Type: AWS::ServiceDiscovery::Service
NginxTCP80Listener:
Properties:
DefaultActions:
- ForwardConfig:
TargetGroups:
- TargetGroupArn:
Ref: NginxTCP80TargetGroup
Type: forward
LoadBalancerArn:
Ref: LoadBalancer
Port: 80
Protocol: TCP
Type: AWS::ElasticLoadBalancingV2::Listener
NginxTCP80TargetGroup:
Properties:
Port: 80
Protocol: TCP
Tags:
- Key: com.docker.compose.project
Value: laclientapi
TargetType: ip
VpcId: vpc-08cccbaf3a61d85bf
Type: AWS::ElasticLoadBalancingV2::TargetGroup
NginxTaskDefinition:
Properties:
ContainerDefinitions:
- Command:
- us-east-1.compute.internal
- laclientapi.local
Essential: false
Image: docker/ecs-searchdomain-sidecar:1.0
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: Nginx_ResolvConf_InitContainer
- DependsOn:
- Condition: SUCCESS
ContainerName: Nginx_ResolvConf_InitContainer
Essential: true
Image: docker.io/library/nginx:latest@sha256:32da30332506740a2f7c34d5dc70467b7f14ec67d912703568daff790ab3f755
LinuxParameters: {}
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group:
Ref: LogGroup
awslogs-region:
Ref: AWS::Region
awslogs-stream-prefix: laclientapi
Name: nginx
PortMappings:
- ContainerPort: 80
HostPort: 80
Protocol: tcp
Cpu: "256"
ExecutionRoleArn:
Ref: NginxTaskExecutionRole
Family: laclientapi-nginx
Memory: "512"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Type: AWS::ECS::TaskDefinition
NginxTaskExecutionRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Condition: {}
Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Tags:
- Key: com.docker.compose.project
Value: laclientapi
- Key: com.docker.compose.service
Value: nginx
Type: AWS::IAM::Role
I am not sure what to do to pass the ECS health check. Any help is much appreciated. Many thanks