reverse proxying with an Apache dyno
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
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
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
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
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
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
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
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.