Deployment mit Phing z.B. Joomla Teil 3

Automatisiertes Deployen mit einem Befehl


In den ersten beiden Teilen (1, 2) wurde das Deployment weitgehend automatisiert. Es wurde ein Archiv erstellt, auf einen Server hochgeladen und dort wieder mit Phing verarbeitet. Gibt es keinen Grund für eine solche prozessbedingte Aufteilung, kann man das weiter automatisieren.

Um das ganze Deplyoment mit einem Befehl auszuführen, nimmt man das Batch-Script und die XML-Datei aus Teil 1 und passt diese an. Im Kern geht es darum, dass man SCP verwendet um das erstellte Archiv auf den Zielserver zu laden. Da SCP eine interaktive Benutzerauthentifizierung fordert, wird ein SSH-Key ohne Passwort verwendet. Dessen Speicherort wird als Argument mitgegeben.

Wenn das Archiv auf den Server hochgeladen ist, werden die Scripte aus Teil 2 so verwendet wie bisher. Der einzige Unterschied ist, dass man sich nicht mehr auf dem Server einloggt, sondern per SSH den Befehl auf dem Zielserver ausführt.

phing-config.xml


<?xml version="1.0" encoding="UTF-8"?>

<project name="JoomlaDeploymentBuild" default="extract_target">

    <fail unless="projectName" message="Please provide a projectName." />
    <fail unless="dbHost" message="Please provide the database host." />
    <fail unless="dbName" message="Please provide database name." />
    <fail unless="dbUser" message="Please provide database user name." />
    <fail unless="dbPassword" message="Please provide database password." />
    <fail unless="projectDir" message="Please provide where the project is located." />
    <fail unless="baseBuildDir" message="Please provide the base build directory." />
    <fail unless="targetDir" message="Please provide a target directory." />
    <fail unless="remoteHost" message="Please provide the remote host." />
    <fail unless="remoteUser" message="Please provide the remote user name." />
    <fail unless="remotePath" message="Please provide the remote path to upload archive." />
    <fail unless="sshKeyFile" message="Please provide the ssh key file." />
    <fail unless="targetDeployCommand" message="Please provide the target deploy command to execute on remote server." />

    <tstamp prefix="mytime"></tstamp>

    <property name="srcDirName" value="src" />
    <property name="dataDirName" value="data" />
    <property name="buildName" value="build_${projectName}_${mytime.DSTAMP}_${mytime.TSTAMP}" />
    <property name="buildDir" value="${baseBuildDir}/${buildName}" />
    <property name="srcDir" value="${buildDir}/${srcDirName}" />
    <property name="dataDir" value="${buildDir}/${dataDirName}" />
    <property name="archiveName" value="${buildName}.tar.gz" />
    
    <resolvepath propertyName="sourceDir" file="${projectDir}"/>    

    <!-- ============================================  -->
    <!-- Target: prepare                               -->
    <!-- ============================================  -->
    <target name="prepare">
        <tstamp prefix="mytime"></tstamp>
        <mkdir dir="${buildDir}" />
        <mkdir dir="${srcDir}" />
        <mkdir dir="${dataDir}" />
    </target>    
    
    <!-- ============================================  -->
    <!-- Target: dump                                  -->
    <!-- ============================================  -->
    <target name="dump" depends="prepare">    
        <echo msg="Dumping database ${dbName}" />
        <exec checkreturn="true" command="mysqldump  -h ${dbHost} -u${dbUser} -p${dbPassword} --default-character-set=utf8 --databases ${dbName}  > ${dataDir}/${dbName}.sql" />
    </target>    
    
    <!-- ============================================  -->
    <!-- Target: copy                                  -->
    <!-- ============================================  -->
    <target name="copy" depends="dump">    
        <echo msg="Copying files to build src directory ${srcDir}" />
        <copy todir="${srcDir}">
            <fileset dir="${sourceDir}">
                <include name="**"></include>
                <exclude name="**/.git/**"/>
                <exclude name="**/.svn/**"/>                
                <exclude name=".idea/**"/>
                <exclude name=".gitignore"/>
                <exclude name="cache/**"/>                <!-- has index.html -->
                <exclude name="tmp/**"/>                  <!-- has index.html -->
                <exclude name="administrator/cache/**"/>  <!-- has index.html -->
                <exclude name=".htaccess"/>
                <exclude name=".htpasswd"/>
                <exclude name="htaccess.txt"/>
                <exclude name="LICENSE.txt"/>
                <exclude name="README.txt"/>
                <exclude name="robots.txt.dist"/>
                <exclude name="web.config.txt"/>
            </fileset>
        </copy>        
        
        <copy file="${sourceDir}/cache/index.html" tofile="${srcDir}/cache/index.html" />
        <copy file="${sourceDir}/tmp/index.html" tofile="${srcDir}/tmp/index.html" />
        <copy file="${sourceDir}/administrator/cache/index.html" tofile="${srcDir}/administrator/cache/index.html" />
        
        <echo msg="All source files copied." />        
    </target>
    
    <!-- ============================================  -->
    <!-- Target: pack                                  -->
    <!-- ============================================  -->
    <target name="pack" depends="copy">
        <tar destfile="${buildDir}/${archiveName}" compression="gzip">
            <fileset dir="${buildDir}">
                <include name="${srcDirName}/**"></include>
                <include name="${dataDirName}/**"></include>
               </fileset>
        </tar>
    </target>
    
    <!-- ============================================  -->
    <!-- Target: clean                                 -->
    <!-- ============================================  -->
    <target name="clean" depends="pack">
        <move file="${buildDir}/${archiveName}" tofile="${targetDir}/${archiveName}" overwrite="true"/>
        <chmod mode="0777">
            <fileset dir="${buildDir}" defaultexcludes="false">
                <include name="**" />
            </fileset>
        </chmod>

        <echo msg="Cleanup, delete build dir ${buildDir}" />
        <delete dir="${buildDir}" includeemptydirs="true" verbose="false" failonerror="true" />
    </target>

    <!-- ============================================  -->
    <!-- Target: upload, use scp to skip php ssh2 ext. -->
    <!-- ============================================  -->
    <target name="upload" depends="clean">
        <echo msg="Upload archive to ${remoteUser}@${remoteHost}:${remotePath}"/>
        <exec checkreturn="true" command="scp -i ${sshKeyFile} ${targetDir}/${archiveName} ${remoteUser}@${remoteHost}:${remotePath} " />
    </target>

    <!-- ============================================  -->
    <!-- Target: extract_target                        -->
    <!-- ============================================  -->
    <target name="extract_target" depends="upload">
        <echo msg="Run deployment command on target server"/>
        <exec checkreturn="true" command="ssh -i ${sshKeyFile} -t ${remoteUser}@${remoteHost} ${targetDeployCommand} ${buildName}" />
    </target>

</project>

run.bat


echo off

set projectName="yourProject.com"
set dbHost="192.168.0.123"
set dbName="your_db_name"
set dbUser="your_db_user"
set dbPassword="super_geheim_123"
set projectDir="C:\htdocs\yourProject.com"
set baseBuildDir="G:\Build\joomla\yourProject.com"
set targetDir="G:\Deployment\archive"
set buildFile="G:\Projects\deployment-scripts\joomla\phing-config.xml"
set phingBinPath="C:\Opt\phing\phing.phar"

:: Configuration for scp and ssh
set remoteHost="your.server.com"
set remoteUser="user123"

:: Destination for the uploaded archive
set remotePath="/home/user123/deployment/your-project.com/archive"

:: Path to your passphrase free ssh private key, think to upload your public key to authorized_keys
set sshKeyFile="Z:\sshkeys\deployment\user123\id_rsa"

::  Shell script from part 2 of that turorial that runs the deployment on target server
set targetDeployCommand="/home/user123/deployment/your-project.com/run.sh"


call php %phingBinPath% -f %buildFile% ^
-DprojectName=%projectName% ^
-DdbHost=%dbHost% ^
-DdbName=%dbName% ^
-DdbUser=%dbUser% ^
-DdbPassword=%dbPassword% ^
-DprojectDir=%projectDir% ^
-DbaseBuildDir=%baseBuildDir% ^
-DtargetDir=%targetDir% ^
-DremoteHost=%remoteHost% ^
-DremoteUser=%remoteUser% ^
-DremotePath=%remotePath% ^
-DsshKeyFile=%sshKeyFile% ^
-DtargetDeployCommand=%targetDeployCommand%

Somit ruft man nur run.bat auf und alles weitere läuft vollautomatisch ab.

Zurück zur Kategorie: Dev-Ops
Zurück nach oben