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
-~----------~----~----~----~------~----~------~--~---