【问题标题】:How to deploy Rails application on Amazon Elastic Beanstalk on a single container Docker environment如何在单个容器 Docker 环境中的 Amazon Elastic Beanstalk 上部署 Rails 应用程序
【发布时间】:2015-10-09 13:51:36
【问题描述】:

我一直在尝试将我的 Rails 应用程序停靠在 Elastic Beanstalk 上。有很多例子,但大多数都不适合我的具体用例。那就是:

  • 在单容器 Docker 环境下运行(因此不需要 docker-compose/fig)
  • 在 Amazon Elastic Beanstalk 上运行。
  • 使用passenger-docker 作为基础镜像(Ruby 变体之一)。
  • 传递由 Elastic Beanstalk 设置的环境变量(通过控制台的 CLI)。
  • 容器中的 Nginx 和乘客。
  • 能够安装自定义包(扩展它)。
  • 合理的.dockerignore文件。

这里的问题不是关于如何部署的过程,而是正确的 Docker 配置,它可以与具有上述特定标准的 Amazon Elastic Beanstalk 一起使用。

运行此程序的正确配置是什么?

【问题讨论】:

    标签: ruby-on-rails docker amazon-elastic-beanstalk


    【解决方案1】:

    这对我有用...

    Dockerfile

    在本例中,我使用phusion/passenger-ruby22:0.9.16 作为基础映像,因为:

    • 您的 Dockerfile 可以更小。
    • 它减少了编写正确 Dockerfile 所需的时间。您不必担心基础系统和堆栈,您可以只专注于您的应用。
    • 正确设置了基础系统。基本系统很容易出错,但是这个镜像做的一切都是正确的。 Learn more.
    • 它大大减少了运行 docker build 所需的时间,让您可以更快地迭代 Dockerfile。
    • 它减少了重新部署期间的下载时间。 Docker 只需要下载一次基础镜像:在第一次部署期间。在每次后续部署中,只会下载您对基础映像所做的更改。

    你可以learn more about it here ...无论如何,到Dockerfile

    # The FROM instruction sets the Base Image for subsequent instructions. As such,
    # a valid Dockerfile must have FROM as its first instruction. We use
    # phusion/baseimage as a base image. To make our builds reproducible, we make
    # sure we lock down to a specific version, not to `latest`!
    FROM phusion/passenger-ruby22:0.9.16
    
    # The MAINTAINER instruction allows you to set the Author field of the generated
    # images.
    MAINTAINER "Job King'ori Maina" <yo@kingori.co> (@itsmrwave)
    
    # The RUN instructions will execute any commands in a new layer on top of the
    # current image and commit the results. The resulting committed image will be
    # used for the next step in the Dockerfile.
    
    # === 1 ===
    
    # Prepare for packages
    RUN apt-get update --assume-yes && apt-get install --assume-yes build-essential
    
    # For a JS runtime
    # http://nodejs.org/
    RUN apt-get install --assume-yes nodejs
    
    # For Nokogiri gem
    # http://www.nokogiri.org/tutorials/installing_nokogiri.html#ubuntu___debian
    RUN apt-get install --assume-yes libxml2-dev libxslt1-dev
    
    # For RMagick gem
    # https://help.ubuntu.com/community/ImageMagick
    RUN apt-get install --assume-yes libmagickwand-dev
    
    # Clean up APT when done.
    RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    
    # === 2 ===
    
    # Set correct environment variables.
    ENV HOME /root
    
    # Use baseimage-docker's init process.
    CMD ["/sbin/my_init"]
    
    # === 3 ====
    
    # By default Nginx clears all environment variables (except TZ). Tell Nginx to
    # preserve these variables. See nginx-env.conf.
    COPY nginx-env.conf /etc/nginx/main.d/rails-env.conf
    
    # Nginx and Passenger are disabled by default. Enable them (start Nginx/Passenger).
    RUN rm -f /etc/service/nginx/down
    
    # Expose Nginx HTTP service
    EXPOSE 80
    
    # === 4 ===
    
    # Our application should be placed inside /home/app. The image has an app user
    # with UID 9999 and home directory /home/app. Our application is supposed to run
    # as this user. Even though Docker itself provides some isolation from the host
    # OS, running applications without root privileges is good security practice.
    RUN mkdir -p /home/app/myapp
    WORKDIR /home/app/myapp
    
    # Run Bundle in a cache efficient way. Before copying the whole app, copy just
    # the Gemfile and Gemfile.lock into the tmp directory and ran bundle install
    # from there. If neither file changed, both instructions are cached. Because
    # they are cached, subsequent commands—like the bundle install one—remain
    # eligible for using the cache. Why? How? See ...
    # http://ilikestuffblog.com/2014/01/06/how-to-skip-bundle-install-when-deploying-a-rails-app-to-docker/
    COPY Gemfile /home/app/myapp/
    COPY Gemfile.lock /home/app/myapp/
    RUN chown -R app:app /home/app/myapp
    RUN sudo -u app bundle install --deployment --without test development doc
    
    # === 5 ===
    
    # Adding our web app to the image ... only after bundling do we copy the rest of
    # the app into the image.
    COPY . /home/app/myapp
    RUN chown -R app:app /home/app/myapp
    
    # === 6 ===
    
    # Remove the default site. Add a virtual host entry to Nginx which describes
    # where our app is, and Passenger will take care of the rest. See nginx.conf.
    RUN rm /etc/nginx/sites-enabled/default
    COPY nginx.conf /etc/nginx/sites-enabled/myapp.conf
    

    Dockerrun.aws.json

    {
      "AWSEBDockerrunVersion": "1",
      "Ports": [
        {
          "ContainerPort": "80"
        }
      ],
      "Logging": "/home/app/myapp/log"
    }
    

    .dockerignore

    /.bundle
    /.DS_Store
    /.ebextensions
    /.elasticbeanstalk
    /.env
    /.git
    /.yardoc
    /log/*
    /tmp
    
    !/log/.keep
    

    nginx-env.conf

    请注意rails-env.conf 不会在 Nginx 之外设置任何环境变量,因此您将无法在 shell 中看到它们(即Dockerfile)。您还必须使用不同的方法来为 shell 设置环境变量。

    # By default Nginx clears all environment variables (except TZ) for its child
    # processes (Passenger being one of them). That's why any environment variables
    # we set with docker run -e, Docker linking and /etc/container_environment,
    # won't reach Nginx. To preserve these variables, place an Nginx config file
    # ending with *.conf in the directory /etc/nginx/main.d, in which we tell Nginx
    # to preserve these variables.
    
    # Set by Passenger Docker
    env RAILS_ENV;
    env RACK_ENV;
    env PASSENGER_APP_ENV;
    
    # Set by AWS Elastic Beanstalk (examples, change accordingly)
    env AWS_ACCESS_KEY_ID;
    env AWS_REGION;
    env AWS_SECRET_KEY;
    env DB_NAME;
    env DB_USERNAME;
    env DB_PASSWORD;
    env DB_HOSTNAME;
    env DB_PORT;
    env MAIL_USERNAME;
    env MAIL_PASSWORD;
    env MAIL_SMTP_HOST;
    env MAIL_PORT;
    env SECRET_KEY_BASE;
    

    nginx.conf

    server {
      listen 80;
      server_name _;
      root /home/app/myapp/public;
    
      # The following deploys your app on Passenger.
    
      # Not familiar with Passenger, and used (G)Unicorn/Thin/Puma/pure Node before?
      # Yes, this is all you need to deploy on Passenger! All the reverse proxying,
      # socket setup, process management, etc are all taken care automatically for
      # you! Learn more at https://www.phusionpassenger.com/.
      passenger_enabled on;
      passenger_user app;
    
      # Ensures that RAILS_ENV, RACK_ENV, PASSENGER_APP_ENV, etc are set to
      # "production" when your application is started.
      passenger_app_env production;
    
      # Since this is a Ruby app, specify a Ruby version:
      passenger_ruby /usr/bin/ruby2.2;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-23
      • 2015-10-12
      • 2016-12-26
      • 2016-07-18
      • 2014-03-31
      • 2014-12-13
      • 2013-06-25
      • 2012-09-24
      • 2015-07-06
      相关资源
      最近更新 更多