Tim Jackson
If you're building and supporting a number of individual web applications then rapidly reproducing predictable deployments can become a challenge, especially when distributed across multiple developers and multiple environments. This talk outlines some of the real-world challenges, and introduces an open source tool which can help make your life easier.
Things we typically have to do to get a system up and running...
which can easily lead to...
and
$ wadf-deploy mywebapp Do you want to deploy database(s) if relevant? (y/n):y Checking out svn+ssh://svn@svn.example.com/apps/mywebapp/trunk... PEAR dependencies found; creating a PEAR installation in pear_local/ install ok: channel://pear.php.net/Archive_Tar-1.3.3 install ok: channel://pear.php.net/Structures_Graph-1.0.2 install ok: channel://pear.php.net/Console_Getopt-1.2.3 install ok: channel://pear.php.net/XML_Util-1.2.1 install ok: channel://pear.php.net/PEAR-1.9.0 Installing PEAR dependencies... upgrade ok: channel://pear.php.net/Net_URL-1.0.15 upgrade ok: channel://pear.php.net/HTTP_Request-1.4.4 upgrade ok: channel://__uri/mywebapp-1.1.0 Setting up database mywebapp on host localhost... Deleting existing tables in database mywebapp... Deploying new schema for database mywebapp as user myuser... Deploying webserver configuration... Deploying scheduled jobs from /home/myuser/mywebapp/crontab... Running kickstart script /home/myuser/mywebapp/setup.php... ----------- OUTPUT BELOW IS FROM KICKSTART SCRIPT, NOT WADF ----------- Set up initial database content.....................OK ------------------- END OF KICKSTART SCRIPT OUTPUT -------------------- Restarting webserver... Starting WADF HTTPD instance: [ OK ] Listening on port 10080 and configured for the following applications: mywebapp: (/home/myuser/mywebapp) ver=DEVTR:1792 http://mywebapp.localhost.localdomain:10080 $ firefox http://mywebapp.localhost.localdomain:10080
No, If you use the standard conventions, what we just saw can be done from a default install with only 1 option:
[local] vc_base = svn+ssh://svn@svn.example.com/apps
@some_macro@
@appref@
- app reference@deploy_path@
- filesystem path to deployed app@vhostX_name@
- application hostname (X=1,2,...)@dbX_[name|host|user|pass|type]@
- database details@php_dir@
- path to PEAR installation (if used)@profile@
- environment profile in usefoo.template
vs foo
- the original files with environment-specific data are not checked into SCMDefaults can be specified in a file called wadf.conf
in the root of the site (this can be checked in if you don't include passwords or things that vary from deployment-to-deployment...). Example:
[local] admin_email = developer@example.com [staging] admin_email = qa@example.com [live] admin_email = sales@customer.example.net
If you need to prompt at install time...
[globals] ; Here's a macro with a made-up name admin_email = developer@example.com [staging] ; '%%' means "prompt on deploy" (with optional message) admin_email = %%E-mail address to receive admin notifications vhost1_name = staging.example.com [live] ; '**' means "something should have been filled in here; halt the deployment" admin_email = **Awaiting customer admin contact vhost1_name = www.example.com
These values get saved in a file called .wadf-instance
within the deployment.
By default, these are all in the root of the application, but that's configurable (as is the naming).
vhost-httpd.conf.template
- template Apache HTTPD virtual host. Don't include PHP config options! (think about CGI)php.ini
- PHP configuration options for the app, including include_path
etc.setup.php
- anything that needs setting up, typically basic population of SQL databaseschema.sql
- SQL schema (without data)crontab
- scheduled jobs for this applicationpackage.xml
- Dependency metadataExample vhost.conf.template
<VirtualHost @vhost1_interface@> ServerName @vhost1_name@ DocumentRoot @deploy_path@/webroot RewriteEngine on RewriteRule /.* @deploy_path@/application/bootstrap_http.php </VirtualHost>
Example php.ini
:
engine = on ; when processed, 'php_dir' will be the path to the PEAR installation include_path = .:@deploy_path@/include:@php_dir@ register_globals = off magic_quotes_gpc = off ...
Create a package.xml
file in the root of the site (location configurable)
package.xml
format which is unfortunately a bit long-winded for what we want<dependencies>
sectionExample package.xml
for the web application itself:
<package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0"...> <name>testapp</name> <channel>__uri</channel> <summary>Test application</summary> <description>Test application</description> ...some boring stuff here: version, notes, developer etc. ... <dependencies> <required> <php><min>5.2.0</min></php> <pearinstaller><min>1.7.0</min></pearinstaller> <package> <name>HTTP_Request</name> <channel>pear.php.net</channel> <min>1.4.4</min> </package> </required> </dependencies> <phprelease/> </package>
pear list
') a "dependency tags" file which overrides the normal dependency mechanism and force-installs the specified versions:PEAR:pear.php.net/Archive_Tar-1.3.3 PEAR:pear.php.net/Console_Getopt-1.2.3 PEAR:pear.php.net/Date-1.4.7 ... SVN:svn+ssh://svn@svn.example.com/Somelib/trunk@12345 /checkouts/Somelib ...
(SVN dependencies are there as an optional alternative to externals; useful if you have groups of developers accessing SVN via different protocols e.g. HTTP, SVN, SVN+SSH etc.)
channel-discover pear.timj.co.uk
pear install timj/Tools_WADF
[local] vc_base = svn+ssh://svn@example.com/clients
wadf-deploy [-d foo=bar] [-v] [-r revision] <appref> [version]
wadf-reprocess [--db] [--templates-only] ... [version]
wadf-undeploy
wadf-clean
wadf-list-macros
wadf-httpd [-i myapp] [start|stop|restart|reload|status|...]
wadf-deploy
. This will:
*.template
)wadf-reprocess
if you've changed any template files or dependencieswww.timj.co.uk/computing/software/wadf