2

I have a FastAPI/Uvicorn/SQLAlchemy app that I'm trying to run in ECS. I have successfully run the app via docker compose, but when I try to deploy the container in ecs I get the following error:

executable file not found in $PATH:

I am trying to run this command:

bash -c alembic -c alembic.ini upgrade head && gunicorn --bind 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker src.backend_service.main:app

I have tried this via the "command" section of the ECS UI.

My Dockerfile looks like this:

# NOTE: this image has to be built from the root directory since it contains files and folders from there
# docker build -t backend_service .

# Pull base image
FROM --platform=linux/amd64 python:3.10.11-slim-buster

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /code/

# Install dependencies
COPY ./src/backend_service/requirements_backend_service.txt requirements_backend_service.txt
RUN pip3 install -r requirements_backend_service.txt

COPY ./src/backend_service /code/src/backend_service/
COPY ./db_alembic /code/db_alembic
COPY ./alembic.ini /code/alembic.ini


ENV PATH="/code/venv/bin:$PATH"
ENV PATH="/code:$PATH"

ENV PYTHONPATH=/code

EXPOSE 8000

And my Docker Compose file looks like this:

backend_service:
    platform: linux/amd64
    environment:
      ENV: dev
    image: backend_service:latest
    build:
      dockerfile: ./Dockerfile.backend
    command: bash -c "alembic -c alembic.ini upgrade head && gunicorn --bind 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker src.backend_service.main:app"
    volumes:
        - ./src/backend_service:/code/src/backend_service
    ports:
      - "8000:8000"

My ecs task definition looks like this:

{
    "taskDefinitionArn": "arn:aws:ecs:XXXXXXXXX:task-definition/run_backend_service_manual:3",
    "containerDefinitions": [
        {
            "name": "backend_service",
            "image": "XXXXXXXXX/ecr-repository-dev-v1:backend_service_latest",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "backend_service-8000-tcp",
                    "containerPort": 8000,
                    "hostPort": 8000,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "command": [
                "bash -c alembic -c alembic.ini upgrade head && gunicorn --bind 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker src.backend_service.main:app"
            ],
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "workingDirectory": "/code/",
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/run_backend_service_manual",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "eu-central-1",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
    ],
    "family": "run_backend_service_manual",
    "taskRoleArn": "arn:aws:iam::XXXXXXXXX:role/dev-ecs-execution-v1",
    "executionRoleArn": "arn:aws:iam::XXXXXXXXX:role/dev-ecs-execution-v1",
    "networkMode": "awsvpc",
    "revision": 3,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.28"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "ecs.capability.task-eni"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "1024",
    "memory": "2048",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "2024-12-31T19:56:03.600Z",
    "registeredBy": "arn:aws:iam::XXXXXXXXX:root",
    "enableFaultInjection": false,
    "tags": []
}

I think this might have something to do with how I'm passing the command because it works via Docker Compose. I have tried the docker run documentation and have tried putting the parameters in a list (["paramq1", "param2"]) but I keep getting the same error.

What might I be doing wrong?

4
  • 2
    Is it exactly the same docker image you are running in both docker compose and ECS? You need to show your ECS task definition (JSON format) or at least a screenshot of what you are doing in ECS or something. Your question includes the details of what works (docker compose), but does not include any real detail of what doesn't work (ECS). I will say this sort of thing is MUCH simpler if you just add a script like run.sh to your docker image, that has the actual command inside of it, and then all you have to do is have ECS run the script. Commented Dec 31, 2024 at 22:58
  • @Mark B I've added the task definition json. Commented Jan 1 at 13:06
  • Side note: please don't run migrations at every launch. DB schema update is a deployment operation, while container restart may happen independently. Commented Jan 1 at 14:34
  • 2
    For the main problem: does "command": ["bash", "-c", "alembic ... && gunicorn ..."] work (only three parts)? And is your error message complete (does it really end after the colon)? Commented Jan 1 at 14:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.