Docker and Rails in Production
Last week, I deployed a Rails app in a Docker container onto AWS Elastic Beanstalk. It was an unncessarily time consuming task due to small gaps in my knowledge and unfamiliarity with Docker and Elastic Beanstalk. This blog post is written during my first month working as a junior system administrator (“devops”) and this is a recap of my experience to the best of my memory.
Super helpful links: https://github.com/phusion/passenger-docker https://intercityup.com/blog/deploy-rails-app-including-database-configuration-env-vars-assets-using-docker.html https://intercityup.com/blog/how-i-build-a-docker-image-for-my-rails-app.html https://rossfairbanks.com/2015/03/06/rails-app-on-docker-using-passenger-image.html
Thanks to these blog posts (amongst many others), I was able to cut down a lot of time out of learning how to deploy this rails app.
First thing’s first. I installed docker-machine, which is the new boot2docker, and attempted to run my docker image containing the Rails app locally, in production, on my Macbook.
Here is the Dockerfile that I used:
MAINTAINER Brian Choy <bycEEE@gmail.com>
# Set correct environment variables.
ENV HOME /root
# Use baseimage-docker's init system.
# Start Nginx / Passenger
RUN rm -f /etc/service/nginx/down
# Remove the default site
RUN rm /etc/nginx/sites-enabled/default
# Add the nginx info
ADD nginx.conf /etc/nginx/sites-enabled/webapp.conf
# Add the rails-env configuration file
ADD rails-env.conf /etc/nginx/main.d/rails-env.conf
# Run Bundle in a cache efficient way
ADD Gemfile /tmp/
ADD Gemfile.lock /tmp/
# Add the rails app
ADD . /home/app
RUN chown -R app:app /home/app
# Run bundle and expose port 80
RUN sudo -u app bundle install --deployment --without test development doc
RUN sudo -u app RAILS_ENV=production rake assets:precompile
# Clean up
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
The reason why I used passenger-docker is included on their GitHub. Basically they’re maintaining a Ubuntu 14.04 base image that is tweaked and configured properly for Docker.
These Rails environment variables are now accessible to me and can be changed via my AWS console. My database also resides in AWS RDS so I did not set up a local MySQL database to connect to.
Running my app:
docker run --rm -p 80:80 myappname
Shell access to my container to poke around for errors:
sudo docker exec -i -t 665b4a1e17b6 bash
Afterwards just go to your AWS account, spin up another instance of Elastic Beanstalk, add in all your environment variables, and make sure RAILS_ENV is set to production in your environment variables.
I’m sure there were way more pain points in this process not mentioned in this blog post and I probably blocked them out of my memory. So far I can relax and be satisfied that this works, but eventually I’ll have to do this again. Will update this blog post or make another one in the future with more info.