如何使用 Elastic beanstalk 和 Dockerrun.aws.json 正确部署到 AWS?
Posted
技术标签:
【中文标题】如何使用 Elastic beanstalk 和 Dockerrun.aws.json 正确部署到 AWS?【英文标题】:How do you deploy properly to AWS with Elastic beanstalk and Dockerrun.aws.json? 【发布时间】:2015-02-24 06:48:48 【问题描述】:我目前有一个本地运行的 docker 镜像,并且私有地托管在 hub.docker.com 上。
在容器内,我有 rails、puma、nginx。 Elastic beanstalk 能够从 docker hub 成功拉取镜像,但之后无法执行任何操作。
AWS 有 nginx 并返回此错误。谁能指出我做错了什么?
AWS 错误日志
-------------------------------------
/var/log/nginx/error.log
-------------------------------------
2014/12/27 08:48:34 [emerg] 3161#0: no host in upstream ":80" in /etc/nginx/conf.d/elasticbeanstalk-nginx-docker-upstream.conf:2
更多 AWS 错误日志
nginx: [emerg] no host in upstream ":80" in /etc/nginx/conf.d/elasticbeanstalk-nginx- docker-upstream.conf:2
nginx: configuration file /etc/nginx/nginx.conf test failed
Failed to start nginx, abort deployment (Executor::NonZeroExitStatus)
at /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/executor-1.0/lib/executor/exec.rb:81:in `sh'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/executor-1.0/lib/executor.rb:15:in `sh'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/executable.rb:63:in `execute!'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/hook-directory-executor.rb:29:in `block (2 levels) in run!'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/activity.rb:169:in `call'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/activity.rb:169:in `exec'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/activity.rb:126:in `timeout_exec'
from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.1.0/gems/beanstalk-core-1.0/lib/elasticbeanstalk/activity.rb:110:in `block
错误的src文件
upstream docker
server :80;
keepalive 256;
这是我的文件。
Dockerfile
FROM ruby:2.1.5
#################################
# native libs
#################################
RUN apt-get update -qq
RUN apt-get install -qq -y build-essential
RUN apt-get install -qq -y libpq-dev
RUN apt-get install -qq -y nodejs
RUN apt-get install -qq -y npm
RUN apt-get install -qq -y nginx
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#################################
# Install Nginx.
#################################
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx
ADD config/nginx.conf /etc/nginx/sites-enabled/default
EXPOSE 80
#################################
# Symlinking Nodejs for ubuntu
# -- http://***.com/questions/26320901/cannot-install-nodejs-usr-bin-env-node-no-such-file-or-directory
#################################
RUN ln -s /usr/bin/nodejs /usr/bin/node
#################################
# NPM install globals
#################################
RUN npm install bower -g
#################################
# Rails
#################################
RUN mkdir /app
WORKDIR /app
ADD . /app
ENV RAILS_ENV production
ENV SECRET_KEY_BASE test123
RUN bundle install --without development test
RUN bundle exec rake bower:install
RUN bundle exec rake assets:precompile
CMD foreman start -f Procfile
Dockerrun.aws.json
"AWSEBDockerrunVersion": "1",
"Authentication":
"Bucket": "aws-bucket",
"Key": ".dockercfg"
,
"Image":
"Name": "ericraio/my-image",
"Update": "true"
,
"Ports": [
"ContainerPort": "80"
],
"Logging": "/var/log/nginx"
NGINX
upstream rails_app
server unix:///app/tmp/sockets/puma.sock fail_timeout=0;
server
# listen 80 deferred;
# server_name domain.tld www.domain.tld;
root /app/public;
try_files $uri/index.html $uri @rails_app;
location @rails_app
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://rails_app;
error_page 500 504 /500.html;
error_page 502 /502.html;
error_page 503 /503.html;
client_max_body_size 4G;
keepalive_timeout 10;
【问题讨论】:
【参考方案1】:问题是在 EC2 上容器无法运行。 Amazon 使用此命令构建 IP 地址并设置环境变量。
EB_CONFIG_NGINX_UPSTREAM_IP=$(docker inspect `cat $EB_CONFIG_DOCKER_STAGING_APP_FILE` | jq -r .[0].NetworkSettings.IPAddress)
然后amazon用这行来构建IP地址。
EB_CONFIG_NGINX_UPSTREAM_PORT=`cat $EB_CONFIG_DOCKER_STAGING_PORT_FILE`
我的端口 80 已暴露,但由于我的容器无法运行,我没有主机。这就是您收到此错误的原因。
no host in upstream ":80"
【讨论】:
但是为什么容器会失败。我在 Docker 中部署了一个 java 应用程序并在 :9000 上遇到了同样的错误。 @ChrisFellows 如果您的容器无法运行,那么亚马逊无法构建 IP 地址。亚马逊确实需要输出一条错误消息。尝试在本地构建和运行容器,看看你的输出是什么。 本地运行良好。还执行 docker ps -a 向我显示 docker 容器已启动并正在运行。但是,如果我尝试 curl 127.0.0.1:9000 (这就是 Dockerfile 中的 EXPOSE 内容),没有骰子。它不会连接。仍在努力寻找根本问题。 终于想通了。尽管文档说 Dockerfile 将优先于 Dockerrun.aws.conf,但来自 Dockerrun 的某些东西却把事情搞砸了。我只是把它拿出来,一切都奏效了。我不知道是什么搞砸了那里。这是一个blog article,我将一些关键的日志记录/配置文件放在一起。希望能为外面的人服务。 @ChrisFellows 太棒了!【参考方案2】:如上所述,容器可能已失败。部署脚本无法找到 NGINX 必须将呼叫转发到的 IP。
所以这个异常不是最初的原因。为了知道最初发生了什么:
-
使用 SSH 连接您的 EC2 实例
sudo docker ps -a
确定哪个容器 ID 与您的应用程序相关联(该命令是查找它的好方法)。
sudo docker 日志 [CONTAINER ID]
我在这个页面找到了答案:https://forums.aws.amazon.com/thread.jspa?messageID=626464
【讨论】:
谢谢!在我的情况下,容器拒绝正常关闭,因此启动新容器的部署命令由于内存不足而失败。重启解决了这个问题(暂时)。以上是关于如何使用 Elastic beanstalk 和 Dockerrun.aws.json 正确部署到 AWS?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AWS elastic-beanstalk 中更改我的 python 版本
如何使用 aws cli 在 Elastic Beanstalk 上上传和部署?
如何使用 CLI 为 Elastic Beanstalk 配置 VPC
AWS Elastic Beanstalk - 如何使用 npm 和 webpack 构建捆绑 JS