Using CloudFront with S3 and Paperclip

I wanted to cache my S3 images for my Rails app, so I changed my app to serve images using AWS CloudFront, a CDN.

Doing this was pretty simple.

(1) Set-up a AWS CloudFront instance and your S3 bucket as your origin

(2) Change your Paperclip settings to use the new CloudFront instance.  I did this in production.rb (make sure neither the url or s3_host_alias values are being written by Paperclip settings in your model):

config.paperclip_defaults = {
storage: :s3,
:url => “:s3_alias_url”,
:s3_host_alias => “”,
:path => “:rails_env/:class/:attachment/:id/:style/:filename”,
:bucket => “your-bucket-name”,
s3_credentials: {
bucket: ENV[‘AWS_S3_BUCKET’],
access_key_id: ENV[‘AWS_ACCESS_KEY_ID’],
secret_access_key: ENV[‘AWS_SECRET_ACCESS_KEY’],

and that’s it!

Now, if you check the URL of your images, it should see that their source is prefaced with your CloudFront URL.

Using Route 53 to Map your Domains

Route 53 is an Amazon Web Service (AWS) tool for routing domain names to your AWS servers.

It’s very easy to do:

(1) log in to your Amazon Web Services account and go to the AWS Management Console

(2) go to Services > Route 53

(3) in Route 53, click the “Create Hosted Zone” button

(4) once your zone has created, you should have four “Delegation Sets”.  The Delegation Sets are the addresses that you will need to point your domain name servers to.  You do this typically by logging into your account with the company that you registered your domain with (ie Yahoo or Go Daddy), and then for this domain finding the section to edit or change your name servers.

(5) after you have updated your name servers with the domain registering company, go back to the AWS Management Console.  In the console, go to Services > EC2.

(6) If you haven’t already, you will probably want to either create a static IP or elastic load balancing, and have whichever you create point to your EC2 instance

(7) if you are using an elastic IP, it will have an IP associated with it.  Copy that and go back to your hosted zone in Route 53

(8) For your hosted zone, click “Go to Record Sets”

(9) Next, click “Create Record Sets”

(10) select:

    • IPv4 for the type
    • if you are using elastic load balancing:
      • click “yes” for alias
      • select your load balancer from the menu that appears
    • if you are using elastic IP
      • leave “no” for alias
      • enter your IP in the “value” box
    • save

(11) Most likely, you’ll want to do this at least twice – once for your domain with “www” and one without – that way people can reach your app if they type www and if they don’t.

Your domain name change will take awhile to propagate, but once it does, your domain will be pointing to your AWS server(s) now.

Setting Up SSL on AWS Bitnami Instance of Ruby on Rails (Apache)

Setting up SSL on the Bitnami instance of Ruby on Rails is easy.

  1. First, you’ll want to make sure that you’ve purchased your SSL certificates for your domain
  2. Next, log in to your EC2 instance
  3. place the .key and .crt files you have for your SSL certificate in your apps’s root directory
  4. go to your app’s root and move the files to the correct directory with

mv yourcrt.crt /opt/bitnami/apache2/conf/extra/yourcrt.crt

mv yourkey.key /opt/bitnami/apache2/conf/extra/yourkey.key

       5.  the httpd.conf file that the instance comes with already points to another file for the ssl configuration, so we’ll want to edit that file that is being used.

6.  enter “cd  /opt/bitnami/apache2/conf/extra”

7.  enter “pico httpd-ssl.conf” to edit the ssl configuration

8.  in the file (CNTL + X to save when you are done):

    • change the “DocumentRoot” to “home/bitnami/apps/yourapp/public” or where ever your app is
    • change the “ServerName” to
    • change the “ServerAdmin” to your email
    • change the “SSLCertificateFile” to “/opt/bitnami/apache2/conf/extra/yourcrt.crt”
    • change the “SSLCertificateKeyFile” to “/opt/bitnami/apache2/conf/extra/yourkey.key”

9.  stop and restart your server

apachectl -k stop

apachectl -k graceful

Your app should now be successfully set-up for SSL.

Running Ruby on Rails on EC2 with Bitnami

Bitnami makes it easy to get started with Rails with their Amazon Machine Image (AMI) which creates a server for your app with all of the software you need already installed.  For my apps, I’m using Apache and Passenger, but Nginx is also installed if you prefer that.

Here are some instructions for setting up Rails using Apache / Passenger / MySQL

(1) sign-up for your Amazon Web Services account

(2) log in, and go to your AWS Management console

(3) go to the EC2 section

(4) click on the security groups link

(5) change the default security group to allow inbound requests:

http, https and ssh access from ip

(this allows people to access your app over http or https and allows you shell access to the server)

(6) click on the key pairs link and create a key pair (you’ll need this to access your EC2 instance)

(7) click the instances link

(8) click the ‘launch instance’ button and then select to create an instance from the Amazon Marketplace.  In the search box, enter Ruby on Rails

(9) select the Bitnami Ruby on Rails image and then follow the steps to create the instance

(10) while your instance is getting created, you’ll want to create your MySQL database.  In the Console, off the top menu, click “Services” and then RDS (under databases)

(11) click the “launch a DB instance” button in RDS, click MySQL on the next screen

(12) on the next screen, select a class (based on how powerful the server you want running your DB), enter the other required fields and record or remember what you entered here as you’ll need them to access your database

(13) Click on the “DB Security Groups” link.  Click on the default group, and down below you should be able to alter the permissions.  If you want to be able to access your database from your PC, add one for CIDR/IP and then copy the CIDR detected (it will show as AWS’s best guess in small font once your select CIDR).  You will need to add one for “EC2 Security Group” and select the “Default” EC2 security group.  This does not mean that you are adopting the settings of the  EC2 security group – it means that you are allowing members of that group to access the DB – this way your EC2 server with the application can access the database.

(14) Next you’ll have to update your database.yml file to make sure it connects to your RDS.  Once your instance has finished creating (green light next to the instance), click on the DB Instances tab on the left, and then on the next screen click on your instance.  This should bring up the properties of the instance in the lower frame of the web page.  Note the “endpoint” as this is the host you will use in your database.yml.

In your database.yml, for production enter this:

adapter: mysql2
encoding: utf8
database: (your database name from step 12)
username: (your database user name from step 12)
password: (your database password from step 12)
host: (your endpoint)
port: 3306

(15)next you’ll want to log in to your EC2 instance, which should have been created by now to finish setting that up.  to log in, you can use the Putty program or you can use the Java shell client that AWS provides.  To use the the client AWS provides, go to Services > EC2 in the AWS management console.  Click on the Instances tab, and then right click your running instance and select “connect”.

(16) In the Java pop-up, change the user name from ubuntu to bitnami, and change the private key path to the path that the .pem file you downloaded to (in step 6), and then click “Launch SSH instance”.  If you are prompted to add the remote host, click ‘yes’.

(17) once you’re in, you can create a directory for your app, i put mine in /home/bitnami/apps/myappname

cd /home/bitnami/apps

sudo mkdir myappname

(18)  you can follow these steps to set-up git on your EC2 instance.  For my EC2 instance, I put my repo in: /home/bitnami/repo  (so you may want to change the directories in the set-up git link)

(19) we want to make sure your permissions are correct, otherwise your app will get 403 errors (Permission Denied) when accessing pages of your app.  Go to the directory above the one where you put your app.  For example, I used /home/bitnami/apps/myappname, so I would go to the /home/bitnami/apps folder:

cd /home/bitnami/apps

sudo chown -R bitnami:bitnami myappname

chmod -R 775 myappname

chmod -R 755 myappname

(20) after you’ve pushed your code, it should be in the directory you set-up for your app (in my example, /home/bitnami/apps/myappname).  run these three commands:

cd /home/bitnami/apps/myappname

bundle install

rake db:create

(21) with apache and passenger already installed, your app is ready to run.  the one last thing you have to do is to point Apache to your app.  to do that, go into your shell client and enter this command:

cd /opt/bitnami/apach2/conf

pico httpd.conf

(22) you should now be editing the httpd.conf file which is apache’s configuration for routing.  find this line and delete it:

DocumentRoot “/opt/bitnami/apache2/htdocs”

(23) paste (shift + insert key) in this (replace “myappname” with your app’s name):

<VirtualHost *:80>
DocumentRoot /home/bitnami/apps/myappname/public
<Directory /home/bitnami/apps/myappname/public>
Allow from all
Options -MultiViews

(24) exit and save (CNTL + x, then click enter when it asks you if you want to save)

(25) run these commands to stop and restart your server so the changes take effect:

sudo apachectl -k stop

sudo apachectl -k graceful

(26) go to the public IP for your EC2 instance (you can find this if you go into the AWS Management Console, then go to the EC2 section – Services > EC2 – and click on your running instance to see the attributes – it’s “Public DNS”)

You’re app should now be available on the web at this address.

Getting EC2 to Use Git for Rails App

I wanted to use git to push my code.  Since I used an Amazon Machine Image (AMI) that installed Ruby on Rails that also included git, git was already installed on my Linux server, and I just needed to make it work.

(1) go into Services > EC2 and make sure that you have a key pair attached to your instance.  If not click the key pairs link on the left side, create a key pair and make a new instance that using this, so you have SSH access to your server.

(2) log into your instance using SSH

(3) go to the home directory, enter:

cd /home

(4) create a new directory in home (this is not where your Rails app will go):

mkdir repo

(5) go into repo:

cd repo

(6) initiate git for repo:

git init –bare

(7) create the directory where your Rails app will go.  Mine went into /var/www/app, so:

cd /var/www

mkdir app

(7) next go to the repo/hooks directory:

cd /home/repo/hooks

(8) hooks are scripts that run at given points in the git process.  we need to edit the receive-post file – this is triggered each time a new git push is made.  enter this:

cat > post-receive

(9) after hitting enter, type this:


GIT_WORK_TREE=/var/www/app (or wherever you want to put you Rails app)


git checkout -f

(10) after saving that you should be able to see your changes:

pico post-receive

(11) once you’ve confirmed that, run:

chmod +x hooks/post-receive

(12) next, when you do git pushes, you may have a personal ssh that is used, it’s an “” file.  for me, on windows, it was located in C:/Users/Me/.ssh

(13) copy the contents of that file (open it with notepad)

(14) go back to your SSH session and go to the ssh directory:

cd ~/.ssh

(15) In that directory, there is an authorized_keys file that contains a key that must match yours to do the git.  You can use the pico command to edit the file.  If you’ve never edited in pico, here are commands.

pico authorized_keys

(16) remove anything that is in there, paste your SSH details from step 8, then save the file

(17) go to git bash and add this new remote (if you have trouble with using your public ip, assign an elastic ip to your instance in the aws management console, in services > ec2):

git remote add origin ssh://[ec2 instance user name]@[public ip for your ec2]/home/repo

(18) in git bash:

git push origin