Date Created: Sun 28-Nov-2010

Get my WebSphere Application Server course here >> http://www.themiddlewareshop.com/products/


    WordPress 0 to 60 in 5 minutes flat

    Article by Martin Jackson - Link to article: http://blog.screv.com/?p=34



    So Steve and I agreed that our first sprint was to build a WordPress server, that’ll be a snap to do (or so I thought!)

    In order to create a WordPress server I need 4 main components:

    • A Server with an Operating System installed
    • A MySQL database
    • A HTTP Web Daemon and
    • The WordPress application itself.

    So like a good boy scout I set off about installing a WordPress on a centos box by hand and I found some most excellent instructions here by Andrew at Adlibre.

    I hit my first problem, the WordPress package from EPEL for RHEL/CentOS 5 is quite old, it’s 2.8 while the version of WordPress with all the new hotness is 3.0.

    Hmm  ”old busted” or “new hotness” (not to say the 2.8 is either old or busted but you get what I mean). I decided I’d roll with the new hotness and then I hit another dilemma I couldn’t find a RPM for RHEL/CentOS 5, so should I just roll out the tar ball or create a package for it?

    This is currently a hot topic in the Devops community and when I went to Devops Hamburg back in October one of the more popular open space sessions was “packaging vs. non-packaging, when and what?” and the main output was it “depends”.

    However I wanted a zero touch and fully automated deployment so I investigated both methods and weighted them up:

    Scenario 1 – Installation of Tar ball

    • Download WordPress tar ball to the server file system
    • Untar the package and install it to the correct location
    • Track the installation and ensure that it is valid (correctly installed, all checksums in place (Thanks AndrewH!)) also be able to cleanly handle upgrades.
    Scenario 2 – Installation RPM
    • Package WordPress RPM
    • Yum install WordPress

    I quickly came to the conclusion that the packaging case won over when I imagined the amount of puppet code I’d have to churn out to do scenario #1 and make it robust versus just using what I believed was the right tool for the job i.e. RPM and keeping it as simple as possible.

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    Name          : wordpress
    Version       : 3.0.1
    Release       : 1
    Group         : System/Servers
    Summary       : Personal publishing platform.
    URL           : http://wordpress.org/
    Source0       : http://wordpress.org/%{name}-%{version}.tar.gz
    Vendor        : WordPress
    License       : GPLv2+
    Packager      : Martin Jackson
    BuildArch     : noarch
    BuildRoot     : %{_tmppath}/%{name}-%{version}-root
    Requires      : php
    Requires      : php-mysql
     
    %description
    WordPress is an open source Content Management System (CMS), often used as a
    blog publishing application, powered by PHP and MySQL. It has many features
    including a plug-in architecture and a template system.
     
    %prep
    %setup -q -n %{name}
     
    # fix dir perms
    find . -type d | xargs chmod 755
     
    # fix file perms
    find . -type f | xargs chmod 644
     
    # disable wordpress update option
    sed -i -e "s/add_action/#add_action/g" wp-includes/update.php
     
    %install
    rm -rf %{buildroot}
     
    install -d %{buildroot}%{_sysconfdir}/httpd/conf.d
    install -d %{buildroot}%{_sysconfdir}/%{name}
    install -d %{buildroot}/var/www/%{name}
     
    cp -aRf * %{buildroot}/var/www/%{name}/
     
    cat > %{buildroot}%{_sysconfdir}/httpd/conf.d/%{name}.conf << EOF
     
    Alias /%{name} /var/www/%{name}
     
        AllowOverride None
        Allow from All
     
    EOF
     
    # cleanup
    rm -f %{buildroot}/var/www/%{name}/license.txt
     
    %clean
    rm -rf %{buildroot}
     
    %files
    %defattr(-,root,root)
    /var/www/%{name}
    %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/%{name}.conf
     
    %changelog
    * Wed Nov 17 2010 Martin Jackson  3.0.1.1
    - initial Red Hat Enterprise package

    OK now I have my newly packaged WordPress 3.0 rpm and life is good, everything else I need is already packaged and can be easily installed using yum, a few minutes later I have a fully functioning WordPress server.

    Now for the fun part, how do a fully automate the creation of a WordPress server end to end.

    Firstly I created a custom kickstart profile on my cobbler server to install a minimal Just Enough Operating System (JeOS) base build (faster to install and patch with the minimum security attack surface) with some additional post install stuff to bootstrap puppet.

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    install
    url --url http://rasengan/cblr/links/Centos-5.5-x86_64
    key --skip
    lang en_US.UTF-8
    keyboard uk
    skipx
    network --device eth0 --bootproto dhcp --hostname testvm-wordpress.uncommonsense.local
     
    rootpw --iscrypted $MD5PASSWORD
    firewall --enabled --http --port=22:tcp
    authconfig --useshadow  --enablemd5
    selinux --permissive
    timezone Europe/London
    bootloader --location=mbr --driveorder=vda
    clearpart --all --initlabel
    part /boot --fstype ext3 --size=100
    part pv.2 --size=0 --grow --ondisk=vda
    volgroup VolGroup00 --pesize=32768 pv.2
    logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=512 --grow --maxsize=1024
    logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
    repo --name=source-1  --baseurl=http://rasengan/cobbler/ks_mirror/Centos-5.5-x86_64/
    $yum_repo_stanza
    reboot
     
    %packages --nobase --excludedocs
    coreutils
    dhclient
    yum
    rpm
    ruby
    libselinux-ruby
    subversion
    e2fsprogs
    lvm2
    grub
    sysstat
    ntp
    openssh-server
    openssh-clients
    xorg-x11-xauth
    screen
    net-snmp
    net-snmp-utils
    system-config-securitylevel
    xterm
    mutt
    sudo
    yum-downloadonly
    yum-protectbase
    -dhcpv6-client
    -iptables-ipv6
    -system-config-securitylevel-tui
    -wireless-tools
    -rhpl
    -mdadm
     
    %post
    exec < /dev/tty3 > /dev/tty3
    chvt 3
    echo
    echo ##############################
    echo # Running Post Configuration #
    echo ##############################
    echo
    rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
    echo "192.168.1.5             puppet rasengan rasengan.uncommonsense.local" >> /etc/hosts
    yum -y install puppet rdoc
    chkconfig puppet on
    cat > /etc/sysconfig/puppet << EOF
    # The puppetmaster server
    PUPPET_SERVER=rasengan
     
    # If you wish to specify the port to connect to do so here
    #PUPPET_PORT=8140
     
    # Where to log to. Specify syslog to send log messages to the system log.
    #PUPPET_LOG=/var/log/puppet/puppet.log
     
    # You may specify other parameters to the puppet client here
    #PUPPET_EXTRA_OPTS=--waitforcert=500
    EOF
    cat > /etc/puppet/puppet.conf << EOF
    [main]
        # The Puppet log directory.
        # The default value is '$vardir/log'.
        logdir = /var/log/puppet
     
        # Where Puppet PID files are kept.
        # The default value is '$vardir/run'.
        rundir = /var/run/puppet
        # Where SSL certificates are kept.
        # The default value is '$confdir/ssl'.
        ssldir = $vardir/ssl
        libdir = /var/lib/puppet/lib
     
    [puppetd]
        # The file in which puppetd stores a list of the classes
        # associated with the retrieved configuratiion.  Can be loaded in
        # the separate ``puppet`` executable using the ``--loadclasses``
        # option.
        # The default value is '$confdir/classes.txt'.
        classfile = $vardir/classes.txt
     
        # Where puppetd caches the local configuration.  An
        # extension indicating the cache format is added automatically.
        # The default value is '$confdir/localconfig'.
        localconfig = $vardir/localconfig
        pluginsync = true
        plugindest = /var/lib/puppet/lib
    EOF
    cat >> /etc/rc.local <<EOF
     
    ( sleep 360 ; /sbin/service puppet restart ; /sbin/service httpd graceful ) &
    EOF

    Next I had to install and configure a simple apache server I didn’t have to do anything clever with virtual hosts so I wrote a nice simple puppet module.

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    # Class: apache
    #
    # This class managed the apache httpd server
    #
    # Parameters:
    #   None
    #
    #
    # Actions:
    #   Install the latest version of apache httpd server
    #
    # Requires:
    #   - Package[""]
    #
    # Sample Usage:
    #
     
    class apache::install {
        package{"httpd":
            ensure => installed
        }
    }
     
    class apache::config {
        File{
            require => Class["apache::install"],
            notify  => Class["apache::service"],
            owner   => "root",
            group   => "root",
            mode    => 644
        }
    }
     
    class apache::service {
        service{"httpd":
            ensure  => running,
            enable  => true,
            require => Class["apache::config"],
        }
    }
     
    class apache {
        include apache::install,
                apache::config,
                apache::service
    }
     
    class apache::disable {
        include apache::install,
                apache::config
    }

    For the MySQL installation and configuration I wanted something a little more robust since I believed I could make a lot of use out of a good MySQL puppet module. I found it quite ironic that I stumbled across a problem that I had previously answered on server fault that being how do you find a top notch MySQL module:

    There were quite a few out there and after a fair bit of back and forth I settled on the Camp to Camp boys’ MySQL puppet module, it is very functional and quite compact in the amount of supporting modules that are needed to make it function:

    puppet-mysql

    puppet-augeas

    puppet-common

    You’ll need to have the plugin sync enabled in your puppet.conf for this to work because it copies some custom facts and plugins to the client in order to create the databases.

    ?
    1
    2
    3
    4
    5
    6
    [main]
        libdir = /var/lib/puppet/lib
     
    [puppetd]
        pluginsync = true
        plugindest = /var/lib/puppet/lib

    Onto the final stretch I need to install WordPress so I whipped up the following puppet module to install WordPress.

    I used the following entry in my nodes.pp file to pull it all together

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    node "testvm-wordpress.uncommonsense.local" {
            include repository::uncommonsense
            include apache
            include augeas
            include wordpress
            $mysql_password = "foo"
            include mysql::server::small
     
            mysql::rights {"Set rights for wordpress database":
               user     => "username",
               password => "password",
               database => "wordpress",
            }
     
            mysql::database {"wordpress":
               ensure   => present
            }
    }

    Ok so I now have a fully functional WordPress Server in about 5 minutes. This is just a basic setup but it demonstrates what can be done without too much effort and if I wanted to take this further in the future, I would create an erb template for the wp-config.php so that the database settings are populated by puppet using the existing username, password and database name variables.

    Martin Jackson is a Freelance Linux and Virtualization Consultant, Devops advocate, Infrastructure as Code Hacker and a keen Judoka. You can follow him as @actionjack on twitter.

    Get my WebSphere Application Server course here >> http://www.themiddlewareshop.com/products/


Steve Robinson - IBM Champion 2013

About Me

Steve Robinson has been working in IT for over 20 years and has provided solutions for many large-enterprise corporate companies across the world. Steve specialises in Java and Middleware.

In January 2013, I was awarded the prestigous 'IBM Champion' accolade.


Read my books?

IBM WebSphere Application Server 8.0 Administration Guide

IBM WebSphere Application Server 8.0 Administration Guide

WebSphere Application Server 7.0 Administration Guide

WebSphere Application Server 7.0 Administration Guide

WebSphere Categories

Other Categories