【问题标题】:HTTP 500 Deploying Elixir/Phoenix to AWS Elastic BeanstalkHTTP 500 将 Elixir/Phoenix 部署到 AWS Elastic Beanstalk
【发布时间】:2018-04-30 10:10:31
【问题描述】:

我在部署到 AWS/Elastic Beanstalk 所需的 elixir/phoenix 配置方面遇到问题。 (按照此处找到的指南:https://thoughtbot.com/blog/deploying-elixir-to-aws-elastic-beanstalk-with-docker - 我的 Dockerfile 看起来相似,除了更新的库)。

我可以在eb local run 中运行,但在推动生产时遇到了麻烦。

但是,当我尝试部署到 EB 时,我收到以下警告,并且它崩溃了:

Environment health has transitioned from Degraded to Severe. 
100.0 % of the requests are failing with HTTP 5xx. 
Command failed on all instances. 
Incorrect application version found on all instances. Expected version "app-8412-171116_115503" (deployment 5). 
ELB processes are not healthy on all instances. 
100.0 % of the requests to the ELB are erroring with HTTP 4xx. 
Insufficient request rate (0.5 requests/min) to determine application health (5 minutes ago). 
ELB health is failing or not available for all instances.

我想知道是否有人可以让我知道我的配置是否正确。

我一直在尝试很多事情,但我想我已经弄糊涂了,因为我现在只是在猜测。

config.exs

use Mix.Config

config :newsly,
  ecto_repos: [Newsly.Repo]

config :logger, :console,
  format: "$time $metadata[$level] $message\n",
  metadata: [:request_id]

import_config "#{Mix.env}.exs"

prod.exs

use Mix.Config

config :logger, :console, format: "[$level] $message\n"

config :phoenix, :stacktrace_depth, 5


import_config "prod.secret.exs"

prod.secret.exs

use Mix.Config

config :ex_aws,
  access_key_id: System.get_env("AWS_ACCESS_KEY_ID"),
  secret_access_key: System.get_env("AWS_SECRET_ACCESS_KEY"),
  bucket_name: System.get_env("BUCKET_NAME"),
  s3: [
   scheme: "https://",
   host: System.get_env("BUCKET_NAME"),
   region: "us-west-2"
  ]

config :newsly, Newsly.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: System.get_env("USERNAME"),
  password: System.get_env("PASSWORD"),
  database: System.get_env("DATABASE"),
  hostname: System.get_env("DBHOST"),
  # sometimes hostname is db (like in the docker-compose method - play with this one)
  pool_size: 10


config :newsly, Newsly.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: false,
  url: [scheme: "http", host: System.get_env("HOST"), port: 4000],
  secret_key_base: System.get_env("SECRET_KEY_BASE"),
  pubsub: [adapter: Phoenix.PubSub.PG2, pool_size: 5, name: Newsly.PubSub],
  check_origin: false,
  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
                    cd: Path.expand("../", __DIR__)]]

在我的 Dockerfile 中,我将环境变量设置如下;

ENV AWS_ACCESS_KEY_ID=nottelling
ENV AWS_SECRET_ACCESS_KEY=nottelling
ENV BUCKET_NAME=s3 storage bucket (not eb related)
ENV SECRET_KEY_BASE=nottelling
ENV HOST=host name of my eb instance im uploading to
ENV DBHOST=AWS rds host that holds postgres
ENV USERNAME=nottelling
ENV PASSWORD=nottelling

我的实例运行状况报告未显示为红色,并显示以下警告:

Environment health has transitioned from Warning to Severe. 100.0 % of the requests are failing with HTTP 5xx. ELB processes are not healthy on all instances. ELB health is failing or not available for all instances.

NGINX 似乎被线条呛到了

2017/11/16 17:59:46 [error] 28815#0: *99 connect() failed (113: No route to host) while connecting to upstream, client: 172.31.20.108, server: , request: "GET / HTTP/1.1", upstream: "http://172.17.0.2:4000/", host: "172.31.38.244"

在 nginx 日志中。

如果我查看 eb 活动日志,我有

duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11

这似乎正在杀死 nginx

[2017-11-16T18:02:33.927Z] INFO  [29355] - [Application update app-8412-171116_115503@5/AppDeployStage1/AppDeployEnactHook/01flip.sh] : Completed activity. Result:
  nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11
  Stopping nginx: [  OK  ]
  Starting nginx: nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11
  [  OK  ]
  iptables: Saving firewall rules to /etc/sysconfig/iptables: [  OK  ]
  Stopping current app container: e0161742ee69...
  Error response from daemon: No such image: aws_beanstalk/current-app:latest
  Making STAGING app container current...
  Untagged: aws_beanstalk/staging-app:latest
  eb-docker start/running, process 1398
  Docker container e25f2b562f4f is running aws_beanstalk/current-app.

有人有什么想法吗?

编辑:

挖掘我发现的 nginx 日志

map $http_upgrade $connection_upgrade {
    default        "upgrade";
    ""            "";
}

server {
    listen 80;

    gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
        set $year $1;
        set $month $2;
        set $day $3;
        set $hour $4;
    }
    access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

    access_log    /var/log/nginx/access.log;

    location / {
        proxy_pass            http://docker;
        proxy_http_version    1.1;

        proxy_set_header    Connection            $connection_upgrade;
        proxy_set_header    Upgrade                $http_upgrade;
        proxy_set_header    Host                $host;
        proxy_set_header    X-Real-IP            $remote_addr;
        proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
    }
}

所以,

duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11

似乎指的是这一行:

gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

但是在这一点上,如果 nginx 仅仅因为它定义了 text/html 两次而窒息,我会感到惊讶。所以现在我不确定....

编辑编辑: 我应该提到我的 nginx/error.logs 如下所示(最后几行重复 ad-infinum):

2017/11/16 17:19:22 [warn] 18445#0: duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11
2017/11/16 17:19:22 [warn] 18460#0: duplicate MIME type "text/html" in /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11
2017/11/16 17:20:06 [error] 18467#0: *11 connect() failed (113: No route to host) while connecting to upstream, client: 172.31.32.139, server: , request: "GET / HTTP/1.1", upstream: "http://172.17.0.2:4000/", host: "172.31.38.244"
2017/11/16 17:20:15 [error] 18467#0: *13 connect() failed (113: No route to host) while connecting to upstream, client: 172.31.20.108, server: , request: "GET / HTTP/1.1", upstream: "http://172.17.0.2:4000/", host: "172.31.38.244"
2017/11/16 17:20:21 [error] 18467#0: *15 connect() failed (113: No route to host) while connecting to upstream, client: 172.31.32.139, server: , request: "GET / HTTP/1.1", upstream: "http://172.17.0.2:4000/", host: "172.31.38.244"
2017/11/16 17:20:30 [error] 18467#0: *17 connect() failed (113: No route to host) while connecting to upstream, client: 172.31.20.108, server: , request: "GET / HTTP/1.1", upstream:

这是问题的核心

NGINX 根本无法将入口点连接到应用程序,我不知道为什么!

更新:

根据 Kevin Johnson 的建议,我成功地将我的 Dockerfile 推送到 AWS ECR,并且当我 eb deploy 用良好的 Dockerrun.aws.json 编辑我的应用程序时,它正确编译。这实际上是执行此操作的首选方式。 但是,我仍然遇到同样的错误!我不知道发生了什么,但我想我可以肯定地说我的 Dockerfile 成功编译。

我认为 AWS 中存在问题,我不确定是什么问题。

更新

问题与 NGINX 路由问题有关。在一个干净的问题中提供更多信息:How Do I modify NGINX routing on Elastic Beanstalk AWS?

【问题讨论】:

  • 端点不适用于url: [scheme: "http", host: System.get_env("HOST"), port: 4000]。尝试仅使用指定的端口运行它。
  • 很抱歉 PatNowak 我不明白你在说什么。 url: [scheme: "http", host: System.get_env("HOST"), port: 4000] 正在使用指定的端口运行。写在那里的端口 4000。嗯?
  • 我的意思是:只申请url: [port: 4000]。我很确定host 在弹性豆茎上存在问题,我不太确定scheme 是否也能正常工作。
  • 好吧,我试试然后回复你
  • @PatNowak - 我已将您指定的行更改为 url: [port: 4000] 并得到 100.0 % of the requests are failing with HTTP 5xx. ELB processes are not healthy on all instances. ELB health is failing or not available for all instances. 如果我 ssh 进入 eb 实例,则 docker 容器无法启动,我仍然有 nginx 错误。

标签: amazon-web-services nginx amazon-ec2 elixir phoenix-framework


【解决方案1】:

我高度怀疑您正在处理的问题是:

  1. 您的 Dockerrun.aws.config 文件指向 ECS Repository 上不存在的 docker 映像。这由错误消息指示: Error response from daemon: No such image: aws_beanstalk/current-app:latest Making STAGING app container current... 当 EB 无法用最新配置替换实例时,它将求助于旧配置,这可能是您在设置 EB 时可能利用的 AWS 的 Hello World 应用程序。该容器没有在端口 4000 上运行 Web 服务,而您的 Dockerrun.aws.config 指定端口 4000。 (尽管您的 Dockerrun.aws.config 没有被 EB 替换为以前的工作版本,但我会感到惊讶) 所以检查Dockerrun.aws.config 并确保其中提到的图像端点确实存在。尝试在本地拉取它并相应地运行它。首先清理所有图像的本地环境并在需要时运行 docker 容器。

  2. 您在 docker 中运行的应用程序在启动时会立即崩溃。同样,EB 将检测到这一点并用之前的容器替换崩溃的容器,该容器再次没有打开端口 4000

【讨论】:

  • 好吧,正如我上面所说的 eb local run 有效,所以我不认为应用程序崩溃了。我不太明白 1. - 我没有这样做(我假设你的意思是ECR Repository),但我不明白为什么有必要这样做。我正在推送我的 dockerfile 和我的 dockerrun,所以 AWS 不应该从我提供的内容中构建吗?为什么需要外部 docker 存储库?我将完成这些步骤,看看是否解决了我的问题,但这让我很困惑。
  • 另外,我还没有听说过Dockerrun.aws.config。这不是我提供的文件,我只根据我链接的教程推了Dockerrun.aws.json。它应该是eb ssh repo 中的一个文件吗?如果是这样,它位于哪里?我在网上找不到参考。
  • 当您执行 eb deploy 时,您需要在 EB Docker 部署环境中关心的唯一资产是文件 Dockerrun.aws.config。这是 EB 将研究的配置文件以执行所有必要的操作。此配置文件将包含可以从(dockerhub、AWS ECR)下载映像的存储库以及您的所有端口设置。无需将您的裸代码上传到 EB。因此,您可以做的是,为部署目的创建一个单独的文件夹,进入其中并进行 eb 配置,设置所有内容,然后在该文件夹的根目录中添加 Dockerrun.aws.config
  • 要回答您的其他问题,是的,您也可以上传 Dockerfile,但Dockerrun.aws.json(不是Dockerrun.aws.config,我的错误)是所需的主要文件。如果您在Dockerrun.aws.json 中指定将构建的 elixir 容器推送到的远程 docker repo 的位置,则不需要 Dockerfile 等。
  • 你能提供一个提到Dockerrun.aws.config的链接吗?很抱歉我很迟钝,但我去过的每个网站都提到你需要使用DockerfileDockerrun.aws.json。他们都没有提到将图像上传到存储库,假设 AWS 将从 Dockerfile 构建图像(我的 eb-activity.logs 显示它确实如此)。如果您有其他方法,我会感兴趣,但我还需要更多内容。我的:Dockerfile:hastebin.com/momelofavo.nginx & Dockerrun:hastebin.com/umivigutow.json
猜你喜欢
  • 2020-03-24
  • 2015-09-20
  • 2018-09-06
  • 2019-10-30
  • 2020-08-14
  • 2020-08-02
  • 2014-12-25
  • 2020-07-03
  • 2014-10-30
相关资源
最近更新 更多