3
votes

I'm trying to migrate my Rails app from Heroku to AWS. I got my AWS CodePipeline working up until the last bit, writing the appspec.yml for CodeDeploy.

This requires me to write Ubuntu commands to stop my application, possibly do some migration stuff, and then start the application again.

This is not my strong suit so I am struggling a bit with this part. I thought I'd start with executing "rails server" as "AfterInstall" action. But then I openend up a whole box of new problems, i.e. there is no Rails and Bundler installed on the EC2 instance etc.. While I was trying to just solve one mini problem at a time I wondered whether I should actually be writing this file from scratch.

So here's my question: isn't this somewhat identical for all Rails apps that are deployed with CodeDeploy? Shouldn't that be available already, hopefully done by someone with a lot more clue than me about what exactly he or she is doing? I didn't find much through Google, so I'm hoping somebody could shed some light onto this for me. I'm afraid even if I get it working it won't be a good and robust and production-ready appspec.yml in the end anyways...

Thanks a lot already!

2

2 Answers

5
votes

It sounds like you are trying to run rails server directly on the EC2 instance, I would probably use NGINX with Passenger because then restarting your Rails app after deploy would be as simple as running an after install script to touch tmp/restart.txt which would cause Passenger to restart the app.

I searched around a bit and found the following post where they are using NGINX and Passenger as well, it looks very much like the kind of approach that I would take and I can see that they include before and after install scripts as well.

http://sfviapgh.com/blog/2016/2/18/how-to-deploy-rails-with-aws-codedeploy

Just in case the post is later unavailable here is the key points:

  1. Setup an EC2 instance with everything that you need for your production server. In our case, this was Ruby, Passenger, and nginx. You do not want to clone your app via git to the server ahead of time but you will need to know the path of where you want your app to live on the server (for example www/var/...). Make sure you know which users you will use for each process (cloning the code, restarting the processes).
  2. Install the AWS CodeDeploy agent on to the server.
  3. Move the EC2 instance to a Production App Group AMI.
  4. In our codebase, we added the following bash scripts to our /script folder. Our full scripts are a bit more complicated (cloning our env vars from a secure s3 bucket) but these will get you off to a solid start. CodeDeploy currently hooks into GitHub only. Luckily, GitHub is what we are using to manage our codebases.
  5. Setup a required AWS CodeDeploy appspec.yml at the root of your app that references these scripts (see below).

application/appspec.yml

version: 0.0
os: linux
files:
  - source: /
    destination: <the directory your code will live>
permissions:
  - object: <the directory your code will live>
    owner: <user who will deploy your code>
    group: <group that user lives in>
  AfterInstall:
    - location: script/AfterInstall.sh
      runas: <user who will deploy your code>
  ApplicationStart:
    - location: script/ApplicationStart.sh
      runas: <root user>

application/script/AfterInstall.sh

#!/bin/bash
cd /var/www/<app location>
RAILS_ENV=production bundle install --path vendor/bundle
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake assets:clobber
RAILS_ENV=production bundle exec rake assets:precompile

application/script/ApplicationStart.sh

#!/bin/sh
sudo service nginx restart

I hope that helps you a bit further with the deployment.

0
votes

Travis tutorial. This gives you a step-by-step approach to setting things up. Hope it helps.