Policies/Web Applications

From Mandriva Community Wiki

Jump to: navigation, search
Packaging policy extension for web applications

Contents


The following tries to address some common issues faced when dealing with packaging web applications.

[edit] Files location

Most web applications use a simple single-directory setup, partly for multi-platform compatibility reasons, and partly for usablity in an environment without shell access, such as web hosting. Since we don't have such constraints when producing packages for Linux, we should try to ensure an FHS-compliant setup, for the following reasons:

  • security: it's ridiculous to install sensitive files under a web root, and to deny its access through the web server configuration, when just installing it somewhere outside the web root would be enough
  • flexibility: FHS compliance makes it easier to reuse the same setup, notably between different virtual hosts, without duplicating the whole application
  • maintainability: centralized configuration in a standard location is far easier to handle than a distributed configuration in non-standard locations intermixed with content
  • consistency: all other packaged applications follow the same logic, and treating some applications differently just because they have contraints when run under different operating systems or configurations would be inconsistent

There are various strategies that can achieve this objective. The simplest strategy is to use symlinks between real file locations and the place where the application expects to find them. Another strategy, cleaner but more difficult to maintain through successive upstream releases, involves patching (unless the patch could be pushed upstream). In any case, using a different setup than the default one should be explicitly documented in the package documentation.

Here are the various groups of files for a sample package called foo.

[edit] web files

These are the only files that are supposed to be retrieved by the client: web pages, stylesheets, images, etc. They go in /var/www/foo, and are owned by root user and root group.

[edit] variable files

These are the files that are susceptible to change during the application's lifetime. They go in /var/lib/foo. If they are supposed to be editable by the application directly from the web interface, they should be owned by apache user and apache group. If they are just read from the interface, and modified by other means, such as cron tasks, they could safely be owned by another user and group, typically root:root.

[edit] log files

They go to /var/log/foo, and are owned by apache user and apache group. Caution, default msec rules change all files directly under /var/log to the root user and the root group starting from level 3, so even a single log file should have its own directory to avoid breaking.

[edit] config files

These go in /etc/foo or /etc directly and are owned by the root user and the root group. Files containing sensitive information, such as passwords, should be owned by apache group and should not be world-readable. Some applications have a web configuration interface making it mandatory to change the file owner to apache also.

[edit] other files

These go in /usr/share/foo for arch-independent files or /usr/lib/foo for arch-dependent ones and are owned by the root user and the root group.

[edit] Apache integration

The apache package setup has been cleaned after 10.2. Therefore, new setup applies starting from the 2.0.54-1mdk release.

[edit] configuration

As before, web applications often have the constraint of not being able to access the web server configuration, and thus having to rely on per-directory configuration using .htaccess files. Once again, we don't have such constraints, especially since once web root is cleaned, no denied access configuration should be needed. For this reason, no .htaccess configuration files are allowed, and any apache configuration should be handled in a single configuration file that will be dynamically included by apache at startup. This offers several advantages:

  • centralized configuration is easier to maintain
  • parsing the configuration once during start up is more efficient than parsing every directory for each request
  • msec is able to enforce perm and ownership easily

This file should be installed in /etc/httpd/conf/webapps.d/foo.conf, owned by the root user and the root group. It should contain an alias, as the application web root /var/www/foo is not under default server web root /var/www/html. It should also contain any necessary configuration directives, as previously specified in the .htaccess files. The genconfig script provided below automatically ensures this aggregation if called with rpm build root as an argument: genconfig rpm/tmp/foo.

Starting with release 1.23, rpm-mandriva-setup defines a convenient macro %_webappconfdir for apache configuration file location is defined by rpm macro. Here is a safe way to use it:

BuildRequires:  rpm-mandriva-setup >= 1.23
...

# apache configuration
install -d -m 755 %{buildroot}%{_webappconfdir}
cat > %{buildroot}%{_webappconfdir}/%{name}.conf <<EOF
...
EOF

...

%files
%config(noreplace) %{_webappconfdir}/%{name}.conf

[edit] installation/desinstallation

Apache configuration reloading is not trivial: reloading is quicker than reloading, but ir will not take care of new files. Moreover, you don't want to issue two reload commands when you just update one package. And finally, you don't want error messages if apache was not running at all.

Starting with release 0.16, rpm-helper provides convenient rpm macros and scriptlets to handle everything. Here is a safe way to use them:

Requires(post):   rpm-helper >= 0.16
Requires(postun): rpm-helper >= 0.16
BuildRequires:    rpm-helper >= 0.16

%post
%_post_webapp

%postun
%_postun_webapp

[edit] dependencies

Standard CGI applications should just require apache, with an additional version requirement if you hardcoded the configuration file location. CGI apps are supposed to be thread-safe, so no need to specifically prefork apache core.

Applications requiring an embedded interpretor should just require the correct apache module, that will take care of requiring other apache packages:

  • php applications should require apache-mod_php
  • mod_perl applications should require apache-mod_perl

Once again, an additional version requirement is needed if you hardcoded the configuration file location

[edit] Backportability

The use of rpm macros and scriptlet defined in other packages doesn't prevent backportability:

  • until mandriva 10.2 (included), just backport rpm-helper and rpm-mandriva-setup also
  • in earlier release, you'll have to either define those macros manually in /etc/rpm/macros, or pass them on the command line with --define switch

[edit] genconfig

#!/usr/bin/perl
use File::Find;

my $buildroot = $ARGV[0];

find(\&callback, $buildroot);

sub callback {
        return unless $_ eq '.htaccess';

        open(HTACCESS, $_) or die "Can't open $_: $!";
        my $dir = $File::Find::dir;
        $dir =~ s/$buildroot//;
        print "<Directory \"$dir\">\n";
        while (<HTACCESS>) {
                print "\t$_";
        }
        print "</Directory>\n";
        close(HTACCESS);
}
Personal tools