NGINX Unit

Zope§

To run apps built with the Zope web framework using Unit:

  1. Install Unit with a Python 3.6+ language module.

  2. Install Zope. Here, we do this at /path/to/app/; use a real path in your configuration.

    First, install Zope’s core files, for example:

    $ pip install -U pip wheel zc.buildout
    $ cd /path/to/app/
    $ wget https://pypi.org/packages/source/Z/Zope/Zope-A.B.C.tar.gz
    $ tar xfvz Zope-A.B.C.tar.gz --strip-components=1
    $ buildout
    

    Next, add a new configuration file named /path/to/app/wsgi.cfg:

    [buildout]
    extends =
        buildout.cfg
    
    parts +=
        wsgi.py
    
    [wsgi.py]
    recipe = plone.recipe.zope2instance
    user = admin:admin
    zodb-temporary-storage = off
    eggs =
    scripts =
    initialization =
        from Zope2.Startup.run import make_wsgi_app
        wsgiapp = make_wsgi_app({}, '${buildout:parts-directory}/wsgi.py/etc/zope.conf')
        def application(*args, **kwargs):return wsgiapp(*args, **kwargs)
    

    It creates a new Zope instance. The part’s name must end with .py for the resulting instance script to be recognized as a Python module; the initialization option defines a WSGI entry point.

    Rerun Buildout, feeding it the new configuration file:

    $ buildout -c wsgi.cfg
    
          ...
          Installing wsgi.py.
          Generated script '/path/to/app/bin/wsgi.py'.
    

    Thus created, the instance script can be used with Unit.

    Run the following command so Unit can access the application directory:

    # chown -R unit:unit /path/to/app/
    

    Note

    The unit:unit user-group pair is available only with official packages, Docker images, and some third-party repos. Otherwise, account names may differ; run the ps aux | grep unitd command to be sure.

    For further details, including permissions, see the security checklist.

    Last, prepare the Zope configuration for Unit (use a real value for path):

    {
        "listeners": {
            "*:80": {
                "pass": "applications/zope"
            }
        },
    
        "applications": {
            "zope": {
                "type": "python 3",
                "path": "/path/to/app/",
                "module": "bin.wsgi"
            }
        }
    }
    

    Create a virtual environment to install Zope’s PIP package:

    $ cd /path/to/app/
    $ python3 --version
          Python 3.Y.Z
    $ python3 -m venv venv
    $ source venv/bin/activate
    $ pip install 'zope[wsgi]'
    $ deactivate
    

    Warning

    Create your virtual environment with a Python version that matches the language module from Step 1 up to the minor number (3.Y in this example). Also, the app type in Unit configuration must resolve to a similarly matching version; Unit doesn’t infer it from the environment.

    After installation, create your Zope instance:

    $ venv/bin/mkwsgiinstance -d instance
    

    To run the instance on Unit, create a WSGI entry point:

    from pathlib import Path
    from Zope2.Startup.run import make_wsgi_app
    
    wsgiapp = make_wsgi_app({}, str(Path(__file__).parent / 'etc/zope.conf'))
    def application(*args, **kwargs):return wsgiapp(*args, **kwargs)
    

    Save the script as wsgi.py in the instance home directory (here, it’s /path/to/app/instance/).

    Run the following command so Unit can access the application directory:

    # chown -R unit:unit /path/to/app/
    

    Note

    The unit:unit user-group pair is available only with official packages, Docker images, and some third-party repos. Otherwise, account names may differ; run the ps aux | grep unitd command to be sure.

    For further details, including permissions, see the security checklist.

    Last, prepare the Zope configuration for Unit (use real values for path and home):

    {
        "listeners": {
            "*:80": {
                "pass": "applications/zope"
            }
        },
    
        "applications": {
            "zope": {
                "type": "python 3.Y",
                "path": "/path/to/app/instance/",
                "home": "/path/to/app/venv/",
                "module": "wsgi"
            }
        }
    }
    
  3. Upload the updated configuration. Assuming the JSON above was added to config.json:

    # curl -X PUT --data-binary @config.json --unix-socket \
           /path/to/control.unit.sock http://localhost/config/
    

    Note

    The control socket path may vary; run unitd -h or see Startup and Shutdown for details.

    After a successful update, your Zope instance should be available on the listener’s IP address and port:

    $ curl http://localhost
    
          <!DOCTYPE html>
          <html>
            <head>
          <base href="http://localhost/" />
    
              <title>Auto-generated default page</title>
              <meta charset="utf-8" />
            </head>
            <body>
    
              <h2>Zope
                  Auto-generated default page</h2>
    
              This is Page Template <em>index_html</em>.
            </body>
          </html>