reverse proxying with an Apache dyno

2012-06-25 Thread Brandon Rhodes
Hosting providers like WebFaction make it easy to assemble full web
sites out of smaller pieces.  They provide a control panel that lets you
add entries to WebFaction's nginx configuration so you can (for example)
serve /static URLs using Apache, serve /blog from a WordPress
instance, and send everything else to your dynamic web application.

When I saw Kenneth Reitz's blog post Static Sites on Heroku Cedar, I
wondered whether a similar arrangement might be possible on Heroku:

http://kennethreitz.com/static-sites-on-heroku-cedar.html

With a bit of work, I have found that such an arrangement is indeed
possible.

But I wanted to ask here on the mailing list whether this approach is in
the spirit of the service that Heroku is trying to provide - and whether
the performance I am seeing is reasonable or not.

Building Apache with mod_proxy
--

The default Heroku buildpack that Kenneth uses in the above blog post
does not include mod_proxy, but only mod_rewrite.  So the first step was
to create a slightly modified fork of the default Heroku PHP buildpack:

https://github.com/brandon-rhodes/heroku-buildpack-php

Instead of using the Apache and PHP tarballs that Heroku provides under
the php-lp S3 bucket, I had to build an alternative pair of tarballs
and make them available under my own S3 bucket.  You can see the
procedure for building the tarballs in README.md my fork of the
repository.

I ran the README.md steps on a Heroku Cedar instance to make sure that
they would be binary-compatible with the Heroku dyno standbox:

$ heroku run bash
Running `bash` attached to terminal... up, run.2
~ $ cd /app
~ $ curl -O http://apache.cyberuse.com/httpd/httpd-2.2.22.tar.gz
...
and so forth

(I actually skipped the pear section of the README, because apt-get
did not seem to be available in the sandbox.  Hope it was not important.)

This produces two *.tar.gz files that are in great danger of
disappearing, because as soon as you exit bash the temporary instance
produced by heroku run will be destroyed along with its filesystem.
So I used nc to copy the tarballs off to another server before exiting
bash, then put the tarballs on S3 like Heroku does (using s3cmd), and,
finally, updated the URLs in heroku-buildpack-php/bin/compile to point
at the new location.

Building a proxy with this custom buildpack
---

Kenneth used an .htaccess file to turn off the PHP engine.  With this
buildpack we can now go farther, and add rewrites that back-end certain
URLs with content from another web server on the Internet - in my case,
another Heroku app.  For example, to serve /static/* URLs from local
files in your Apache front-end, but forward other URLs back to another
Heroku app, you can do something like this:

 # .htaccess
 php_flag engine off
 RewriteEngine on
 RewriteRule !^static/ http://morning-snow-4827.herokuapp.com%{REQUEST_URI} [P]

Of course, be sure to create the same empty index.php file that
Kenneth recommends, so that your tiny app is recognized correctly as a
(not-really) PHP application.

So my small front-end app looks like this:

/.htaccess(content shown above)
/index.php(empty)
/static/index.html(says htmlbodypThis is static content)

I can deploy this as an Apache-powered front-end reverse proxy like
this:

$ heroku create --stack cedar --buildpack 
http://github.com/brandon-rhodes/heroku-buildpack-php.git
$ git push heroku master

You can, for the next few days, see the result by visiting the following
pair of URLs, the first of which serves the static content, and the
second of which (since it does not match /static) proxies content
through to a small botanical web application:

http://falling-autumn-5266.herokuapp.com/static/
http://falling-autumn-5266.herokuapp.com/Families/

Performance and impact
--

Some simple tests with ab suggest that proxying through a
Dyno-resident Apache instance like this adds right around 100ms to every
request to the back-end.  As usual, the shape of each particular
application will determine whether the cheaper static resources make up
for the extra expense incurred for dynamic resources:

BEFORE

All content served by dynamic app: ~410ms

AFTER

Static content served right from Apache: ~83ms
Dynamic content proxied through Apache: ~517ms

So here are the questions on which I would like feedback:

* Is this approach good or evil?

* In particular, is it un-neighborly and unfriendly that each dynamic
  request through this stack keeps two Heroku dynos busy instead of just
  one (or, on the contrary, will Heroku love being able to sell me more
  Dynos as my user base expands)?

* Is 100ms of additional delay for dynamic queries reasonable?  Or does
  it reflect that I have done something non-optimal in setting this up?
  Or does it simply indicate that a Heroku dyno does not 

Re: reverse proxying with an Apache dyno

2012-06-25 Thread Richard Schneeman
There was a thread awhile ago about using a rack based reverse proxy gem. Maybe 
someone who has tried that could give you their experience. As you mentioned 
this setup seems like it took quite a bit of work. Many frameworks like Rails 
have the ability to mount applications within your application. So you can have 
for example several sinatra apps actually running within your app. Or depending 
on how you wanted to split things up you can just have different apps serving 
different subdomains, which is actually what Heroku does. blog.heroku.com,  
addons.heroku.com, etc. they are all separate (mostly ruby) apps. We link them 
together with shared style sheets and a gem that can provide a consistent 
header and footer.  

I know there are some minor issues with embedding apache into a dyno, but i've 
not had enough experience with it first hand to tell you what they are, just be 
on the look out for any unexpected behavior. 

In general we advocate one codebase per each application 
http://www.12factor.net/codebase. If each section of your app can stand on its 
own, splitting out your app can make sense. For instance it would be reasonable 
for Heroku to have a blog without needing addons or vice versa. But it doesn't 
make much sense if data is regularly passed between different apps using your 
apache routing layer. This makes your app much more coupled, harder to debug 
and potentially failure prone. Note that this is different from Service 
Oriented Architecture, which is completely acceptable since each piece should 
be able to be run independently, and with layers of error handling put into 
place.

For serving static content, we recommend bypassing your stack altogether and 
using a CDN such as cloud front. Not only is this going to be much faster, it 
will take load off of your server so it can handle more requests. 

-- 
Richard Schneeman
http://heroku.com

@schneems (http://twitter.com/schneems)




On Monday, June 25, 2012 at 7:00 PM, Brandon Rhodes wrote:

 Hosting providers like WebFaction make it easy to assemble full web
 sites out of smaller pieces. They provide a control panel that lets you
 add entries to WebFaction's nginx configuration so you can (for example)
 serve /static URLs using Apache, serve /blog from a WordPress
 instance, and send everything else to your dynamic web application.
 
 When I saw Kenneth Reitz's blog post Static Sites on Heroku Cedar, I
 wondered whether a similar arrangement might be possible on Heroku:
 
 http://kennethreitz.com/static-sites-on-heroku-cedar.html
 
 With a bit of work, I have found that such an arrangement is indeed
 possible.
 
 But I wanted to ask here on the mailing list whether this approach is in
 the spirit of the service that Heroku is trying to provide - and whether
 the performance I am seeing is reasonable or not.
 
 Building Apache with mod_proxy
 --
 
 The default Heroku buildpack that Kenneth uses in the above blog post
 does not include mod_proxy, but only mod_rewrite. So the first step was
 to create a slightly modified fork of the default Heroku PHP buildpack:
 
 https://github.com/brandon-rhodes/heroku-buildpack-php
 
 Instead of using the Apache and PHP tarballs that Heroku provides under
 the php-lp S3 bucket, I had to build an alternative pair of tarballs
 and make them available under my own S3 bucket. You can see the
 procedure for building the tarballs in README.md (http://README.md) my fork 
 of the
 repository.
 
 I ran the README.md (http://README.md) steps on a Heroku Cedar instance to 
 make sure that
 they would be binary-compatible with the Heroku dyno standbox:
 
 $ heroku run bash
 Running `bash` attached to terminal... up, run.2
 ~ $ cd /app
 ~ $ curl -O http://apache.cyberuse.com/httpd/httpd-2.2.22.tar.gz
 ...
 and so forth
 
 (I actually skipped the pear section of the README, because apt-get
 did not seem to be available in the sandbox. Hope it was not important.)
 
 This produces two *.tar.gz files that are in great danger of
 disappearing, because as soon as you exit bash the temporary instance
 produced by heroku run will be destroyed along with its filesystem.
 So I used nc to copy the tarballs off to another server before exiting
 bash, then put the tarballs on S3 like Heroku does (using s3cmd), and,
 finally, updated the URLs in heroku-buildpack-php/bin/compile to point
 at the new location.
 
 Building a proxy with this custom buildpack
 ---
 
 Kenneth used an .htaccess file to turn off the PHP engine. With this
 buildpack we can now go farther, and add rewrites that back-end certain
 URLs with content from another web server on the Internet - in my case,
 another Heroku app. For example, to serve /static/* URLs from local
 files in your Apache front-end, but forward other URLs back to another
 Heroku app, you can do something like this:
 
 # .htaccess
 php_flag engine off
 RewriteEngine on
 RewriteRule !^static/ 

Reverse Proxying

2012-06-20 Thread Jeff Schmitz
I'd like to set up a reverse proxy, so that requests to
myherokuapp.com/blogare served by
blog.myherokuapp.com without the user being any the wiser.

However, I haven't seen any way to do this in Heroku.

Has anybody

1) been able to do configure this, or
2) been able to reverse proxy within their Rails app via gem/plugin, or
3) deployed a blog gem/plugin *within* their Rails app that they love

Tired of losing SEO juice, searching for answers...

Thanks

jeff

-- 
You received this message because you are subscribed to the Google
Groups Heroku group.

To unsubscribe from this group, send email to
heroku+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/heroku?hl=en_US?hl=en


Re: Reverse Proxying

2012-06-20 Thread Neil Middleton
Is there a valid reason for wanting to avoid serving directly from 
blog.yourapp.com (i.e are 301's sufficient?)

On Wednesday, 20 June 2012 at 16:27, Jeff Schmitz wrote:

 I'd like to set up a reverse proxy, so that requests to myherokuapp.com/blog 
 (http://myherokuapp.com/blog) are served by blog.myherokuapp.com 
 (http://blog.myherokuapp.com) without the user being any the wiser.
 
 However, I haven't seen any way to do this in Heroku.
 
 Has anybody
 
 1) been able to do configure this, or
 2) been able to reverse proxy within their Rails app via gem/plugin, or 
 3) deployed a blog gem/plugin within their Rails app that they love
 
 Tired of losing SEO juice, searching for answers...
 
 Thanks
 
 jeff 
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Heroku group.
  
 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com 
 (mailto:heroku+unsubscr...@googlegroups.com)
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Heroku group.

To unsubscribe from this group, send email to
heroku+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/heroku?hl=en_US?hl=en


Re: Reverse Proxying

2012-06-20 Thread Jeff Schmitz
Because search engines don't consider blog.youapp.com as part of yourapp.com
.

So you get the small benefit of additional inbound links, and a large minus
from relevant content not being on my site.

On Wed, Jun 20, 2012 at 10:29 AM, Neil Middleton
neil.middle...@gmail.comwrote:

 Is there a valid reason for wanting to avoid serving directly from
 blog.yourapp.com (i.e are 301's sufficient?)

 On Wednesday, 20 June 2012 at 16:27, Jeff Schmitz wrote:

 I'd like to set up a reverse proxy, so that requests to
 myherokuapp.com/blog are served by blog.myherokuapp.com without the user
 being any the wiser.

 However, I haven't seen any way to do this in Heroku.

 Has anybody

 1) been able to do configure this, or
 2) been able to reverse proxy within their Rails app via gem/plugin, or
 3) deployed a blog gem/plugin *within* their Rails app that they love

 Tired of losing SEO juice, searching for answers...

 Thanks

 jeff

 --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


  --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


-- 
You received this message because you are subscribed to the Google
Groups Heroku group.

To unsubscribe from this group, send email to
heroku+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/heroku?hl=en_US?hl=en


Re: Reverse Proxying

2012-06-20 Thread Richard Schneeman
For Reverse proxy in Rails app,  I haven't used one but this looks promising: 

https://github.com/jaswope/rack-reverse-proxy 

You could do it _in_ the rails app, but it will be much more performant if you 
do it through a rack middleware. 


-- 
Richard Schneeman
http://heroku.com

@schneems (http://twitter.com/schneems)




On Wednesday, June 20, 2012 at 11:04 AM, Jeff Schmitz wrote:

 Because search engines don't consider blog.youapp.com 
 (http://blog.youapp.com) as part of yourapp.com (http://yourapp.com).
 
 So you get the small benefit of additional inbound links, and a large minus 
 from relevant content not being on my site.  
 
 On Wed, Jun 20, 2012 at 10:29 AM, Neil Middleton neil.middle...@gmail.com 
 (mailto:neil.middle...@gmail.com) wrote:
  Is there a valid reason for wanting to avoid serving directly from 
  blog.yourapp.com (http://blog.yourapp.com) (i.e are 301's sufficient?)
  
  On Wednesday, 20 June 2012 at 16:27, Jeff Schmitz wrote:
  
  
  
   I'd like to set up a reverse proxy, so that requests to 
   myherokuapp.com/blog (http://myherokuapp.com/blog) are served by 
   blog.myherokuapp.com (http://blog.myherokuapp.com) without the user being 
   any the wiser.
   
   However, I haven't seen any way to do this in Heroku.
   
   Has anybody
   
   1) been able to do configure this, or
   2) been able to reverse proxy within their Rails app via gem/plugin, or 
   3) deployed a blog gem/plugin within their Rails app that they love
   
   Tired of losing SEO juice, searching for answers...
   
   Thanks
   
   jeff 
   
   
   
   -- 
   You received this message because you are subscribed to the Google
   Groups Heroku group.

   To unsubscribe from this group, send email to
   heroku+unsubscr...@googlegroups.com 
   (mailto:heroku+unsubscr...@googlegroups.com)
   For more options, visit this group at
   http://groups.google.com/group/heroku?hl=en_US?hl=en
  
  -- 
  You received this message because you are subscribed to the Google
  Groups Heroku group.
   
  To unsubscribe from this group, send email to
  heroku+unsubscr...@googlegroups.com 
  (mailto:heroku%2bunsubscr...@googlegroups.com)
  For more options, visit this group at
  http://groups.google.com/group/heroku?hl=en_US?hl=en
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Heroku group.
  
 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com 
 (mailto:heroku+unsubscr...@googlegroups.com)
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Heroku group.

To unsubscribe from this group, send email to
heroku+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/heroku?hl=en_US?hl=en


Re: Reverse Proxying

2012-06-20 Thread Jeff Schmitz
Thanks, Richard, I misspoke about that.

Exactly, I mean in my code, not in heroku's code.

Anybody use this gem on heroku?  Your Impressions?

TIA

jeff

On Wed, Jun 20, 2012 at 11:27 AM, Richard Schneeman 
richard.schnee...@gmail.com wrote:

 For Reverse proxy in Rails app,  I haven't used one but this looks
 promising:

 https://github.com/jaswope/rack-reverse-proxy

 You could do it _in_ the rails app, but it will be much more performant if
 you do it through a rack middleware.


 --
 Richard Schneeman
 http://heroku.com
 @schneems http://twitter.com/schneems

 On Wednesday, June 20, 2012 at 11:04 AM, Jeff Schmitz wrote:

 Because search engines don't consider blog.youapp.com as part of
 yourapp.com.

 So you get the small benefit of additional inbound links, and a large
 minus from relevant content not being on my site.

 On Wed, Jun 20, 2012 at 10:29 AM, Neil Middleton neil.middle...@gmail.com
  wrote:

 Is there a valid reason for wanting to avoid serving directly from
 blog.yourapp.com (i.e are 301's sufficient?)

 On Wednesday, 20 June 2012 at 16:27, Jeff Schmitz wrote:

 I'd like to set up a reverse proxy, so that requests to
 myherokuapp.com/blog are served by blog.myherokuapp.com without the user
 being any the wiser.

 However, I haven't seen any way to do this in Heroku.

 Has anybody

 1) been able to do configure this, or
 2) been able to reverse proxy within their Rails app via gem/plugin, or
 3) deployed a blog gem/plugin *within* their Rails app that they love

 Tired of losing SEO juice, searching for answers...

 Thanks

 jeff

 --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


  --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


  --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


  --
 You received this message because you are subscribed to the Google
 Groups Heroku group.

 To unsubscribe from this group, send email to
 heroku+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/heroku?hl=en_US?hl=en


-- 
You received this message because you are subscribed to the Google
Groups Heroku group.

To unsubscribe from this group, send email to
heroku+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/heroku?hl=en_US?hl=en


Best approach for reverse proxying to several apps

2012-03-09 Thread gerardc
Hi all,

I'm currently researching the feasibility of somehow setting up reverse 
proxying between various applications (all rails/ruby) hosted on heroku.

My thinking is that one could act as the master - that sits under a top 
level domain - that filters and delegates requests.
From what I've found so far, there are a few ways of achieving this, namely 
a few different rack gems or even using rails' own routing layer. 
All these solutions are quite 'hacky' however and the related articles 
suggest they be used only in development environments.

I'm thinking however, that this approach is the wrong way to go about it. I 
could host the apps on a VSP and easily use NGinx to handle this sort of 
work. 
Plus it would mean less coupling between the apps overall... 

Does anyone have any experience of rolling out the above?

Any thoughts/hints/tips are greatly appreciated! :)

- ger


-- 
You received this message because you are subscribed to the Google Groups 
Heroku group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/heroku/-/3A8yNjRb_pQJ.
To post to this group, send email to heroku@googlegroups.com.
To unsubscribe from this group, send email to 
heroku+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/heroku?hl=en.