Monday, February 22, 2010

Nginx is to Apache as JSON is to XML

As part of getting up and running on FsckVPS I decided to go with Nginx rather than Apache because it's so hot right now (like Hansel) and I figured it's something I should learn.

Well, after setting up Nginx with Passenger, Ruby / Rack / Rails, and Python / WSGI / TurboGears I have to say that there is no reason in my mind to go back to apache.

Nginx is simpler than Apache in the same way that JSON is simpler than XML.


Passenger installs Nginx for you!
Virtual Hosts with Nginx
Nginx as a Reverse Proxy for a Thin cluster
Nginx and Passenger way easier than mod_wsgi
Nginx articles on Slicehost


This is much less complicated than it sounds:

  1. Installed Ubuntu 9.04
  2. Installed latest stable ruby (which includes rubygems) from source
  3. Installed passenger gem
  4. Installed nginx from source with passenger
  5. Configured nginx (including init.d)
  6. What!? Entirely amazed that I got it right on the first try!

Getting Started with FsckVPS

FsckVPS is an DIY (unmanaged) hosting service.

I chose them for several reasons:

  • Although the old Dell I have under my bed has more guaranteed CPU and RAM, the internet connection at my apartment isn't reliable enough to be hosting sites for clients.
  • They're cheap $10/month for 384/768(burst) RAM
  • Someone on my local ruby list recommended them
  • They give me what I need (a box with connection to the www)
  • They don't give me what I don't (restrictions, hassle)

The sign-up process is a little confusing as they use several software packages.
This is what you can expect to go through:
  1. E-mail sales to get a discount code if you are
    • a student
    • going to release some or all of your software open source
  2. Choose OpenVPN or Xen
    • choose a location (subject to availability)
    • get a discount by paying at least 3 months up front
    • claim your discount code from sales
    • make your payment via credit card / paypal
  3. You will get e-mails with the following information
    • VAServe Account - this is created right away
    • VPS CP Account - this is created during business hours
    • eSupport Account - when you sign up for it
  4. Your VM gets set up during working business hours
    • Wait a few hours to get the e-mail in which you'll find your ip address
    • You may need to wait until the next business day
  5. Once you have your VPS CP account
    • Change your OS as you wish, wait 30 minutes
    • Put in a ticket through eSupport to notifying that you've changed your OS
    • Alternatively, if you're using Ubuntu or Debian this may work for you:
      #/etc/network/interfaces
      auto lo
      iface lo inet loopback


      auto venet0
      iface venet0 inet static
        address 127.0.0.1
        netmask 255.255.255.255
        broadcast 0.0.0.0
        up route add -net 192.0.2.1 netmask 255.255.255.255 dev venet0
        up route add default gw 192.0.2.1


      auto venet0:0
      iface venet0:0 inet static
        address X.X.X.X
        netmask 255.255.255.255
        broadcast 0.0.0.0 

  6. Setup DNS
    • Buy a domain from Google
    • Change your @ and www addresses to the VPS VM's IP address
    • I don't know about setting up DNS on FsckVPS. I know you can do it, but I don't know how yet


And at this point you should be all set to go.


Fsck Anatomy





P.S. To get my Ubu-box up to a more useable status I do this:

apt-get update && apt-get -y upgrade
# EDIT don't use ufw, it's not compatible with OpenVZ
# EDIT 2 I submitted a ticket and they changed the settings such that ufw's firewall rules work
apt-get install ufw
ufw allow ssh/tcp
ufw allow http/tcp
ufw allow https/tcp
/etc/init.d/ufw restart
ufw enable

#iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#iptables -A INPUT -p tcp --dport ssh -j ACCEPT
#iptables -A INPUT -p tcp --dport www -j ACCEPT
#iptables -A INPUT -p tcp --dport https -j ACCEPT



#create an admin user
adduser my_user_name
usermod -a -G sudo my_user_name
visudo # uncomment %sudo ...

# test ssh and disable root ssh
ssh my_user_name@ip-addr
# Don't do this, in case you need serial console login
# sudo passwd root -l
sudo vim /etc/ssh/sshd_config
#set PermitRootLogin No

Friday, February 19, 2010

Rails PaperClip

Don't I feel stupid.
I just posted to the mailing list about a question that was in the getting started! AH!


I was rushing through and everything I was seeing was about image manipulation so I wasn't paying attention and the very last code snippet was the one I needed.

I should have watched the Railcast first. It was exactly what I needed in the way I needed it.

@user.avatar.url

Assuming that the model is user, the has_file_attachment is avatar then that is how you get the URL.

has_attached_file :data,
    :path => ":rails_root/public/system/:attachment/:id/:basename.:extension",
    :url => "/system/:attachment/:id/:basename.:extension"

It seems to be important that the URL is the public version of the path. This may be due to that I'm using the same name for my attachment as the model itself.


And here's some linkage:
Railscast: PaperClip
For attaching files, use Paperclip
Paperclip Tips and Updates
Active Scaffold with Paperclip
Multiple Attachments with Validations In Rails with Paperclip

If you read each of those with relative care it should answer all questions you might have.

Current (Feb 2010) Documentation as opposed to outdated documentation found elsewhere.

undefined method `table_name' for Paperclip::Attachment:Class

Every example that I've seen for paperclip shows it being used with images, not with arbitrary files. Well, it works just fine with arbitrary files -- as long as the name of the model which houses your files is not "Attachment". That name somehow collides with "Paperclip:Attachment".

Something like "Medium" or "MyAttachment"will work fine. I'd be interested to know if "File" works, but I didn't try it for myself.

Monday, February 15, 2010

Facebook's Application Tabs (Pre-"Early 2010")

Lies! All lies!

I'm working with Facebook for a client and I'm having to learn quite a bit to get not-as-much done.

You see, Facebook just changed (yet again) last week and so few to none of the tutorials online have updated nominature nor screenshots.



To say that the Facebook documentation lacks clarity and consistency is an understatement. Ugh!



Today's lesson: Creating a Canvas and a Tab


First we venture here:
http://apps.facebook.com/developer
Only to be redirected here:
http://www.facebook.com/developers/
Which is just fine, btw.


Canvas
Canvas Page URL: ex_ample_app
http://apps.facebook.com/ex_ample_app
Where facebook users will go to use your application within facebook.
Do not supply a facebook connect page here.

Canvas Page Callback: http://www.example-app.com/canvas?
Your server will receive a GET request like http://www.example-app.com/canvas?fb_sig_PARAMS=...
You can use FBML here, but the trend is to use iFrames.

My personal prediction is that they will try to move apps entirely to the sites they belong to in favor of FB Connect and then have Tabs replace what used to be apps as to better establish a better, more consistent user experience on FB.


Profile
Tab Name: Example App

Tab URL: tab
http://apps.facebook.com/ex_ample_app/tab
(This is where I got so frustrated.)
It's not "relative" to your canvas url, it's a parameter appended to your canvas url.
http://www.example-app.com/canvas?tab
 
Also, you would expect that it would GET the tab url, but it actually POSTs to it!
I believe that the reason it POSTs is that it has a HUGE list of params - which may often exceed the character limit of a normal GET.



Why isn't this in the documentation? I have no idea. Because they're crazy and they already have a PHP library that is saavy to their crazy caveats?