Plone 4.1 with Apache and mod_wsgi (sorta)

Update 2011-06-01: Still not working perfectly, but I did manage to clean up a couple steps by using more of mod_wsgi’s bells and whistles:

Issues:

  • The site is still slow (despite using Daemon Mode)
  • I get signal errors. This is a known problem when trying to serve signal-dependent python stuff via mod_wsgi, but I’m not sure it causes any real problems.
    [Wed Jun 01 17:59:40 2011] [warn] mod_wsgi (pid=12739): Callback registration for signal 10 ignored.
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/zeocluster/zope2.wsgi", line 3, in 
    [Wed Jun 01 17:59:40 2011] [warn]     application = make_wsgi_app(None, '/var/www/Plone-ZEO-4.1rc2/zeocluster/parts/client1/etc/zope.conf')
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/run.py", line 68, in make_wsgi_app
    [Wed Jun 01 17:59:40 2011] [warn]     starter.prepare()
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/__init__.py", line 90, in prepare
    [Wed Jun 01 17:59:40 2011] [warn]     self.registerSignals()
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/__init__.py", line 340, in registerSignals
    [Wed Jun 01 17:59:40 2011] [warn]     self.cfg.trace])
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Signals/Signals.py", line 115, in registerZopeSignals
    [Wed Jun 01 17:59:40 2011] [warn]     SignalHandler.registerHandler(SIGUSR1, showStacks)
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Signals/SignalHandler.py", line 37, in registerHandler
    [Wed Jun 01 17:59:40 2011] [warn]     signal.signal(signum, self.signalHandler)
  • In many cases I can’t POST to the site. I can log in as long as it’s not HTTP Basic, but I can’t edit pages or make site-setup configuration changes. Not sure why.

Notes:

  • For the following instructions I did every step as the user apache, so Plone runs as that user, as does zeo. This may not be the absolute best practice, but it made things a bit simpler.
  • You can substitute instance in probably every case cartier love bracelet ebay fake
    I used client1.
  1. Install Apache and mod_wsgi. Make sure to specify Python 2.6 for mod_wsgi.
  2. Grab a Plone 4.1 release candidate and install it as the user apache. Use the same Python 2.6 as you did for mod_wsgi.
  3. Create a path configuration file:
    $ ( # Do this in a subshell so we don't contaminate the IFS
    >   # variable in our normal shell.
    > cd /var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs
    > eggs=( *.egg )
    > IFS=$'\n'
    > echo "${eggs[*]}" > mod_wsgi.pth
    > )
  4. In your fake cartier bracelets
    buildout cartier love necklace directory cartier love bangle create an empty file called ‘zope2.wsgi.in’ as a collective.recipe.template template.copy the bin/client1 file into zope2.wsgi.in (because you need all the egg paths)
  5. Put these two lines in it:
    from Zope2.Startup.run import make_wsgi_app
    application = make_wsgi_app(None, '${zope-conf}')
  6. Add a section called wsgi to your buildout.cfg file:
    [buildout]
    …
    parts =
            …
            wsgi
            …
    …
    [wsgi]
    recipe = collective.recipe.template
    input = zope2.wsgi.in
    output = zope2.wsgi
    zope-conf = ${client1:location}/etc/zope.conf
  7. In your apache config:
    …
    WSGIPythonPath /var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/
    WSGIDaemonProcess neon processes=1 threads=1 python-path=/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/
    WSGIProcessGroup neon
    WSGIScriptAlias / /var/www/Plone-ZEO-4.1rc2/zeocluster/zope2.wsgi
    
    <Directory "/var/www/Plone-ZEO-4.1rc2/zeocluster">
            Order allow,deny
            Allow from all
    </Directory>
    …
  8. Run buildout and start replica cartier the zeoserver.
  9. I had some problems with cartier love bracelet replica HTTP Basic Authentication through WSGI, so I avoided it by starting cartier bracelet of anastasia steele actress
    the client without WSGI for the purpose of logging in to the ZMI to create the Plone site. bin/client1 fg
  10. Log in to http://localhost:8080 and create the Plone site.
  11. Once I had actually created the Plone site, I killed the client1 instance and removed the <http-server> section from zope.conf
  12. Start apache, and observe the logs as you navigate around your Plone site on port 80.

As I said, my site is slow and a lot of errors appear in the logs, but it’s functional, which is better than I’ve seen it so far. More work on this later.

The Future of the Internet is in the Client and the Cloud

Commentary on: http://www.zdnet.com/blog/btl/the-future-of-the-internet-its-in-the-app/49512?tag=nl.e539

The Forrester CEO cited in this article strikes me as remarkably naïve
(or maybe badly misquoted). I’m not downplaying the importance of
apps, but 90% of the popular www.cartierbracelets.co apps bracelets on the market are popular because
they exchange cartier love bracelet ebay fake
data with a web server. “Leaves cloud computing in the
dust”? I don’t think so. The app model depends on cloud computing.

Now, there’s been some interesting development in the area of merging
the concept of apps with websites. Both Google and Mozilla are working
on it from opposite ends: Google with its ChromeOS efforts (oddly,
ChromeOS is diametrically opposite of the space cartier bracelet of anastasia steele actress
occupied by Android,
but I think Google’s doing that strategically replica cartier love bracelets and on purpose) and
Mozilla with its Open Web Applications project.

I’m not sure cartier bracelets what approach Microsoft will really take. They’ve made
their position on HTML 5 clear, and that’s a good thing, but as for
apps they seem to just be covering their bases. (They’ve made it
possible to install Android apps on the Windows Mobile platform, for
example.)

I am interested in the app model, definitely, but the Internet isn’t
going to change as drastically as Colony seems to think. The article
does rightly point out that the Internet will use more of the power of
client machines than it has in the past, but that has less discount cartier bracelet to do with
apps than it does with the growth of HTML 5, powerful Javascript
engines like V8 and frameworks like Sencha and JQuery. (Those tend to
be hidden behind app development anyway.)

So I’m following the app discussion carefully, but really focusing my
efforts on the cross-platform frameworks like Mozilla’s OWA, because replica cartier love bracelets I
think that’s where the biggest bang for my buck will end up.

How to build a simple shared zeoclient-only setup for Plone 3

Note: The following is probably very adaptable to Plone 4. In fact, I suspect it’s even easier in Plone 4. But I’m working on Plone 3 right now, so there you go.

This is the second in a two-part guide on how to separate the Plone database server from the client instances. Even with load-balancing proxies, convenient high-availability in Plone always remains just out of reach. As long as the zeoserver and its clients are on the same www.cartierlovebracelet.co machine, you have to consider both server and clients in your change control processes. Separation is simplification. I’ve given other reasons to care in my previous cartier love bracelet ebay fake
post, but as an update, here is the approximate storage size of a single client-only site with a lot of eggs:

$ du -hs *
53M	Python-2.4
73M	Zope-2.10.11-final-py2.4
149M	testcase

Getting started with the clients

  1. Decide how you will structure your filesystem:
    • Shared Python 2.4: /opt/plone/Python-2.4
    • Shared Zope 2.10: /opt/plone/Zope-2.10.11-final-py2.4
    • Buildout for zeo: /opt/plone/testcase
  2. Create the user that the clients will run as. Create the parents of the above cartier love bracelet
    paths and give that user ownership. Become cartier bracelet of anastasia steele actress
    that user for the rest of these instructions.

    useradd plone
    mkdir /opt/plone && chown plone /opt/plone
    su - plone || sudo -u plone bash
  3. Download and unpack the Universal Installer (UI) from Plone.org. Use the UI to install a shared Zope and Python, but nuke the rest of what it installs for now.
    ./install.sh --target=/opt/plone zeo && rm -rf /opt/plone/{buildout-cache,zeocluster}
  4. Use the UI to install an actual zeoserver using that shared Python and Zope:
    ./install.sh --target=/opt/plone/testcase --with-python=/opt/plone/Python-2.4/bin/python --with-zope=/opt/plone/Zope-2.10.11-final-py2.4 zeo
  5. Go to the zeocluster directory and clean out the buildout stuff that is only needed for Plone clients. You really only need
    bin/buildout, buildout.cfg. If you’re using bash you can do this quickly with extglob:

    cd /opt/plone/testcase/zeocluster && shopt -s extglob
    rm -rf ../buildout-cache/ bin/!(buildout) !(bin|buildout.cfg|versions.cfg) .installed.cfg
  6. Create a backup of the buildout file and begin working on it. You can delete almost everything in there, just keep the zope2, zopepy and client parts and fix any broken references. Here’s what mine looks like:
    [buildout]
    extends = versions.cfg
    versions = versions
    extensions = buildout.dumppickedversions
    zeo-address = 10.0.0.87:8100
    client1-address = 8080
    client2-address = 8081
    eggs = Plone
    zcml =
    develop =
    debug-mode = off
    parts =
            zope2
            client1
            client2
            zopepy
    
    [zope2]
    recipe = plone.recipe.zope2install
    fake-zope-eggs = true
    additional-fake-eggs =
            ZConfig
            pytz
    location = /opt/plone/Zope-2.10.11-final-py2.4
    
    [client1]
    recipe = plone.recipe.zope2instance
    zeo-client = true
    zeo-address = ${buildout:zeo-address}
    effective-user = plone
    user = admin:abc
    http-address = ${buildout:client1-address}
    debug-mode = ${buildout:debug-mode}
    verbose-security = ${buildout:debug-mode}
    deprecation-warnings = ${buildout:debug-mode}
    eggs = ${buildout:eggs}
    zcml = ${buildout:zcml}
    environment-vars = PYTHON_EGG_CACHE ${buildout:directory}/var/.python-eggs
    zope2-location = ${zope2:location}
    
    [client2]
    < = client1
    http-address = ${buildout:client2-address}
    
    [zopepy]
    recipe = zc.recipe.egg
    eggs = ${buildout:eggs}
    interpreter = zopepy
    extra-paths = ${zope2:location}/lib/python
    scripts = zopepy
    
    [versions]
    Cheetah = 2.0.1
    Paste = 1.7.2
    PasteScript = 1.7.3
    ZopeSkel = 2.11.1
    collective.recipe.backup = 1.1
    plone.recipe.command = 1.0
    plone.recipe.distros = 1.5
    plone.recipe.osxcontroller = 0.3
    plone.recipe.precompiler = 0.3
    plone.recipe.unifiedinstaller = 0.9
    collective.recipe.zope2cluster = 1.0
    PasteDeploy = 1.3.3
    zc.recipe.egg = 1.2.2
  7. Once you’re satisfied with your buildout configuration, run buildout, fix permissions and try to start the instance. (Note: buildout always crashes the first replica cartier ring time I do this because of a setuptools incompatibility. Just run it again if it fails.):
    bin/buildout || bin/buildout && bin/client1 start && bin/client2 start
  8. That’s it! Now to create cartier replica a new client setup, just repeat steps 5-8, updating the paths and port cartier replica numbers (zeo-address, clientN-address) to suit.

That’s really all there is to it.

How to build a simple shared zeoserver-only setup for Plone 3

Note: The following is probably very adaptable to Plone 4. In fact, I suspect it’s even easier in Plone 4. But I’m working on Plone 3 right now, so there you go.

When you first install Plone, you get everything together: server, client, whatever, it just works. I’m sure not everybody knows, or cares, that Zope can be run as a zeoserver distinct from the zeoclient. But there are some reasons to care:

  1. Simplicity: Plone can seem complex, but zeoserver is dead simple. Separating it from the clients is the easiest way to see this.
  2. Flexibility: Need to reboot or migrate a server without site downtime? You can’t, unless you’re using load-balancing proxies. But with zeoserver on a separate machine from the clients, the clients can withstand short outages of the zeoserver without apparent downtime, even if you don’t have a load balancer! (YMMV depending on demand, zeoserver’s reboot time and the clients’ caches.) Moving the clients gets easier, too.
  3. Backups: I don’t need to backup all of Plone. The only important part is the Data.fs (and in Plone 4, the blobs, but that’s for another day). Now my backup scenario can effectively ignore the client cartier love bracelet ebay fake
    servers, and just back up what’s on the server with the ZODBs on it.
  4. Scalability: I’ll let these results speak for themselves:
    Before
    $ du -hs --exclude '*.log' plone
    526M     site1
    407M     site2
    676M     site3
    After:
    $ du -hs *
    53M	Python-2.4
    73M	Zope-2.10.11-final-py2.4
    11M	site1
    11M	site2
    11M	site3

    Well, that’s not quite discount cartier bracelet fair cartier bracelet of anastasia steele actress
    – the client code isn’t listed there, but it’s no longer an issue for this server.

Hopefully that’s enough to get you interested.

Getting started

  1. Decide how you will cartier replica structure your filesystem:
    • Where the Data.fs will be stored: /srv/plone/testcase/Data.fs
    • Shared Python 2.4: /opt/plone/Python-2.4
    • Shared Zope 2.10: /opt/plone/Zope-2.10.11-final-py2.4
    • Buildout for zeo: /opt/plone/testcase
  2. Create the user that the zeoservers will run as. Create the parents of the above paths and give that user ownership. Become that user for the rest of these instructions.
    useradd zeo
    mkdir /srv/plone && chown zeo /srv/plone
    mkdir /opt/plone && chown zeo /opt/plone
    su - zeo || sudo -u zeo bash
  3. Download and unpack the Universal Installer (UI) from Plone.org. Use the UI to install a shared Zope and Python, but nuke the rest of what it installs for now.
    ./install.sh --target=/opt/plone zeo && rm -rf /opt/plone/{buildout-cache,zeocluster}
  4. Use the UI to install an actual zeoserver using that shared Python and Zope:
    ./install.sh --target=/opt/plone/testcase --with-python=/opt/plone/Python-2.4/bin/python --with-zope=/opt/plone/Zope-2.10.11-final-py2.4 zeo
  5. Go to the zeocluster directory and clean out the buildout stuff that is only needed for Plone clients. You really only need bin/buildout, buildout.cfg. If you’re using bash you can do this quickly with extglob:
    cd /opt/plone/testcase/zeocluster && shopt -s extglob
    rm -rf ../buildout-cache/ bin/!(buildout) !(bin|buildout.cfg|versions.cfg) .installed.cfg
  6. Create a backup of the buildout file and begin working on it. You can delete almost everything in there, just keep the zope2 and zeoserver parts and fix any broken cartier bracelets references. Here’s what mine looks discount cartier bracelet like:
    [buildout]
    extends = versions.cfg
    versions = versions
    extensions = buildout.dumppickedversions
    dump-picked-versions-file = picked-versions.cfg
    zeo-address = 8100
    file-storage = /srv/plone/testcase/Data.fs
    parts =
    	zope2
    	zeoserver
    
    [zope2]
    recipe = plone.recipe.zope2install
    url = ${versions:zope2-url}
    fake-zope-eggs = true
    additional-fake-eggs =
    	ZConfig
    	pytz
    
    [zeoserver]
    recipe = plone.recipe.zope2zeoserver
    zope2-location = ${zope2:location}
    zeo-address = ${buildout:zeo-address}
    effective-user = zeo
    file-storage = ${buildout:file-storage}
  7. Once you’re satisfied with your buildout configuration, run buildout, fix permissions and try to start the instance. (Note: buildout always crashes the first time I do this because of a setuptools incompatibility. Just cartier replica run it again if it fails.):
    bin/buildout || bin/buildout && chown -R zeo:zeo . && bin/zeoserver start
  8. That’s it! Now to create a new zeoserver, just repeat steps 5-8, updating the paths and port number (zeo-address) to suit.

That’s really all there is to it. Tomorrow I’ll post bracelets how to put together the client side.