2015-07-20 18 views
4

我一直试图在Elastic Beanstalk上对我的Rails应用程序进行dockerize。这里有很多例子,但大多数不适合我的具体用例。即:如何在单个容器上的Amazon Elastic Beanstalk上部署Rails应用程序Docker环境

  • 单个容器泊坞环境(所以不需要搬运工人-撰写/图)在Amazon Elastic魔豆
  • 运行下运行。
  • 利用passenger-docker作为基础图像(Ruby变体之一)。
  • 传递由Elastic Beanstalk设置的环境变量(通过控制台的CLI)。
  • Nginx和Passenger在容器中。
  • 能够安装自定义软件包(扩展它)。
  • 合理的.dockerignore文件。

有关如何部署的过程并不是问题,而是正确的Docker配置,它可以与Amazon Elastic Beanstalk一起使用以上特定条件。

什么是正确的配置,让这个运行?

回答

4

这是对我工作......

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" <[email protected]> (@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.con不会在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; 
} 
相关问题