docker-archive / compose-cli

Easily run your Compose application to the cloud with compose-cli
Apache License 2.0
956 stars 253 forks source link

No ARM64 version of docker/ecs-searchdomain-sidecar which is needed for Docker ECS context #2190

Closed KymPohl closed 1 year ago

KymPohl commented 1 year ago

I'm using a docker ecs context to produce a CloudFormation template on a linux/arm64 platform, and targeting a linux/arm64 deployment in aws. Running my docker compose up (using the ecs context) produces the TaskDefinition below as part of the outputted CloudFormation template. This TaskDefinition makes reference to a docker/ecs-searchdomain-sidecar:1.0 image which apparently only supports an amd64 architecture. Consequently the "_ResolvConf_InitContainer" component of the resulting deployment fails to startup on the target arm64 platform (runtime error --> "exec /resolv: exec format error"). FWIW, if I remove the relevant section of the TaskDefinmition of the template everything deploys fine to aws and executes without issue on the target arm64 platform.

So it seems that I either need to somehow locate an arm64-compatible image of ecs-searchdomain-sidecar:1.0, or is there a different recommended approach for using docker compose using an ecs context to perform an arm64 deployment to aws fargate?

Docker Hub entry for ecs-searchdomain-sidecar ... https://hub.docker.com/r/docker/ecs-searchdomain-sidecar/tags

  ApiTaskDefinition:
    Properties:
      ContainerDefinitions:
        - Command:
            - us-west-2.compute.internal
            - buildingscience-analyzer.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: buildingscience-analyzer
          Name: Api_ResolvConf_InitContainer
        - DependsOn:
            - Condition: SUCCESS
              ContainerName: Api_ResolvConf_InitContainer
          Environment:
            - Name: SERVER_PORT
              Value: "80"
          Essential: true
          Image: <my-app-image>
          LinuxParameters: {}
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group:
                Ref: LogGroup
              awslogs-region:
                Ref: AWS::Region
              awslogs-stream-prefix: buildingscience-analyzer
          Name: api
          PortMappings:
            - ContainerPort: 80
              HostPort: 80
              Protocol: tcp
      Cpu: "256"
      ExecutionRoleArn:
        Ref: ApiTaskExecutionRole
      Family: buildingscience-analyzer-api
      Memory: "512"
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      RuntimePlatform:
        CpuArchitecture: ARM64
        OperatingSystemFamily: LINUX
    Type: AWS::ECS::TaskDefinition
cmcclen commented 1 year ago

I've ran into a version of this problem the past few days. I'm trying to avoid Cloudformation, Kubernetes and EKS. The ARM64 target versus X86_64 oil not so much an issue. From my M1 laptop, the compose request seems to default to ARM64 though. The only way to override that seemed to be using: x-aws-cloudformation: Resources: CpdbTaskDefinition: Properties: RuntimePlatform: CpuArchitecture: X86_64 OperatingSystemFamily: LINUX in my compose.yml file.

Until moments ago this did not seem to work. This morning using X86_64 or AMD64 seems to override the default ARM64 and avoid the sidecar issue. Surprisingly AMD64 works, although not documented as allowed value. ARM64 is still failing.

mtelvers commented 1 year ago

I have exactly this issue. I started out with a simple docker-compose.yaml to deploy Caddy. This works fine and creates an X86_64 service.

version: "3.4"
services:
  live:
    image: caddy
    ports:
      - target: 80
    deploy:
      replicas: 2

Adding in the CpuArchitecture...

x-aws-cloudformation:
  Resources:
    LiveTaskDefinition:
      Properties:
        RuntimePlatform:
          CpuArchitecture: ARM64

causes the deployment to fail:

# docker --context awsecs compose -f docker-compose.yaml -p test up
... blah ...
LiveService TaskFailedToStart: Task failed to start

Using an ARM64 machine I published ecs-searchdomain-sidecar for ARM64

git clone https://github.com/docker/compose-cli.git
cd compose-cli/ecs/resolv
docker build --tag myorg/ecs-searchdomain-sidecar .
docker push myorg/ecs-searchdomain-sidecar:latest

Then the very untidy part -- run docker --context awsecs compose -f docker-compose.yaml -p test convert and extract the ContainerDefinitions section. Paste this onto the end of the x-aws-cloudformation block in the docker-compose.yaml file. Updating the Image: section to the newly published Docker container resulting in:

version: "3.4"
services:
  live:
    image: caddy
    ports:
      - target: 80
    deploy:
      replicas: 2

x-aws-cloudformation:
  Resources:
    LiveTaskDefinition:
      Properties:
        RuntimePlatform:
          CpuArchitecture: ARM64
        ContainerDefinitions:
          - Command:
              - us-east-1.compute.internal
              - test.local
            Essential: false
            Image: myorg/ecs-searchdomain-sidecar:latest
            LogConfiguration:
              LogDriver: awslogs
              Options:
                awslogs-group:
                  Ref: LogGroup
                awslogs-region:
                  Ref: AWS::Region
                awslogs-stream-prefix: test
            Name: Live_ResolvConf_InitContainer
          - DependsOn:
              - Condition: SUCCESS
                ContainerName: Live_ResolvConf_InitContainer
            Essential: true
            Image: docker.io/library/caddy:latest@sha256:918c1a90862f95b1f8ea1b5cc869b0d2653bf0d6e18b0010771e17b96155403a
            LinuxParameters: {}
            LogConfiguration:
              LogDriver: awslogs
              Options:
                awslogs-group:
                  Ref: LogGroup
                awslogs-region:
                  Ref: AWS::Region
                awslogs-stream-prefix: test
            Name: live
            PortMappings:
              - ContainerPort: 80
                HostPort: 80

This works. Sadly, I can't seem to make a more surgical edit to just change the Image: of ecs-seachdomain-sidecar. Any edits to ContainerDefinitions replaces the whole block.

KymPohl commented 1 year ago

mtelvers, thanks for the tip. Following your helpful instructions I built a multi-arch version of the ecs-searchdomain-sidecar component, hosted it in AWS ECR, added the modified TaskDefinition x-aws-cloudformation overlays for my app's various services to my respective compose file, and deployed my app to AWS. Everything deployed fine on the target linux/arm64 platform. Thanks again for you recommendation...

taco-chen commented 1 year ago

@KymPohl Is there any possibility to share your docker-compose.yml? Thanks!