| 17 | | # Script to turn a generic Debian Squeeze box into an Eden server |
| 18 | | # with Apache & MySQL |
| 19 | | |
| 20 | | # Update system |
| 21 | | apt-get update |
| 22 | | apt-get upgrade -y |
| 23 | | |
| 24 | | # Install Admin Tools |
| 25 | | apt-get install -y unzip psmisc mlocate telnet lrzsz vim elinks-lite rcconf htop sudo |
| 26 | | # Install Git |
| 27 | | apt-get install -y git-core |
| 28 | | # Email |
| 29 | | apt-get -y install exim4-config exim4-daemon-light |
| 30 | | |
| 31 | | ######## |
| 32 | | # MySQL |
| 33 | | ######## |
| 34 | | apt-get -y install mysql-server python-mysqldb phpmyadmin mytop |
| 35 | | |
| 36 | | # Tune for smaller RAM setups |
| 37 | | sed -i 's|query_cache_size = 16M|query_cache_size = 1M|' /etc/mysql/my.cnf |
| 38 | | sed -i 's|key_buffer = 16M|key_buffer = 1M|' /etc/mysql/my.cnf |
| 39 | | sed -i 's|max_allowed_packet = 16M|max_allowed_packet = 1M|' /etc/mysql/my.cnf |
| 40 | | |
| 41 | | /etc/init.d/mysql restart |
| 42 | | |
| 43 | | ######### |
| 44 | | # Apache |
| 45 | | ######### |
| 46 | | apt-get -y install libapache2-mod-wsgi |
| 47 | | a2enmod rewrite |
| 48 | | a2enmod deflate |
| 49 | | a2enmod headers |
| 50 | | a2enmod expires |
| 51 | | |
| 52 | | # Enable Basic Authentication for WebServices |
| 53 | | sed -i 's|</IfModule>|WSGIPassAuthorization On|' /etc/apache2/mods-enabled/wsgi.conf |
| 54 | | echo "</IfModule>" >> /etc/apache2/mods-enabled/wsgi.conf |
| 55 | | |
| 56 | | # Prevent Memory leaks from killing servers |
| 57 | | sed -i 's|MaxRequestsPerChild 0|MaxRequestsPerChild 300|' /etc/apache2/apache2.conf |
| 58 | | |
| 59 | | # Tune for smaller RAM setups |
| 60 | | sed -i 's|MinSpareServers 5|MinSpareServers 3|' /etc/apache2/apache2.conf |
| 61 | | sed -i 's|MaxSpareServers 10|MaxSpareServers 6|' /etc/apache2/apache2.conf |
| 62 | | |
| 63 | | apache2ctl restart |
| 64 | | |
| 65 | | # Holding Page for Maintenance windows |
| 66 | | cat << EOF > "/var/www/maintenance.html" |
| 67 | | <html><body><h1>Site Maintenance</h1>Please try again later...</body></html> |
| 68 | | EOF |
| 69 | | |
| 70 | | ######### |
| 71 | | # Python |
| 72 | | ######### |
| 73 | | # Install Libraries |
| 74 | | apt-get -y install libgeos-c1 |
| 75 | | |
| 76 | | # Install Python 2.6 |
| 77 | | apt-get -y install python2.6 python-dev ipython |
| 78 | | apt-get -y install python-lxml python-setuptools python-shapely python-dateutil |
| 79 | | apt-get -y install python-serial |
| 80 | | apt-get -y install python-imaging python-reportlab |
| 81 | | apt-get -y install python-xlwt python-xlrd |
| 82 | | |
| 83 | | ######### |
| 84 | | # Web2Py |
| 85 | | ######### |
| 86 | | # Install Web2Py |
| 87 | | adduser --system --disabled-password web2py |
| 88 | | addgroup web2py |
| 89 | | cd /home |
| 90 | | wget http://www.web2py.com/examples/static/web2py_src.zip |
| 91 | | unzip web2py_src.zip |
| 92 | | ln -s /home/web2py ~ |
| 93 | | cat << EOF > "/home/web2py/routes.py" |
| 94 | | #!/usr/bin/python |
| 95 | | default_application = 'eden' |
| 96 | | default_controller = 'default' |
| 97 | | default_function = 'index' |
| 98 | | routes_onerror = [ |
| 99 | | ('eden/400', '!'), |
| 100 | | ('eden/401', '!'), |
| 101 | | ('eden/*', '/eden/errors/index'), |
| 102 | | ('*/*', '/eden/errors/index'), |
| 103 | | ] |
| 104 | | EOF |
| 105 | | |
| 106 | | ############## |
| 107 | | # Sahana Eden |
| 108 | | ############## |
| 109 | | # Install Sahana Eden |
| 110 | | cd web2py |
| 111 | | cd applications |
| 112 | | # @ToDo: Stable branch |
| 113 | | git clone git://github.com/flavour/eden.git |
| 114 | | # Fix permissions |
| 115 | | chown web2py ~web2py |
| 116 | | chown web2py ~web2py/applications/admin/cache |
| 117 | | chown web2py ~web2py/applications/admin/cron |
| 118 | | chown web2py ~web2py/applications/eden |
| 119 | | chown web2py ~web2py/applications/eden/cron |
| 120 | | chown web2py ~web2py/applications/eden/models |
| 121 | | chown web2py ~web2py/applications/eden/static/img/markers |
| 122 | | mkdir -p ~web2py/applications/eden/static/cache/chart |
| 123 | | chown web2py -R ~web2py/applications/eden/static/cache |
| 124 | | mkdir -p ~web2py/applications/eden/uploads/gis_cache |
| 125 | | mkdir -p ~web2py/applications/eden/uploads/images |
| 126 | | mkdir -p ~web2py/applications/eden/uploads/tracks |
| 127 | | chown web2py -R ~web2py/applications/eden/uploads |
| 128 | | ln -s /home/web2py/applications/eden ~ |
| 129 | | |
| 130 | | ##################### |
| 131 | | # Management scripts |
| 132 | | ##################### |
| 133 | | cat << EOF > "/usr/local/bin/backup" |
| 134 | | #!/bin/sh |
| 135 | | NOW=\$(date +"%Y-%m-%d") |
| 136 | | mysqldump sahana > /root/backup-\$NOW.sql |
| 137 | | OLD=\$(date --date='7 day ago' +"%Y-%m-%d") |
| 138 | | rm -f /root/backup-\$OLD.sql |
| 139 | | EOF |
| 140 | | chmod +x /usr/local/bin/backup |
| 141 | | |
| 142 | | cat << EOF > "/usr/local/bin/compile" |
| 143 | | #!/bin/sh |
| 144 | | cd ~web2py |
| 145 | | python web2py.py -S eden -R applications/eden/static/scripts/tools/compile.py |
| 146 | | apache2ctl restart |
| 147 | | EOF |
| 148 | | chmod +x /usr/local/bin/compile |
| 149 | | |
| 150 | | cat << EOF > "/usr/local/bin/maintenance" |
| 151 | | #!/bin/sh |
| 152 | | if [ "" != "off" ] |
| 153 | | then |
| 154 | | a2dissite maintenance |
| 155 | | a2ensite production |
| 156 | | cd ~web2py && sudo -H -u web2py python web2py.py -K eden -Q >/dev/null 2>&1 & |
| 157 | | else |
| 158 | | killall -u web2py python |
| 159 | | a2ensite maintenance |
| 160 | | a2dissite production |
| 161 | | fi |
| 162 | | apache2ctl restart |
| 163 | | EOF |
| 164 | | chmod +x /usr/local/bin/maintenance |
| 165 | | |
| 166 | | cat << EOF > "/usr/local/bin/pull" |
| 167 | | #!/bin/sh |
| 168 | | cd ~web2py/applications/eden |
| 169 | | sed -i 's/deployment_settings.base.migrate = False/deployment_settings.base.migrate = True/g' models/000_config.py |
| 170 | | git pull |
| 171 | | /usr/local/bin/maintenance |
| 172 | | rm -rf compiled |
| 173 | | cd ~web2py |
| 174 | | sudo -H -u web2py python web2py.py -S eden -M -R applications/eden/static/scripts/tools/noop.py |
| 175 | | cd ~web2py/applications/eden |
| 176 | | sed -i 's/deployment_settings.base.migrate = True/deployment_settings.base.migrate = False/g' models/000_config.py |
| 177 | | /usr/local/bin/compile |
| 178 | | /usr/local/bin/maintenance off |
| 179 | | EOF |
| 180 | | chmod +x /usr/local/bin/pull |
| 181 | | |
| 182 | | # Change the value of prepopulate, if-necessary |
| 183 | | cat << EOF > "/usr/local/bin/clean" |
| 184 | | #!/bin/sh |
| 185 | | /usr/local/bin/maintenance |
| 186 | | cd ~web2py/applications/eden |
| 187 | | rm -f databases/* |
| 188 | | rm -rf errors |
| 189 | | rm -rf sessions |
| 190 | | rm -rf uploads |
| 191 | | sed -i 's/deployment_settings.base.migrate = False/deployment_settings.base.migrate = True/g' models/000_config.py |
| 192 | | sed -i 's/deployment_settings.base.prepopulate = 0/deployment_settings.base.prepopulate = 1/g' models/000_config.py |
| 193 | | rm -rf compiled |
| 194 | | mysqladmin -f drop sahana |
| 195 | | mysqladmin create sahana |
| 196 | | cd ~web2py |
| 197 | | sudo -H -u web2py python web2py.py -S eden -M -R applications/eden/static/scripts/tools/noop.py |
| 198 | | cd ~web2py/applications/eden |
| 199 | | sed -i 's/deployment_settings.base.migrate = True/deployment_settings.base.migrate = False/g' models/000_config.py |
| 200 | | sed -i 's/deployment_settings.base.prepopulate = 1/deployment_settings.base.prepopulate = 0/g' models/000_config.py |
| 201 | | /usr/local/bin/maintenance off |
| 202 | | /usr/local/bin/compile |
| 203 | | EOF |
| 204 | | chmod +x /usr/local/bin/clean |
| 205 | | |
| 206 | | cat << EOF > "/usr/local/bin/w2p" |
| 207 | | #!/bin/sh |
| 208 | | cd ~web2py |
| 209 | | python web2py.py -S eden -M |
| 210 | | EOF |
| 211 | | chmod +x /usr/local/bin/w2p |
| 212 | | |
| 213 | | # END |
| 214 | | }}} |
| 220 | | # Script to configure an Eden server |
| 221 | | # - assumes that install-eden-apache-mysql.sh has been run |
| 222 | | |
| 223 | | echo -e "What domain name should we use? : \c " |
| 224 | | read DOMAIN |
| 225 | | |
| 226 | | echo -e "What host name should we use? : \c " |
| 227 | | read hostname |
| 228 | | sitename=$hostname".$DOMAIN" |
| 229 | | |
| 230 | | echo -e "What is the current root MySQL password: \c " |
| 231 | | read rootpw |
| 232 | | |
| 233 | | # @ToDo: Generate a random password |
| 234 | | echo -e "What should be the MySQL password for user 'sahana': \c " |
| 235 | | read password |
| 236 | | |
| 237 | | echo "Now reconfiguring system" |
| 238 | | |
| 239 | | cd /etc |
| 240 | | filename="hosts" |
| 241 | | sed -i "s|localdomain localhost|localdomain localhost $hostname|" $filename |
| 242 | | |
| 243 | | cd /etc |
| 244 | | filename="hostname" |
| 245 | | echo $hostname > $filename |
| 246 | | |
| 247 | | cd /etc |
| 248 | | filename="mailname" |
| 249 | | echo $sitename > $filename |
| 250 | | |
| 251 | | # ----------------------------------------------------------------------------- |
| 252 | | # Email |
| 253 | | # ----------------------------------------------------------------------------- |
| 254 | | echo configure for Internet mail delivery |
| 255 | | dpkg-reconfigure exim4-config |
| 256 | | |
| 257 | | # ----------------------------------------------------------------------------- |
| 258 | | # Update system |
| 259 | | # in case run at a much later time than the install script |
| 260 | | # ----------------------------------------------------------------------------- |
| 261 | | apt-get update |
| 262 | | apt-get upgrade -y |
| 263 | | cd ~web2py/applications/eden |
| 264 | | git pull |
| 265 | | |
| 266 | | # ----------------------------------------------------------------------------- |
| 267 | | # Apache Web server |
| 268 | | # ----------------------------------------------------------------------------- |
| 269 | | echo "Setting up Web server" |
| 270 | | |
| 271 | | rm -f /etc/apache2/sites-enabled/000-default |
| 272 | | cat << EOF > "/etc/apache2/sites-available/$hostname.$DOMAIN" |
| 273 | | <VirtualHost *:80> |
| 274 | | ServerName $hostname.$DOMAIN |
| 275 | | ServerAdmin webmaster@$DOMAIN |
| 276 | | DocumentRoot /home/web2py/applications |
| 277 | | |
| 278 | | WSGIScriptAlias / /home/web2py/wsgihandler.py |
| 279 | | ## Edit the process and the maximum-requests to reflect your RAM |
| 280 | | WSGIDaemonProcess web2py user=web2py group=web2py home=/home/web2py processes=4 maximum-requests=100 |
| 281 | | |
| 282 | | RewriteEngine On |
| 283 | | # Stop GoogleBot from slowing us down |
| 284 | | RewriteRule .*robots\.txt$ /eden/static/robots.txt [L] |
| 285 | | # extract desired cookie value from multiple-cookie HTTP header |
| 286 | | #RewriteCond %{HTTP_COOKIE} registered=([^;]+) |
| 287 | | # check that cookie value is correct |
| 288 | | #RewriteCond %1 ^yes$ |
| 289 | | #RewriteRule ^/$ /eden/ [R,L] |
| 290 | | #RewriteRule ^/$ /eden/static/index.html [R,L] |
| 291 | | RewriteCond %{REQUEST_URI} !/phpmyadmin(.*) |
| 292 | | RewriteCond %{REQUEST_URI} !/eden/(.*) |
| 293 | | RewriteRule /(.*) /eden/$1 [R] |
| 294 | | |
| 295 | | ### static files do not need WSGI |
| 296 | | <LocationMatch "^(/[\w_]*/static/.*)"> |
| 297 | | Order Allow,Deny |
| 298 | | Allow from all |
| 299 | | |
| 300 | | SetOutputFilter DEFLATE |
| 301 | | BrowserMatch ^Mozilla/4 gzip-only-text/html |
| 302 | | BrowserMatch ^Mozilla/4\.0[678] no-gzip |
| 303 | | BrowserMatch \bMSIE !no-gzip !gzip-only-text/html |
| 304 | | SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary |
| 305 | | Header append Vary User-Agent env=!dont-vary |
| 306 | | |
| 307 | | ExpiresActive On |
| 308 | | ExpiresByType text/html "access plus 1 day" |
| 309 | | ExpiresByType text/javascript "access plus 1 week" |
| 310 | | ExpiresByType text/css "access plus 2 weeks" |
| 311 | | ExpiresByType image/ico "access plus 1 month" |
| 312 | | ExpiresByType image/gif "access plus 1 month" |
| 313 | | ExpiresByType image/jpeg "access plus 1 month" |
| 314 | | ExpiresByType image/jpg "access plus 1 month" |
| 315 | | ExpiresByType image/png "access plus 1 month" |
| 316 | | ExpiresByType application/x-shockwave-flash "access plus 1 month" |
| 317 | | </LocationMatch> |
| 318 | | ### everything else goes over WSGI |
| 319 | | <Location "/"> |
| 320 | | Order deny,allow |
| 321 | | Allow from all |
| 322 | | WSGIProcessGroup web2py |
| 323 | | </Location> |
| 324 | | |
| 325 | | ErrorLog /var/log/apache2/$hostname_error.log |
| 326 | | LogLevel warn |
| 327 | | CustomLog /var/log/apache2/$hostname_access.log combined |
| 328 | | </VirtualHost> |
| 329 | | EOF |
| 330 | | a2ensite "$hostname.$DOMAIN" |
| 331 | | apache2ctl restart |
| 332 | | |
| 333 | | cat << EOF > "/etc/apache2/sites-available/maintenance" |
| 334 | | <VirtualHost *:80> |
| 335 | | ServerName $hostname.$DOMAIN |
| 336 | | ServerAdmin webmaster@$DOMAIN |
| 337 | | DocumentRoot /var/www |
| 338 | | |
| 339 | | RewriteEngine On |
| 340 | | RewriteCond %{REQUEST_URI} !/phpmyadmin(.*) |
| 341 | | RewriteRule ^/(.*) /maintenance.html |
| 342 | | |
| 343 | | <Location "/"> |
| 344 | | Order deny,allow |
| 345 | | Allow from all |
| 346 | | </Location> |
| 347 | | |
| 348 | | ErrorLog /var/log/apache2/maintenance_error.log |
| 349 | | LogLevel warn |
| 350 | | CustomLog /var/log/apache2/maintenance_access.log combined |
| 351 | | </VirtualHost> |
| 352 | | EOF |
| 353 | | |
| 354 | | # ----------------------------------------------------------------------------- |
| 355 | | # MySQL Database |
| 356 | | # ----------------------------------------------------------------------------- |
| 357 | | echo "Setting up Database" |
| 358 | | |
| 359 | | # Allow root user to access database without entering password |
| 360 | | cat << EOF > "/root/.my.cnf" |
| 361 | | [client] |
| 362 | | user=root |
| 363 | | EOF |
| 364 | | |
| 365 | | echo "password='$rootpw'" >> "/root/.my.cnf" |
| 366 | | |
| 367 | | # Create database |
| 368 | | mysqladmin create sahana |
| 369 | | |
| 370 | | # Create user for Sahana application |
| 371 | | echo "CREATE USER 'sahana'@'localhost' IDENTIFIED BY '$password';" > "/tmp/mypass" |
| 372 | | echo "GRANT ALL PRIVILEGES ON *.* TO 'sahana'@'localhost' WITH GRANT OPTION;" >> "/tmp/mypass" |
| 373 | | mysql < /tmp/mypass |
| 374 | | rm -f /tmp/mypass |
| 375 | | |
| 376 | | # Schedule backups for 02:01 daily |
| 377 | | echo "1 2 * * * * root /usr/local/bin/backup" >> "/etc/crontab" |
| 378 | | |
| 379 | | # ----------------------------------------------------------------------------- |
| 380 | | # Sahana Eden |
| 381 | | # ----------------------------------------------------------------------------- |
| 382 | | echo "Setting up Sahana" |
| 383 | | |
| 384 | | # Copy Templates |
| 385 | | cp ~web2py/applications/eden/deployment-templates/cron/crontab ~web2py/applications/eden/cron |
| 386 | | cp ~web2py/applications/eden/deployment-templates/models/000_config.py ~web2py/applications/eden/models |
| 387 | | |
| 388 | | sed -i 's|EDITING_CONFIG_FILE = False|EDITING_CONFIG_FILE = True|' ~web2py/applications/eden/models/000_config.py |
| 389 | | sed -i "s|akeytochange|$sitename$password|" ~web2py/applications/eden/models/000_config.py |
| 390 | | sed -i "s|127.0.0.1:8000|$sitename|" ~web2py/applications/eden/models/000_config.py |
| 391 | | sed -i 's|base.cdn = False|base.cdn = True|' ~web2py/applications/eden/models/000_config.py |
| 392 | | |
| 393 | | # Configure Database |
| 394 | | sed -i 's|deployment_settings.database.db_type = "sqlite"|deployment_settings.database.db_type = "mysql"|' ~web2py/applications/eden/models/000_config.py |
| 395 | | sed -i "s|deployment_settings.database.password = \"password\"|deployment_settings.database.password = \"$password\"|" ~web2py/applications/eden/models/000_config.py |
| 396 | | |
| 397 | | # Create the Tables & Populate with base data |
| 398 | | sed -i 's|deployment_settings.base.prepopulate = 0|deployment_settings.base.prepopulate = 1|' ~web2py/applications/eden/models/000_config.py |
| 399 | | sed -i 's|deployment_settings.base.migrate = False|deployment_settings.base.migrate = True|' ~web2py/applications/eden/models/000_config.py |
| 400 | | cd ~web2py |
| 401 | | sudo -H -u web2py python web2py.py -S eden -M -R applications/eden/static/scripts/tools/noop.py |
| 402 | | |
| 403 | | # Configure for Production |
| 404 | | sed -i 's|deployment_settings.base.prepopulate = 1|deployment_settings.base.prepopulate = 0|' ~web2py/applications/eden/models/000_config.py |
| 405 | | sed -i 's|deployment_settings.base.migrate = True|deployment_settings.base.migrate = False|' ~web2py/applications/eden/models/000_config.py |
| 406 | | cd ~web2py |
| 407 | | sudo -H -u web2py python web2py.py -S eden -R applications/eden/static/scripts/tools/compile.py |
| 408 | | |
| 409 | | # Add Scheduler |
| 410 | | sed -i 's|exit 0|cd ~web2py \&\& python web2py.py -K eden -Q >/dev/null 2>\&1 \&|' /etc/rc.local |
| 411 | | echo "exit 0" >> /etc/rc.local |
| 412 | | |
| 413 | | #read -p "Press any key to Reboot..." |
| 414 | | echo "Now rebooting.." |
| 415 | | reboot |
| 416 | | |
| 417 | | # END |
| 418 | | }}} |