Diferència entre revisions de la pàgina «Buildout»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
 
(Hi ha 29 revisions intermèdies del mateix usuari que no es mostren)
Línia 7: Línia 7:
 
La conclusió és què no és bo refiar-nos de les versions dels paquets instal·lats en el sistema i descarregar els paquets que requereixi el nostre projecte en el nostre directori particular, i fer ús d'aquests directament sense utiltizar els de sistema.
 
La conclusió és què no és bo refiar-nos de les versions dels paquets instal·lats en el sistema i descarregar els paquets que requereixi el nostre projecte en el nostre directori particular, i fer ús d'aquests directament sense utiltizar els de sistema.
  
<big>Al sistema convé tenir només l'intèrpret i prou (en el nostre cas Python), sense packages, o amb els mínims possibles.</big>
+
<div class="exercici">Al sistema convé tenir només l'intèrpret i prou (en el nostre cas Python), sense packages, o amb els mínims possibles.</div>
 
Aquests "mínims possibles" solen ser distribute, setuptools i virtualenv per Python.
 
Aquests "mínims possibles" solen ser distribute, setuptools i virtualenv per Python.
  
Línia 17: Línia 17:
 
Anem a instal·lar el sistema de buildout per Pyhton i per un projecte Pyramid.
 
Anem a instal·lar el sistema de buildout per Pyhton i per un projecte Pyramid.
  
Pre-requisit: tenir Python al sistema. Millor sense cap package. Com que no es poden eliminar si no és "a mà", potser és més convenient fer una instal·larció neta del S.O. nostre servidor. Si es volen eliminar els python-eggs (packages) del sistema (en general instal·lats amb ''easy_install'' o ''pip''), es pot intentar eliminar-los esborrant-los del seu directori:
+
Pre-requisit: tenir Python al sistema. SENSE CAP PACKAGE. Com que no es poden eliminar si no és "a mà", potser és més convenient fer una instal·larció neta del S.O. nostre servidor. Si es volen eliminar els python-eggs (packages) del sistema (en general instal·lats amb ''easy_install'' o ''pip''), es pot intentar eliminar-los esborrant-los del seu directori:
 
  /usr/local/lib/pythonX.Y/site-packages
 
  /usr/local/lib/pythonX.Y/site-packages
 +
/usr/local/lib/pythonX.Y/dist-packages
 +
 +
=== Exemple de referència ===
 +
Podeu descarregar el projecte Egipcis de GitHub com a exemple:
 +
https://github.com/emieza/egipcis
 +
 +
Per descarregar-lo, construir-lo i arrencar el servidor:
 +
$ git clone https://github.com/emieza/egipcis.git
 +
$ cd egipcis
 +
$ python bootstrap.py
 +
$ bin/buildout
 +
$ bin/pserve development.ini
 +
<br>
  
 
=== Entorn de desenvolupament ===
 
=== Entorn de desenvolupament ===
 
El què anem a fer '''és per a l'entorn de desenvolupament'''. A l'entorn de producció no cal, ja que transferirem el buildout sencer (amb git o svn o per scp) un cop testejat:
 
El què anem a fer '''és per a l'entorn de desenvolupament'''. A l'entorn de producció no cal, ja que transferirem el buildout sencer (amb git o svn o per scp) un cop testejat:
  
# (opcional): instal·lar i posar a punt un virtualenv amb Pyramid
+
# (opcional): instal·lar i posar a punt un virtualenv amb Pyramid (per crear el ''scaffold'' Pyramid).
# Instal·lar el buildout: http://www.buildout.org/install.html (pas 2)
+
# Instal·lar el buildout: http://www.buildout.org/en/latest/install.html (anar directament al pas 2) LINK ACTUALTIZAT
# Iniciar el projecte (pas 3)
+
# Iniciar el projecte (pas 3): buildout init
# Descarregar el ''bootstrap.py'' (al final del pas 3)
+
# Descarregar el ''bootstrap.py'' d'aquí: http://downloads.buildout.org/2/bootstrap.py (el del tutorial està "deprecated")
 
# Crear carpeta "src" sota la qual posarem el projecte<pre> $ mkdir src</pre>
 
# Crear carpeta "src" sota la qual posarem el projecte<pre> $ mkdir src</pre>
# Anar dins la carpeta "src" i crear un projecte Pyramid: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/project.html
+
# Anar dins la carpeta "src" i crear un projecte Pyramid (en aquest exemple: ''myapp''): http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/project.html
 +
#: NOTA: amb el ''pcreate'' ja n'hi ha prou, no feu el ''setup'', ens pot portar problemes.
 
# Traslladar els ''.ini'' del Pyramid a l'arrel del buildout.
 
# Traslladar els ''.ini'' del Pyramid a l'arrel del buildout.
# Anar a l'arrel del buildout i crear buildout.cfg. Utiltizeu l'exemple al final d'aquest tutorial.
+
# Anar a l'arrel del buildout i crear buildout.cfg. Utilitzeu l'exemple al final d'aquest tutorial.
# Construir el projecte:
+
# Construir el projecte (ULL!: aquí potser millor '''NO utilitzar el virtualenv''': feu ''deactivate'' primer):
 +
$ deactivate
 
  $ python bootstrap.py
 
  $ python bootstrap.py
 
  $ bin/buildout -v
 
  $ bin/buildout -v
Línia 38: Línia 53:
 
  $ bin/pserve development.ini
 
  $ bin/pserve development.ini
  
=== Entorn de producció ===
+
=== Enllaç WSGI/Apache ===
 
A l'entorn de producció caldrà afegir un enllaç amb WSGI/Apache. Ja l'hem vist a l'hora de crear un projecte amb els ''scaffolds'' de Pyramid, però en aquest cas és una mica més elaborat perquè requereix carregar els packages dels directoris del buildout (eggs).
 
A l'entorn de producció caldrà afegir un enllaç amb WSGI/Apache. Ja l'hem vist a l'hora de crear un projecte amb els ''scaffolds'' de Pyramid, però en aquest cas és una mica més elaborat perquè requereix carregar els packages dels directoris del buildout (eggs).
  
Línia 50: Línia 65:
 
[mywsgiapp]
 
[mywsgiapp]
 
recipe = collective.recipe.modwsgi
 
recipe = collective.recipe.modwsgi
eggs = docpopservices
+
eggs = myapp
 
       Paste
 
       Paste
 
       PasteDeploy
 
       PasteDeploy
Línia 56: Línia 71:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Aquesta secció és innecessària a l'entorn de desenvolupament, tot i que es sol possar per testejar l'aplicació amb l'Apache.
+
Aquesta secció és innecessària a l'entorn de desenvolupament, tot i que es sol posar per testejar l'aplicació amb l'Apache.
 +
<br>
 +
 
 +
=== Entorn de producció ===
 +
El més convenient és tenir una instal·lació "fresca" del S.O. i només tenir els packages imprescindibles al sistema (la resta els carregarem al directori del projecte amb buildout):
 +
 
 +
* pip : http://www.pip-installer.org/en/latest/installing.html
 +
** Descarregar get_pip.py i executar-ho com a root/sudo
 +
* distribute + setuptools:<pre>$ sudo pip install --upgrade distribute</pre>
 +
* Eines de desenvolupament per compilar acceleracions de Python:<pre>$ sudo apt-get install python-dev</pre>
 +
 
 +
Un cop el projecte estigui desenvolupat i testejat en local, el podem posar en producció copiant els arxius i carpetes pertinents (no totes, que no cal i no convé, llegiu "notes sobre GIT" al final) al servidor públic. Un cop fet, podem reconstruïr el projecte amb:
 +
$ python bootstrap.py
 +
$ bin/buildout -v
 +
 
 +
...i configurant l'Apache per utiltizar l'aplicació wsgi que ha creat el '''collective.recipe.modwsgi''' (l'arxiu està dins la carpeta '''parts/mywsgiapps/wsgi'''). Aquest ''script'' generat s'assegurarà que agafa les llibreries descarregades a ''eggs'' i no les del sistema.
 +
 
 +
Llegeix també les "notes sobre GIT" al final del l'article, és important guardar només els arxius essencials i no els que no calen.
  
 
<br>
 
<br>
  
== Buildout per Pyramid ==
+
== Exemple d'arxiu buildout.cfg per a Pyramid ==
 
Exemple d'arxiu '''buildout.cfg''' per Pyramid:
 
Exemple d'arxiu '''buildout.cfg''' per Pyramid:
  
 
<syntaxhighlight lang="ini">
 
<syntaxhighlight lang="ini">
 
[buildout]
 
[buildout]
develop = src/myapp                    # secció principal on situem la nostra aplicació (sota src)
+
# secció principal on situem la nostra aplicació (sota src)
parts =                               # mòduls dels que consta el projecte a part del de desenvolupament
+
develop = src/myapp
 +
# mòduls dels que consta el projecte a part del de desenvolupament
 +
parts =
 
mywsgiapp
 
mywsgiapp
 
pyramid
 
pyramid
eggs-directory = eggs                  # directori on es descarreguen els packages (eggs)
+
# directori on es descarreguen els packages (eggs)
 
+
eggs-directory = eggs
eggs = myapp                          # el nostre egg
+
# el nostre egg
 
+
develop = src/myapp
 
+
 +
 
[mywsgiapp]
 
[mywsgiapp]
recipe = collective.recipe.modwsgi    # modwsgi ens facilitarà l'enllaç del WSGI/Apache amb el nostre buildout
+
# modwsgi ens facilitarà l'enllaç del WSGI/Apache amb el nostre buildout
 +
recipe = collective.recipe.modwsgi
 
eggs = myapp
 
eggs = myapp
 
       Paste
 
       Paste
 
       PasteDeploy
 
       PasteDeploy
 
config-file = ${buildout:directory}/production.ini
 
config-file = ${buildout:directory}/production.ini
 
+
 
[pyramid]
 
[pyramid]
recipe = zc.recipe.egg                # el mòdul zc.recipe.egg ens permetrà instal·lar els eggs necessaris pel projecte
+
# el mòdul zc.recipe.egg ens permetrà instal·lar els eggs necessaris pel projecte
 +
# també genera els scripts necessaris a bin/ com pserve, etc.
 +
recipe = zc.recipe.egg
 
dependent-scripts = true
 
dependent-scripts = true
 
eggs =
 
eggs =
Línia 93: Línia 131:
 
     pyramid_debugtoolbar
 
     pyramid_debugtoolbar
 
     myapp
 
     myapp
 
+
 
interpreter = py
 
interpreter = py
  
Línia 99: Línia 137:
  
 
Comentaris:
 
Comentaris:
 +
* Totes les llibreries necessàries pel projecte es poden posar a la llista "eggs" del zc.recipe.egg . Buildout les descarregarà i les instal·larà adequadament per poder-se executar després.
 
* ...
 
* ...
 +
 +
== Notes sobre GIT/SVN ==
 +
Com ja sabeu GIT o SVN serveixen per fer control de versions del software. És important no copiar en el repositori els arxius que es generen amb els ''scripts''. Així, cal generar un '''arxiu ''.gitignore'' a l'arrel del projecte''' on li direm quins arxius no s'han d'incloure en el sistema de versionat. Un exemple podria ser aquest:
 +
 +
.DS_Store
 +
*.pyc
 +
.bzr
 +
.bzrignore
 +
bin
 +
eggs
 +
develop-eggs
 +
parts
 +
.mr.developer.cfg
 +
.installed.cfg
 +
 +
<br>
 +
 +
Per afegir el projecte sencer al repo creeu el repositori a github.com, allà apareixeran les comandes necessàries per pujar el vostre projecte ''Buildout''.
 +
 +
Inicialitzem el projecte (es crea carpeta .git):
 +
$ git init
 +
 +
Si heu col·locat correctament l'arxiu .gitignore , només caldrà que feu això per afegir tots els arxius pertinents:
 +
$ git add "*"
 +
 +
i després commit i push:
 +
$ git status
 +
$ git commit -a
 +
$ git remote add origin https://github.com/<usuari>/<nomdelprojecte>.git
 +
$ git push -u origin master
 +
 +
Ale!!
 +
 +
== Problemes amb el joc de caràcters UTF-8 ==
 +
En producció, quan integrem en Apache, apareixen problemes de la codificació per defecte (ASCII). La volem canviar a "utf-8".
 +
 +
Cal editar '''/usr/lib/pythonX.Y/sitecustomize.py''' i afegir:
 +
<syntaxhighlight lang="python">
 +
import sys
 +
sys.setdefaultencoding('utf-8')
 +
</syntaxhighlight>
 +
<br>
 +
 +
== Notes sobre GAE (Pyramid-Appengine) ==
 +
Si has treballat sobre Google App Engine hi ha algunes diferències a solventar si volem passar codi fet en Pyramid "normal" (scaffold ''starter'') respecte el Pyramid_appengine (scaffold ''starter_appengine'').
 +
 +
 +
Si hem desenvolupat en Pyramid i volem passar-ho a GAE cal tenir en compte:
 +
* Els '''''decorators @'' no funcionen''' (potser us funciona en desenvolupament local, però poden fallar en producció, al menys en la v.1.8.x de GAE).
 +
 +
 +
Si hem desenvolupat en GAE i volem passar a Pyramid "normal":
 +
* La configuració sense decorators no té problema.
 +
* Cal afegir la plantilla "jinja2" al buildout.py
 +
* Cal arreglar els "entry_points" (són diferents en GAE). Es pot fer de 2 maneres:
 +
*# En '''__init__.py''', enlloc de la funció make_app() ha de ser main(global_config, **settings)
 +
*#:Millor afegir la funció ''main'' i dins d'ella fer ''return make_app()''
 +
*# <strike>'''O bé en setup.py''', deixar el paràmetre entry_points=""</strike> NO FUNCIONA
 +
 +
<br>
  
 
== Més encara ==
 
== Més encara ==
 
Llista de ...TODO...:
 
Llista de ...TODO...:
* diversos eggs en un mateix buildout
+
* diversos eggs en un mateix buildout. Afegir a setup.py:
 
       packages=find_packages('src'),
 
       packages=find_packages('src'),
 
       package_dir = {'': 'src'},
 
       package_dir = {'': 'src'},
 
* ...
 
* ...

Revisió de 09:57, 2 març 2014

Buildout és un sistema que ens permet elaborar projectes sense dependre de les versions dels paquets instal·lats en el sistema.

http://www.buildout.org

Quan en un mateix servidor conviuen diferents serveis o sites, les versions de l'intèrpret i dels packages per executar els scripts pot variar, el què ens podria portar a incompatiblitats, ja que el sistema sovint no pot gestionar disposar diverses versions alhora.

La conclusió és què no és bo refiar-nos de les versions dels paquets instal·lats en el sistema i descarregar els paquets que requereixi el nostre projecte en el nostre directori particular, i fer ús d'aquests directament sense utiltizar els de sistema.

Al sistema convé tenir només l'intèrpret i prou (en el nostre cas Python), sense packages, o amb els mínims possibles.

Aquests "mínims possibles" solen ser distribute, setuptools i virtualenv per Python.

De fet, en un entorn de desenvolupament podiem utiltizar virtualenv per solucionar aquest problema, però no pel sistema en producció.


Buildout per Python-Pyramid[modifica]

Anem a instal·lar el sistema de buildout per Pyhton i per un projecte Pyramid.

Pre-requisit: tenir Python al sistema. SENSE CAP PACKAGE. Com que no es poden eliminar si no és "a mà", potser és més convenient fer una instal·larció neta del S.O. nostre servidor. Si es volen eliminar els python-eggs (packages) del sistema (en general instal·lats amb easy_install o pip), es pot intentar eliminar-los esborrant-los del seu directori:

/usr/local/lib/pythonX.Y/site-packages
/usr/local/lib/pythonX.Y/dist-packages

Exemple de referència[modifica]

Podeu descarregar el projecte Egipcis de GitHub com a exemple:

https://github.com/emieza/egipcis

Per descarregar-lo, construir-lo i arrencar el servidor:

$ git clone https://github.com/emieza/egipcis.git
$ cd egipcis
$ python bootstrap.py
$ bin/buildout
$ bin/pserve development.ini


Entorn de desenvolupament[modifica]

El què anem a fer és per a l'entorn de desenvolupament. A l'entorn de producció no cal, ja que transferirem el buildout sencer (amb git o svn o per scp) un cop testejat:

  1. (opcional): instal·lar i posar a punt un virtualenv amb Pyramid (per crear el scaffold Pyramid).
  2. Instal·lar el buildout: http://www.buildout.org/en/latest/install.html (anar directament al pas 2) LINK ACTUALTIZAT
  3. Iniciar el projecte (pas 3): buildout init
  4. Descarregar el bootstrap.py d'aquí: http://downloads.buildout.org/2/bootstrap.py (el del tutorial està "deprecated")
  5. Crear carpeta "src" sota la qual posarem el projecte
     $ mkdir src
  6. Anar dins la carpeta "src" i crear un projecte Pyramid (en aquest exemple: myapp): http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/project.html
    NOTA: amb el pcreate ja n'hi ha prou, no feu el setup, ens pot portar problemes.
  7. Traslladar els .ini del Pyramid a l'arrel del buildout.
  8. Anar a l'arrel del buildout i crear buildout.cfg. Utilitzeu l'exemple al final d'aquest tutorial.
  9. Construir el projecte (ULL!: aquí potser millor NO utilitzar el virtualenv: feu deactivate primer):
$ deactivate
$ python bootstrap.py
$ bin/buildout -v

I ja podrem executar el nostre projecte Pyramid amb:

$ bin/pserve development.ini

Enllaç WSGI/Apache[modifica]

A l'entorn de producció caldrà afegir un enllaç amb WSGI/Apache. Ja l'hem vist a l'hora de crear un projecte amb els scaffolds de Pyramid, però en aquest cas és una mica més elaborat perquè requereix carregar els packages dels directoris del buildout (eggs).

Per sort, no cal fer gran cosa perquè tenim un recipe estàndard que ho resoldrà per nosaltres: el collective.recipe.modwsgi. Una recipe és un plugin pel buildout, amb utilitats comunes que s'utilitzen sovint, com és el cas de l'enllaç amb WSGI.

Per més detalls dels recipe i una llista: http://www.buildout.org/docs/recipelist.html

El que ens interessa és el què correspon a la secció [mywsgiapp] del buildout.cfg de més avall:

[mywsgiapp]
recipe = collective.recipe.modwsgi
eggs = myapp
       Paste
       PasteDeploy
config-file = ${buildout:directory}/production.ini

Aquesta secció és innecessària a l'entorn de desenvolupament, tot i que es sol posar per testejar l'aplicació amb l'Apache.

Entorn de producció[modifica]

El més convenient és tenir una instal·lació "fresca" del S.O. i només tenir els packages imprescindibles al sistema (la resta els carregarem al directori del projecte amb buildout):

  • pip : http://www.pip-installer.org/en/latest/installing.html
    • Descarregar get_pip.py i executar-ho com a root/sudo
  • distribute + setuptools:
    $ sudo pip install --upgrade distribute
  • Eines de desenvolupament per compilar acceleracions de Python:
    $ sudo apt-get install python-dev

Un cop el projecte estigui desenvolupat i testejat en local, el podem posar en producció copiant els arxius i carpetes pertinents (no totes, que no cal i no convé, llegiu "notes sobre GIT" al final) al servidor públic. Un cop fet, podem reconstruïr el projecte amb:

$ python bootstrap.py
$ bin/buildout -v

...i configurant l'Apache per utiltizar l'aplicació wsgi que ha creat el collective.recipe.modwsgi (l'arxiu està dins la carpeta parts/mywsgiapps/wsgi). Aquest script generat s'assegurarà que agafa les llibreries descarregades a eggs i no les del sistema.

Llegeix també les "notes sobre GIT" al final del l'article, és important guardar només els arxius essencials i no els que no calen.


Exemple d'arxiu buildout.cfg per a Pyramid[modifica]

Exemple d'arxiu buildout.cfg per Pyramid:

[buildout]
# secció principal on situem la nostra aplicació (sota src)
develop = src/myapp
# mòduls dels que consta el projecte a part del de desenvolupament
parts =
	mywsgiapp
	pyramid
# directori on es descarreguen els packages (eggs)
eggs-directory = eggs
# el nostre egg
develop = src/myapp
 
 
[mywsgiapp]
# modwsgi ens facilitarà l'enllaç del WSGI/Apache amb el nostre buildout
recipe = collective.recipe.modwsgi
eggs = myapp
       Paste
       PasteDeploy
config-file = ${buildout:directory}/production.ini
 
[pyramid]
# el mòdul zc.recipe.egg ens permetrà instal·lar els eggs necessaris pel projecte
# també genera els scripts necessaris a bin/ com pserve, etc.
recipe = zc.recipe.egg
dependent-scripts = true
eggs =
    pyramid
    waitress
    Paste
    PasteDeploy
    nose
    WebTest
    pyramid_debugtoolbar
    myapp
 
interpreter = py

Comentaris:

  • Totes les llibreries necessàries pel projecte es poden posar a la llista "eggs" del zc.recipe.egg . Buildout les descarregarà i les instal·larà adequadament per poder-se executar després.
  • ...

Notes sobre GIT/SVN[modifica]

Com ja sabeu GIT o SVN serveixen per fer control de versions del software. És important no copiar en el repositori els arxius que es generen amb els scripts. Així, cal generar un arxiu .gitignore a l'arrel del projecte on li direm quins arxius no s'han d'incloure en el sistema de versionat. Un exemple podria ser aquest:

.DS_Store
*.pyc
.bzr
.bzrignore
bin
eggs
develop-eggs
parts
.mr.developer.cfg
.installed.cfg


Per afegir el projecte sencer al repo creeu el repositori a github.com, allà apareixeran les comandes necessàries per pujar el vostre projecte Buildout.

Inicialitzem el projecte (es crea carpeta .git):

$ git init

Si heu col·locat correctament l'arxiu .gitignore , només caldrà que feu això per afegir tots els arxius pertinents:

$ git add "*"

i després commit i push:

$ git status
$ git commit -a
$ git remote add origin https://github.com/<usuari>/<nomdelprojecte>.git
$ git push -u origin master

Ale!!

Problemes amb el joc de caràcters UTF-8[modifica]

En producció, quan integrem en Apache, apareixen problemes de la codificació per defecte (ASCII). La volem canviar a "utf-8".

Cal editar /usr/lib/pythonX.Y/sitecustomize.py i afegir:

import sys
sys.setdefaultencoding('utf-8')


Notes sobre GAE (Pyramid-Appengine)[modifica]

Si has treballat sobre Google App Engine hi ha algunes diferències a solventar si volem passar codi fet en Pyramid "normal" (scaffold starter) respecte el Pyramid_appengine (scaffold starter_appengine).


Si hem desenvolupat en Pyramid i volem passar-ho a GAE cal tenir en compte:

  • Els decorators @ no funcionen (potser us funciona en desenvolupament local, però poden fallar en producció, al menys en la v.1.8.x de GAE).


Si hem desenvolupat en GAE i volem passar a Pyramid "normal":

  • La configuració sense decorators no té problema.
  • Cal afegir la plantilla "jinja2" al buildout.py
  • Cal arreglar els "entry_points" (són diferents en GAE). Es pot fer de 2 maneres:
    1. En __init__.py, enlloc de la funció make_app() ha de ser main(global_config, **settings)
      Millor afegir la funció main i dins d'ella fer return make_app()
    2. O bé en setup.py, deixar el paràmetre entry_points="" NO FUNCIONA


Més encara[modifica]

Llista de ...TODO...:

  • diversos eggs en un mateix buildout. Afegir a setup.py:
     packages=find_packages('src'),
     package_dir = {: 'src'},
  • ...