Differences between revisions 25 and 26
Revision 25 as of 2013-09-17 18:12:44
Size: 12180
Editor: ?MathieuParent
Comment: fix postinst with "set -e"
Revision 26 as of 2014-05-10 10:10:13
Size: 12179
Comment: Remove wrong single character in script template
Deletions are marked like this. Additions are marked like this.
Line 175: Line 175:
r fi                 fi

Packaging Web Applications and Modules for Apache HTTPD 2.4 in Jessie

This Wiki page is intended to give practical hands on experience how to package modules and web applications in Debian. Jessie is supposed to ship Apache HTTP 2.4 which requires a major rework of reverse dependencies in Debian.

General instructions

Generally, instructions for packaging modules and are documented in the PACKAGING file included within the apache2 binary package. The latest revision is also available in our version control system under

http://anonscm.debian.org/gitweb/?p=pkg-apache/apache2.git;a=blob;f=debian/PACKAGING;hb=master

Please refer there for the reference documentation. This Wiki page is meant as a practical hands-on tutorial extended by some more explanations. It does not replace the packaging hints.

Upgrading notes

  • Modules must be compiled and linked against the new apache2 binary. ABIs did change. Your module packages from Wheezy won't work with Jessie's Apache2 web server. They either need to be recompiled or removed.

  • Modules must change their build-dependencies (to apache2-dev) and dependencies for binary packages (to apache2-api-20120211 (for the time being!). Check our current virtual Provides in the apache2-bin package.)

  • Web applications must move their configuration files from /etc/apache2/conf.d/yourpackage to /etc/apache2/conf-available/yourpackage at very least.

  • Web application should reconsider their dependencies.
  • Module maintainers should check if their module is obsoleted by one of the new core modules.

Maintainer scripts

Aside of changed dependencies, the biggest change involves maintainer scripts. We intend to consolidate behavior of maintainer scripts, to make it predictable and configurable how modules and web applications behave after the installation.

To achieve this, you should not decide yourself when and if to enable a given piece of configuration or whether or not to restart the web server after installation of your configuration snippet. Likewise, do not decide yourself whether or not to enable a particular module you install in your package.

Instead, call our helper scripts which will behave in a predictable and configurable behavior. In the end, we want to let the site administrator to decide how modules and web applications should behave. Thus, see our documentation how to use apache2-maintscript-helper.

Packaging Modules and Web Applications

Below you find some simple tutorials to get started to build packages which shall depend on apache2 in one or another way.

Modules

Modules should really use dh_apache2 to get things right. It makes packaging Apache2 modules easy, otherwise you need to be especially careful to get dependencies right. Take special care not to depend' on apache2 or apache2-bin. Your module binary package must depend on the virtual API version package we provide instead. In a nutshell, this is how to create a module package:

  • Call the binary package libapache2-mod-yourmodule.
  • Build depend on dh-apache2 and apache2-dev. For the time being dh-apache2 is a virtual package provided by the latter. This may change in future.

  • Add ${misc:Depends} to your "Depends" line in debian/control.

  • Configure and build the module as you are used to. Starting with apache2 2.4 we provide both, apxs and apxs2 again. You do not need to worry about using the correct helper file, there is just one left these days. Let's presume the resulting module object is located in src/yourmodule/mod_yourmodule.so and not being installed by upstream's install target.

  • Create a module module.load file in debian/yourmodule.load. Refer to our packaging guide to get detailed instructions what to put into this file. In particular read there, how to declare module dependencies. Generally speaking, in most cases the following line will do the job:

    • LoadModule yourmodule_module /usr/lib/apache2/modules/mod_yourmodule.so

  • Create a dh_apache2 debhelper configuration file, e.g. called package.apache2 with the following contents:

    • mod src/yourmodule/mod_yourmodule.so

      mod debian/yourmodule.load

  • Finally make sure dh_apache2 is actually invoked by changing relevant parts of your debian/rules file to:

    • %:

          dh $@ --with apache2

Web applications

If you are upgrading your package from Wheezy you probably need to move your configuration files from /etc/apache2/conf.d/yourpackage to /etc/apache2/conf-available/yourpackage.conf. You can use dpkg-maintscript-helper(1) to move configuration files properly. It supports a mv_conffile function you can call. If you are using debhelper, consult dh_installdeb(1) how to automate interaction with dpkg-maintscript-helper.

You can, but you don't need to install your configuration files yourself. It is suggested to use dh_apache2 instead by build-depending on dh-apache2. Don't worry if this pulls apache2-dev for now, dh_apache2 should be shipped within the regular debhelper at some point if everything goes well.

Do not interact with Apache wrapper scripts in your maintainer scripts directly. It can be complex and complicated to decide when to enable a particular piece of configuration. You should use apache2-maintscript-helper instead. Doing that you do not need to worry whether and when to enable a given configuration. If you are using dh_apache2 it does the job for you. Be careful when writing your own maintainer scripts, web applications generally should not depend unconditionally on apache2. Thus, neither our maintscript-helper nor our a2enmod and friends tool will be available at runtime.

Web Applications in a nutshell (without dh_apache2)

  • Make your package being compliant to the Debian policy manual § 11.5.

  • Install your application, chances are it ends up in /usr/share/yourapplication

  • Declare your relationship against the Apache2 web server. Do not depend on it unconditionally. Instead do something like:

    • `Recommends: apache2 | other-webservers-you-want-to-support | httpd
  • Make your Apache configuration file, e.g. in your source package as debian/yourapplication.conf. It should look like this:

    • Alias /yourapplication /usr/share/yourapplication

      <Directory /usr/share/yourapplication>

      • ..

      </Directory>

  • Install the configuration file to /etc/apache2/conf-available/yourapplication.conf.

  • In your postinst maintainer script invoke the enconf handler on fresh installations. Do not omit the conditional unless your package dependencies guarantee apache2 is installed (it shouldn't).

    if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then
        . /usr/share/apache2/apache2-maintscript-helper
        apache2_invoke enconf yourapplication.conf || exit $?
    fi
  • Likewise, in postrm do upon purge and simple removals:

    if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then
        . /usr/share/apache2/apache2-maintscript-helper
        apache2_invoke disconf yourapplication.conf || exit $?
    fi

Web Applications in a nutshell (with dh_apache2)

  • Make your package being compliant to the Debian policy manual § 11.5.

  • Install your application, chances are it ends up in /usr/share/yourapplication

  • Build depend on dh-apache2

  • Add ${misc:Recommends} to your Recommends in debian/control.

  • Make your Apache configuration file, e.g. in your source package as debian/yourapplication.conf. It should look like this:

    • Alias /yourapplication /usr/share/yourapplication

      <Directory /usr/share/yourapplication>

      • ..

      </Directory>

  • Add a dh_apache2 debhelper configuration file to your source package (e.g. to debian/yourpackage.apache2) with the following contents

    • conf debian/yourapplication.conf optionally_other_webservers_you_support
  • Finally make sure dh_apache2 is actually invoked by changing relevant parts of your debian/rules file to:

    • %:

          dh $@ --with apache2

Making web applications compatible to both, Apache 2.2 and 2.4

It is possible to web applications to make them compatible to both, Apache 2.2 and Apache 2.4. That's useful until Apache 2.4 reaches Testing, or you want to support Wheezy backports of your shiny new upstream version of your web application.

Special must be taken when considering dependencies. Do depend or recommend on the apache2 web server package. Do not declare any package relation towards apache2.2-common. For the 2.2 package the dependency pulls apache2.2-common, for the 2.4 package it pulls the respective equivalent, too.

You can use dh_apache2 if you want, but you shouldn't rely on its maintainer script hooks as they won't cope with 2.2 packages. Aside, make your package as usual. If you are using dh_apache2, you may want to use this rules file:

%:
        dh $@  --with apache2

override_dh_apache2:
        dh_apache2 --noscripts

Chances are, your configuration needs some adaption whether it is running under Apache 2.2 or 2.4. In that case you can use the <?IfVersion> clause, for example like this:

<Directory /usr/share/foo>
  ...
  <IfVersion >= 2.3>
    Require local
  </IfVersion> 
  <IfVersion < 2.3>
     Order Deny,Allow
     Deny from all
     Allow from 127.0.0.1
  </IfVersion>   
</Directory>

But please note: You must have the "version" module enabled to do so. We did so for the Apache 2.2 version shipped in Wheezy, and Apache 2.4 (starting with version 2.4.1-3, which was available in Experimental only). Thus, typically no action from your side is required.

In your maintainer scripts, the bottom line is to detect whether the site administrator runs Apache 2.2 or 2.4. Moreover, you should note it's intentional that the link in postrm is always removed:

This is a postinst fragment (assuming your configuration file is foo/foo.conf):

if [ "$1" = "configure" ] ; then

        CONF="foo"
        COMMON_STATE=$(dpkg-query -f '${Status}' -W 'apache2.2-common' 2>/dev/null | awk '{print $3}' || true)

        if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then
                . /usr/share/apache2/apache2-maintscript-helper
                apache2_invoke enconf $CONF || exit $?
        elif [ "$COMMON_STATE" = "installed" ] || [ "$COMMON_STATE" = "unpacked" ] ; then
                if [ -d /etc/apache2/conf.d/ -a ! -L /etc/apache2/conf.d/$CONF.conf ]; then
                    ln -s ../conf-available/$CONF.conf /etc/apache2/conf.d/$CONF.conf
                fi
        fi

fi

And this the postrm counterpart:

if [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then

        CONF="foo"
        COMMON_STATE=$(dpkg-query -f '${Status}' -W 'apache2.2-common' 2>/dev/null | awk '{print $3}' || true)

        if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then
                . /usr/share/apache2/apache2-maintscript-helper
                apache2_invoke disconf $CONF || exit $?
        elif [ "$COMMON_STATE" = "installed" ] || [ "$COMMON_STATE" = "unpacked" ] ; then
                [ ! -L /etc/apache2/conf.d/$CONF.conf ] || rm /etc/apache2/conf.d/$CONF.conf
        fi

fi

Changes to modules' source code

Some hints are available at http://httpd.apache.org/docs/2.4/developer/new_api_2_4.html . Even if your module compiles and works without changes, you should at least add the APLOG_USE_MODULE statement described in that page to take advantage of per-module loglevel configuration.