I run multiple applications, however I run them all on the same app
server, I'm not trying to juggle two different app roles.

The method is scalable, we have an app role with three different rails
apps hosted on the same app server in testing at the moment, and
several with two in production.

we use nginx www role out front, our app servers use apache with
phusion passenger, but this method would work with anything you can
serve with apache; actually not even limited to apache, each app just
needs to be on a unique port no matter what serves it.

The two critical pieces are using  apache2 port based default virtual
hosts and amending the scalr code to generate nginx .include files for
each of the ports that are defined in apache.  Each application is
given a port such as 30000, 40000, 50000 ( no significance to the
number scheme)

 set :scalr_user_code, '/usr/local/aws/user'

    desc "Upload custom nginx port support"
    task :custom_ports, :roles => [:web] do
      upload 
"templates/scalr/user/lib/nginx_reload","#{scalr_user_code}/lib/nginx_reload"
      run "chmod ugo+x #{scalr_user_code}/lib/nginx_reload"
    end

we touch the include file to signify to our script that it should be populated

    desc "Add custom port"
    task :custom_port_add, :roles => [:web] do
      run "touch /etc/nginx/app-servers.#{apache_vhost_port}.include"
      scalr.nginx_reload
    end

then push out the nginx conf file for each application

    desc "Setup vhost conf on nginx web server."
    task :setup, :roles => [:web] do
      put 
ERB.new(File.read(nginx_template)).result(binding),"/etc/nginx/sites-available/#{apache_conf_file}"
      run "ln -sf /etc/nginx/sites-available/#{apache_conf_file}
/etc/nginx/sites-enabled/#{apache_conf_file}"
    end

push out the apache vhost file

      desc "Setup vhost conf on Apache web server."
      task :setup, :roles => [:app] do
        conf = File.read apache_conf_template
        require "erb"
        result = ERB.new(conf).result(binding)
        put result, "#{apache_conf_sites_available}/#{apache_conf_file}"
        run "ln -sf #{apache_conf_sites_available}/#{apache_conf_file}
#{apache_conf_sites_enabled}/#{apache_conf_file}"
      end

=== apache-vhost.conf ===

Listen <%=apache_vhost_port%>
<VirtualHost _default_:<%=apache_vhost_port%> >
    DocumentRoot <%=deploy_to%>/current/public
    Alias /404.html <%= passenger_resources %>/404.html
    Alias /500.html <%= passenger_resources %>/500.html
    ErrorDocument 404 /404.html
    <% %w(400 401 403 500).each do |code| %>
    ErrorDocument <%=code%> /500.html
    <% end %>
    <%=apache_vhost_entries%>
    CustomLog "|/usr/bin/logger -t httpd -p local1.info" combined
</VirtualHost>

=== end ===

=== from nginx_template ===
include /etc/nginx/app-servers.<%=apache_vhost_port%>.include;

server {
  listen 443;
  server_name <%=nginx_server_name%>;
...

 proxy_pass http://backend-<%=apache_vhost_port%>;

...
===  end ===

=== templates/scalr/user/lib/nginx_reload ===
#!/bin/bash

# nginx routines
#
# Copyright (C) 2008 Intridea, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA



. /usr/local/aws/lib/lib.sh

nginx_upstream_reload () {
  APP_PORT=$1
  NGINX_INCL="/etc/nginx/app-servers.$APP_PORT.include"
  touch $NGINX_INCL
  NGINX_BIN="/usr/sbin/nginx"
  TMP_INCL=`mktemp`
  NUM_OF_APPSERVERS="0"

  echo "upstream backend-$APP_PORT" { >> $TMP_INCL

  # Scanning aws hosts dir for Application servers
  for APP_SERV in `ec2_listhosts app`; do
    echo -e "\tserver `basename $APP_SERV`:$APP_PORT;" >> $TMP_INCL
    NUM_OF_APPSERVERS=$[ $NUM_OF_APPSERVERS + 1 ]
  done

  if [ $NUM_OF_APPSERVERS == "0" ]; then
    echo -e "\tserver 127.0.0.1:$1;" >> $TMP_INCL
  fi

  echo '}' >> $TMP_INCL


  # Determine, is configuration changed or no
  PRESENT_MD5=`md5sum $NGINX_INCL | cut -d" " -f1`
  NEW_MD5=`md5sum $TMP_INCL | cut -d" " -f1`

  if [ "$PRESENT_MD5" == "$NEW_MD5" ]; then
    logq "nginx upstream configuration not changed"
    rm $TMP_INCL
  else
    logq "nginx upstream configuration changed."
    mv $NGINX_INCL $NGINX_INCL.save
    mv $TMP_INCL $NGINX_INCL

    logq "Testing new configuration."
    # Test new configuration
    if [ -x $NGINX_BIN ] && ! NG_LOG=`$NGINX_BIN -t 2>&1`; then
      loga "Configuration error detected: '$NG_LOG'. Reverting configuration."

      mv $NGINX_INCL $NGINX_INCL.junk
      mv $NGINX_INCL.save $NGINX_INCL
    elif [ -f /var/run/nginx.pid ]; then
      logq "Reloading nginx."
      kill -HUP `cat /var/run/nginx.pid`
    fi
  fi
}

for f in /etc/nginx/app-servers.*.include
do
echo "Processing $f file..."
  if [[ $f =~ \.(.*)\. ]]
  then
echo Creating upstream include for port ${BASH_REMATCH[1]}
      nginx_upstream_reload ${BASH_REMATCH[1]}
  fi
done
=== end ===

On Fri, Jun 26, 2009 at 2:44 PM, jdMelton<[email protected]> wrote:
>
> I have a need to run two different app roles at the same time in the
> same farm; app and app-rails. I would like some advice on the way to
> approach this. I have searched the web and this group, but did not
> find anything on running both of these roles at the same time. I may
> have missed such information, though.
>
> Currently, I maintain Scalr.net farms for my customers and they run
> with www/app/mysqllvm. I have not brought up a production site with an
> app-rails role, yet.
>
> Most of my pre-scalr.net experience has been with Apache/PHP/Perl/Bash/
> C++/MySQL Linux systems administration. I have performed some scripted
> edits to /etc/nginx/nginx.conf on a www role to serve media files out
> of S3.
>
> I started up www/app/app-rails/mysqllvm in a scalr.net farm, then had
> a look at /etc/nginx/app-servers.include, but this did not
> differentiate between the two roles. I see that /etc/aws/hosts does
> contain app and app-rails. I could write a bash or Perl script to
> update nginx.conf upon changes in /etc/aws/hosts (or the host up/down
> events), yet I am not sure if this is an acceptable approach for
> scalability.
>
> The project will contain PHP focused sites and some Rails focused
> sites. Outside of Scalr.net, I have run threaded Apache 2.2, Phusion
> Passenger, and PHP5-CGI in FastCGI. The site was primarily a Rails
> site with a few items performed by PHP. This project will have
> significant functionality in Rails and in PHP 5, so I believe it would
> be best to use two different servers.
>
> Can anyone offer some advice or some web resources that I could read?
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"scalr-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/scalr-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to