Mirin webspace

Nejbohatší život má ten, kdo žije s minimem nároků

20. 11. 2007 - Komentáře (4) PHP

Deployment PHP aplikací

Instalace aplikací v PHP se většinou provádí prostým kopírováním souborů na FTP nebo někam do adresáře. Pak se většinou spustí buď nějaký setup v prohlížeči, nastaví se určité parametry a hotovo. Jiný přístup používá nějaký konfigurační soubor (buď ini, xml nebo php skript), který je potřeba oeditovat. V obou případech je většinou nutné pořádně pročíst INSTALL README apod. To, co mě tedy v PHP chybí je nějaká podpora pro distribuci a instalaci PHP aplikací.

Klasická cesta, která člověka napadne je použít make, případně shell. Na tu jsem se dal i já a předem říkám, že to není vůbec sranda. V javě existuje ANT případně MAVEN, pro C# pak asi msbuild. Objevil jsem projekt phing, který by měl něco podobného řešit pro PHP, časem se na něj asi podívám, možná že to bude opravdu to pravé.

Co bych od takového nástroje očekával?

  • Podporu pro instalaci přes FTP, SSH, do adresáře.
  • Podporu pro změnu určitých konfiguračních částí aplikace interaktivně z příkazové řádky. Něco na způsob autoconf.
  • Podporu pro vytváření distribučních balíčků.
  • Podporu pro Windos i linux, takže by asi měl být napsán také v PHP.

Další, co mě napadá jsou balíčky, dost si slibuji od rozšíření phar, doufám, že v PHP6 už bude přímo součástí PHP. Tím se práce s distribucí a instalací PHP aplikací velmi ulehčí. Potřeba nějakého build a install systému pak ale bude o to větší.

Jak jsem zmínil výše, vydal jsem se cestou make, autoconf a shellu. Vytvořil jsem si configure a makefile, struktura PHP aplikace je pak následující.

app
 languages
 lib
 modules
www
 css
 images
 js
 index.php
AUTHORS   
COPYING   
README
configure
configure.in
Makefile.in 
INSTALL   
aconf       

V adresářích app, www je samotná PHP aplikace, soubory AUTHORS, COPYING, README jsou klasické GNU like distribuční soubory. To hlavní jsou Makefile.in a configure.in. V adresáři aconf jsou pomocné skripty pro autoconf a make. Používám to pak následovně:

Tímto vytvořím do adresáře /home/mira/finalApp finální distribuci, kterou stačí zkopírovat na FTP. Nastaví to příslušné řetězce v konfiguračních souborech, zakomentuje DEBUG konstanty apod.

$ ./configure --prefix=/home/mira/finalApp \
 --with-zflib=/data/web/virtuals/mujvirtual/app/lib \
 --with-baseurl=/ \
 --with-dbhost=localhost \
 --with-dbname=dbname \
 --with-dbusername=dbuser \
 --with-dbpassword=dbpassword

$ make
$ make install

Implementoval jsem si i podporu pro vytváření balíčku přes make dist. Tvorba Makefile byla ale opravdu ošklivá, nechtěl jsem se ubírat cestou, že autoconf bude upravovat přímo PHP skripty (ty by pak měly koncovku .in a autoconf by v nich provedl záměnu řetězců) ale retězce se nahradí až při make install. Tím ale vznikl dost šílený Makefile plný sedu, no hrůza. Jediné, co se relativně povedlo je configure.in, je poměrně jednoduchý.

$ cat configure.in
dnl Process this file with autoconf to produce a configure script.
AC_INIT(app/HomeWebApp.php)

AC_CONFIG_AUX_DIR(aconf)

AC_PREFIX_DEFAULT([/home/mira/myweb])

AC_SUBST(VERSION,"1.0")

AC_ARG_WITH(zflib,
 [AC_HELP_STRING([--with-zflib=DIR],
   [Zend Framework library directory])],
 [ZFLIB="$withval"],
 [with_zflib=no],
)

if test [ $with_zflib == "no" ] ; then
        AC_MSG_ERROR([Zend Framework library directory must be specified])
fi

AC_ARG_WITH(baseurl,
 [AC_HELP_STRING([--with-baseurl=url],
   [base url for rewriting (default is /)])],
 [BASEURL="$withval"],
 [BASEURL=/],
)

AC_ARG_WITH(dbhost,
 [AC_HELP_STRING([--with-dbhost=name],
   [host name for a database server (default is localhost)])],
 [DBHOST="$withval"],
 [DBHOST=localhost],
)

AC_ARG_WITH(dbname,
 [AC_HELP_STRING([--with-dbname=name],
   [database name (default is zfblog)])],
 [DBNAME="$withval"],
 [DBNAME=zfblog],
)

AC_ARG_WITH(dbusername,
 [AC_HELP_STRING([--with-dbusername=name],
   [username for a database access (default is root)])],
 [DBUSERNAME="$withval"],
 [DBUSERNAME=root],
)

AC_ARG_WITH(dbpassword,
 [AC_HELP_STRING([--with-dbpassword=name],
   [password for a database access (default is "")])],
 [DBPASSWORD="$withval"],
 [DBPASSWORD=""],
)

AC_SUBST(ZFLIB)
AC_SUBST(BASEURL)
AC_SUBST(DBHOST)
AC_SUBST(DBNAME)
AC_SUBST(DBUSERNAME)
AC_SUBST(DBPASSWORD)

AC_OUTPUT(
 Makefile
 app/languages/Makefile
)

echo "files will be installed into $ac_default_prefix directory"

Zato psát Makefile opravdu stojí za to, část, která provádí instalaci vypadá dost šíleně.

install: instFiles
        $(mkinstalldirs) $(wwwDest)
        for file in `cat instFiles`; do\
         dir=`dirname $(wwwDest)/$$file`;\
         if ! test -e $$dir; then\
          echo "creating dir $$dir";\
          mkdir -p $$dir;\
         fi;\
         { echo copying $$file; cp -p $$file $(wwwDest)/$$file ; } \
        done
        echo "copy prepared files to final"
        for tmpFile in $(prepFiles); do\
         destFile=`echo $$tmpFile | sed 's/\.tmp//'`;\
         mv $(wwwDest)/$$tmpFile $(wwwDest)/$$destFile;\
        done
        rm instFiles
        rm $(prepFiles)
        rm $(wwwDest)/app/languages/gettextUtils.sh

#create file instFiles with files, which will be copiied
instFiles: $(prepFiles)
        echo "making list of installed files"
        for dir in $(SUBDIRS); do\
         find $$dir ! -type d -print \
         | sed '/\/\(CVS\|RCS\)\//d; /.*\.svn.*/d; \
     /\.in$$/d; /Makefile/d; /app\/tests/d; \
     /$@/d; s/^.\///; /^\.$$/d; \
     /\.\(pot\|po\)$$/d; ' \
         | sort | uniq >> $@ ;\
        done
        echo "removig original of prepared files from $@"
        for file in $(prepFiles); do\
         echo "get original filename - remove .tmp";\
         file=`echo $$file | sed 's/\.tmp//'`;\
         echo "escaping . in string $$file";\
         file=`echo $$file | sed 's|\.|\\\.|'`;\
         echo "escaping / in string $$file";\
         file=`echo $$file | sed 's|/|\\\/|'`;\
         echo "removig $$file from $@";\
         sed "/$$file$$/d" $@ > $@.tmp;\
         mv $@.tmp $@;\
        done

No prostě šílené, vsadím se, že za pár měsíců na to budu koukat jak tele na nový vrata. Prostě kvalitní setup, install a build nástroj pro PHP mě dost schází.


Komentáře (4)

  1. Daniel Kvasnička - 26. 11. 2007 23:58

    Já používám Ant na deployment aplikací všeho druhu (PHP, Python, Java) už nějakou dobu a už si bez něj nedokážu život představit (o to víc když vidím váš makefile ;-), doporučuji vyzkoušet. Když jsem objevil Phing, tak už jsem nějak neměl důvod se o něj zajímat -- přecejen Eclipse má perfektní integraci Antu a Ant má taky už nějaké místo na slunci...

    Maven používáme v práci, ale pro moje osobní potřeby už mi to připadne jako kanón na vrabce...

  2. koubel - 27. 11. 2007 08:48

    Ant je určite výborný, další možnost je ješte nějaký nástroj z RoR, na obou mi trochu vadí nutná přítomnost dalšího prostředí/interpretru. Jak jsem si tak prohlížel prezentaci Phingu z letošní International PHP Conference, takto vypadá, že Phing zvládne všechno co Ant, podle mě na pro php aplikace bude to pravé ořechové.

    Další věc je ta podpora balíčků (něco jako jary v javě) to mě v PHP taky schází, respektive phar ale používá se minimálně.

  3. Daniel Kvasnička - 27. 11. 2007 21:45

    Nejen balicku, vubec neco na principu CLASSPATH z Javy nebo PYTHONPATH chybi... Kdyz jsem na Rootu cetl o novinkach v PHP 5.3, chtelo se mi smat a brecet zaroven. Nejdriv bude nutne jako vzdy pouzit include a pak bude mozne pracovat s namespaces...no tak kde to jsme :)

    Proto se snazim, pokud to jde, od PHP se presunout k Pythonu (Django, mod_python) a posledni dobou i k Jave - takovy framework Stripes ci perzistentncni/ORM vrstva Apache Cayenne, to jsou skvele kousky softwaru. Navic podpora XSLT 2.0, tuny ruznych knihoven prakticky na cokoliv a lepsi podpora v ceskem hostingovem prostredi nez treba pro Django/Python, to jsou docela silne argumenty...

  4. optik - 27. 11. 2007 23:08

    No, CLASSPATH se dá obejít přes vtipně napsaný __autoload a set_include_path(), pak se pracuje s namespaces a třídami bez include/require, to mě až tak netrápí.

    Ja osobně bych pro web aplikace volil raději dynamické skriptovací jazyky, takže když ne PHP, tak pak raději python/ruby, ale to je věc názoru.

Komentáře jsou uzavřeny.