Skip to content. | Skip to navigation

Personal tools
Log in
Sections
You are here: Home

it-spir.it - Python, Zope & Plone Development

Plone: Move instance to another host without downtime

Sometimes it might be necessary to move a Plone instance to another host. This article describes how do this without almost any downtime.

At Inqbus we're hosting a lot of Plone sites. Therefor we use virtual machines. When sites within an instance grow, it might be necessary to add or extend some components, like adding more ZEO clients or caching (using Varnish or Squid). But what if the virtual machines don't have enough power to handle this? Then those Plone instances have to be migrated to another, more powerful machine.

The problem then is to do this without any downtime. Of course you first have to create a copy of the existing Plone instance on the new machine, create a snapshot backup of all the related data, and restore this data on the new machine. But what about the connected domains? The IP addresses differ (if you don't use one webserver that does all the domain handling). It can take up to several hours to update all the domains on the root DNS servers. But you want your sites online, with up to date data.

Nginx configuration: proxy_pass

We're using Nginx as webserver for several reasons (of course Apache does the job as well). So the following examples are taken from our Nginx config.

Imagine you have the following config on your actual server:

server {
listen ip-of-actual-server:80;
  server_name your-domain.com;
  location / {
    proxy_pass http://127.0.0.1:8080/VirtualHostBase/http/your-domain.com:80/your-site/VirtualHostRoot/;
  }
}

On your new server, add the same config. The only thing that changes is the IP address:

server {
  listen ip-of-new-server:80;
  server_name your-domain.com;
  location / {
    proxy_pass http://127.0.0.1:8080/VirtualHostBase/http/your-domain.com:80/your-site/VirtualHostRoot/;
  }
}

Now, on your old server, adjust the config for your domain. Use the proxy_pass directive to point to your new server. The important part is the proxy_set_header directive.

server {
listen ip-of-actual-server:80;
server_name your-domain.com;
location / {
proxy_pass          http://your-new-server;
proxy_redirect      off;
proxy_set_header    Host $host;
}
}

That's it. Now you can move your instance, restart Nginx and update your DNS settings. It's save to remove the config on the old server after about one week. Then all the root DNS servers should be updated and have the new IP address for your domain.

RhodeCode: remove outdated session data

RhodeCode uses Beaker for session management. By default the Beaker backend is set to file storage. Cleaning up those files by time is necessary.

We use RhodeCode for our internal Mercurial repositories. It's great for what it does: user and group management, repository groups, etc.

But when I looked at our server today I was kind of shocked about the inode usage on one of our partitions. Checking out the Munin graphs I realized that it had something todo with our repos. But the repository folder wasn't that big, only about 160MB. So I was looking for the inode usage:

$ find /opt/repositories/ -type f | wc -l
14110 

That's not too much. Also because df shows a usage of about 500.000 inodes. Ok, checking the RhodeCode directory:

$ find /opt/rhodecode/ -type f | wc -l
483992 

Yes! But wait. Where does all the files come from?

RhodeCode uses Beaker for session management. And by default, file storage is used. This isn't that bad, but from the Beaker documentation you can see that it could be:

Beaker does not automatically delete expired or old cookies on any of its back-ends. This task is left up to the developer based on how sessions are being used, and on what back-end.
The database backend records the last accessed time as a column in the database so a script could be run to delete session rows in the database that haven’t been used in a long time.

So for the file backend that means that all the session files are kept. Forever!

But help is here! You can remove outdated session files with a simple command:

$ find /opt/rhodecode/data/sessions -mtime +3 -exec rm {} \;

This removes all the session files older than 3 days. The result is amazing:

$ find /opt/rhodecode/data/session/ -type f | wc -l
4528

lf you're lazy like me, simply add a cronjob and let your system do the rest:

# m h  dom mon dow   command
0 1 1 * * find /opt/rhodecode/apps/propertyshelf/data/sessions -type f -mtime +3 -exec rm {} \;

This removes old session files on every 1st of a month at 1:00am.

Buildout fails on Mac with Xcode 4 installed

Installing Apple's Xcode 4 can cause some trouble when compiling Zope packages via buildout. This article shows the solution for this problem.

Xcode4 dropped PPC support. After upgrading to Xcode 4 I realized some strange behaviors when running buildout (especially when creating a new Zope buildout where things have to be compiled).

I got some errors like this:

compilation terminated.
lipo: can't open input file: /var/folders/8q/8q7FGaB3FHq8zCFUe4wSVk+++TI/-Tmp-//ccfKEKaS.out (No such file or directory)
error: command 'gcc-4.2' failed with exit status 1

The solution to solve this is pretty simple. Just add this line to your .profile in your home directory:

export ARCHFLAGS="-arch i386 -arch x86_64"

That's it.

collective.prettyphoto for Plone

Over the past few days I had some time to finish what was planned for so long: integrate prettyPhoto (written by Stéphane Caron) into Plone. Here it is...

Introduction

prettyPhoto is a jQuery based lightbox clone. Not only does it support images, it also add support for videos, flash, YouTube, iFrames. It's a full blown media lightbox. The setup is easy and quick, plus the script is compatible in every major browser.

The original implementation by Stéphane Caron can be found here: http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/

This plugin has been tested and is known to work in the following browsers

  • Firefox 2.0+
  • Safari 3.1.1+
  • Opera 9+
  • Internet Explorer 6.0+

collective.prettyphoto is an implementation of prettyPhoto for Plone.

Installing

collective.prettyphoto is availabe at PyPI. It requires Plone 3.x or later (tested on 3.3.3).

Installing without buildout

Install this package in either your system path packages or in the lib/python directory of your Zope instance. You can do this using either easy_install or via the setup.py script.

Installing with buildout

If you are using buildout to manage your instance installing collective.prettyphoto is even simpler. You can install collective.prettyphoto by adding it to the eggs line for your instance:

[instance]
eggs = collective.prettyphoto

After updating the configuration you need to run the ''bin/buildout'', which will take care of updating your system.

Usage

collective.prettyphoto adds a new view for Topics, Folders and Large Plone Folders: Thumbnail view (prettyPhoto).

To use prettyPhoto for inline elements just add prettyPhoto from the styles menu (Kupu and TinyMCE) to the link.

Configuration

collective.prettyphoto can be customized via property sheet (go to ZMI, portal_properties, prettyphoto_properties).

  • theme:
    • dark_rounded
    • dark_square
    • facebook
    • light_rounded (default)
    • light_square
  • speed:
    • fast
    • normal (default)
    • slow
  • opacity: value from 0.0 to 1.0 (default: 0.80)
  • show_title: show the title for images? (default: True)
  • counter_sep: the separator for the gallery counter 1 "of" 2 (default: "/")
  • autoplay: automatically start videos? (default: True)
  • iframe_width: the width of the iframe (must be percantage, default: 75%)
  • iframe_height: the height of the iframe (must be percantage, default: 75%)

Copyright and Credits

prettyPhoto is developed by Stephane Caron (http://www.no-margin-for-errors.com) and is licensed under Creative Commons Attribution 2.5.

Author of collective.prettyphoto: Thomas Massmann (thomas.massmann@inqbus.de, http://www.inqbus-hosting.de).

How to handle internal and external links in Plone

In plone it is possible to mark external links. With a bit of CSS these can be styled separatly. But you might struggle with internal links if you use other editors then Kupu.

With option "Mark external links" enabled in site setup (works with every editor)

<span class="link-external"><a href="...">...</a></span>

Ok, we have external links, but no internal. And putting a span tag around every a tag is kind of stupid in my eyes.

Editor handling

Kupu

<a class="external-link" href="...">...</a>
<a class="internal-link" href="...">...</a>

TinyMCE

<a href="...">...</a>

As long as TinyMCE does not add classes to internal and external links (why not?), we have to give every link a class to get this working properly. Add this to TinyMCE styles config to make it work:

Internal Link|a|internal-link
External Link|a|external-link

Because Kupu will be replaced by TinyMCE in Plone 4, I hope that the link handling will make it into a future release.

CSS Styling

Now we have the classes we need to style our links:

a.internal-link {
    background: url(internal-link.png) no-repeat left center;
    padding-left: 15px;
}

a.external-link {
    background: url(link_icon.gif) no-repeat left center;
    padding-left: 15px;
}

a[href$=".pdf"] {
    background: url(pdf.png) no-repeat left center;
    padding-left: 20px;
}

Upate

With TinyMCE 1.1rc3 this issue has been fixed. There are now classes for internal links and mail links.

blog comments powered by Disqus