带有 Django 的 AWS copilot 从未完成部署

Posted

技术标签:

【中文标题】带有 Django 的 AWS copilot 从未完成部署【英文标题】:AWS copilot with Django never finishes deploying 【发布时间】:2021-02-14 01:01:04 【问题描述】:

我已经按照这个简短的指南使用 docker 创建了一个 django 应用程序 https://docs.docker.com/compose/django/

然后按照副驾驶指令将容器向上推到 ECS: https://aws.amazon.com/blogs/containers/introducing-aws-copilot/

我还使用此示例来测试所有内容 - 效果很好: https://github.com/aws-samples/aws-copilot-sample-service 部署完成并输出和 URL 端点。

就我而言,一切都已成功构建,但是一旦部署了测试环境,它就会不断地构建:

72ff4719 size: 3055
⠏ Deploying load-bal:7158348 to test.

而且永远不会结束。我什至将 requirements.txt 缩小到最低限度。

我的 Dockerfile

FROM python:3.7.4
ENV PYTHONUNBUFFERED=1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
EXPOSE 80
COPY . /code/

docker-compose.yml

version: "3.8"
   
services:
  db:
    image: postgres
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

requirements.txt

Django==3.0.8
djangorestframework==3.11.0
gunicorn==20.0.4
pipenv==2020.6.2
psycopg2-binary==2.8.5
virtualenv==16.7.6

我遵循的说明:

sudo docker-compose run web django-admin startproject composeexample .

成功创建 Django 应用

copilot init

为应用和负载均衡器设置命名

选择创建测试环境

一切都成功构建,然后就坐在这里。我尝试了许多变体,但唯一有效的变体是在不涉及 django 的情况下进行副驾驶教学。

6f3494a64128: Pushed 
cfe650cc4def: Pushed 
a477d6671cc7: Pushed 
90df760355a7: Pushed 
574ea6c52bdd: Pushed 
d1573fad78d1: Pushed 
14c1ff636882: Pushed 
48ebd1638acd: Pushed 
31f78d833a92: Pushed 
2ea751c0f96c: Pushed 
7a435d49206f: Pushed 
9674e3075904: Pushed 
831b66a484dc: Pushed 
ini: digest: sha256:b7460876bc84b1a26e7513fa6d17b5bffd5560ae958a933984376ed2c9fe53f3 size: 3052
⠏ Deploying aiinterview-lb:ini to test. 

【问题讨论】:

【参考方案1】:

tl;dr 本教程使用的 Dockerfile 对于 Copilot 来说是不完整的。它需要一个包含

的额外行
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

并且EXPOSE 指令应更新为 8000。由于 Copilot 无法识别 Docker Compose 语法并且 Dockerfile 中没有指定命令或入口点,因此映像永远不会以 Copilot 的配置设置启动。

详情

AWS Copilot 是围绕“服务”设计的,其中包括图像、可能的 sidecar 和额外的存储资源。这意味着它的基本配置单元是 Docker 镜像和服务清单。它本身并不读取 Docker Compose 语法,因此 Copilot 知道的所有配置都是在 Dockerfile 或映像以及每个服务的 manifest.ymladdons 目录中指定的配置。

在这个设计用于 Docker Compose 的示例中,Dockerfile 没有任何类型的 CMDENTRYPOINT 指令,因此由 Copilot 推送到 Amazon ECR 的构建映像永远不会启动。本教程将映像的命令 (python manage.py runserver 0.0.0.0:8000) 指定为 docker-compose.yml 中的覆盖,因此您需要将 Dockerfile 更新为以下内容:

FROM python:3.7.4
ENV PYTHONUNBUFFERED=1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
EXPOSE 8000
COPY . /code/
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

请注意,我已将 EXPOSE 指令更改为 8000 以匹配来自 docker-compose.yml 的命令,并将 web 部分中指定的命令作为 CMD 指令添加到 Dockerfile。

你也想跑

copilot init --image postgres --name db --port 5432 --type "Backend Service" --deploy

这将创建在您的docker-compose.yml 中指定的数据库服务。您可能需要先运行它,以便您的 Web 容器在搜索凭据时不会启动失败。

其他一些注意事项:

您可以通过在db 的清单文件中添加variablessecrets 来指定您的数据库凭据,该文件是在您的工作区./copilot/db/manifest.yml 中创建的。有关如何向 SSM 添加密钥并使其可供您的 Copilot 服务访问的更多信息,check out our documentation
variables: 
  POSTGRES_DB: postgres
  POSTGRES_USER: postgres

secrets:
  POSTGRES_PASSWORD: POSTGRES_PASSWORD
您的数据库端点可通过db.$COPILOT_SERVICE_DISCOVERY_ENDPOINT 的服务发现访问——您可能需要更新连接到数据库的服务代码以反映此端点,而不是localhost 或0.0.0.0。

【讨论】:

嘿,非常感谢您的详尽回答。我一定会再试一次。 不客气!我们也非常乐意回答 github 或 gitter 上的问题!

以上是关于带有 Django 的 AWS copilot 从未完成部署的主要内容,如果未能解决你的问题,请参考以下文章

AWS Copilot 多负载均衡 Web 服务

带有 Django 的 AWS Beanstalk:eb create 抱怨未知配置设置“StaticFile”

使用带有 Compressor 的 Boto 的 Django AWS S3 无法压缩 UncompressableFileError

Apache 不在 443 (aws) 上为 Django 提供服务

“未提供身份验证凭据。” Django 和 AWS 应用程序

AWS Elasticbeanstalk 上的 Django:命令 02_createadmin 失败