MigratingFromApache » History » Revision 27
« Previous |
Revision 27/51
(diff)
| Next »
Anonymous, 2006-08-31 14:55
typo
= Migrating from Apache to lighty =
Configuration BasicsLighttpd is a great option as a replacement from apache. If you are seriously considering migrating read the documentation for the configuration file [wiki:Docs:Configuration]. The configuration syntax is initially the biggest learning curve, but you will learn of its flexibility once you become familiar with it. One of the most powerful features of the lighty configuration are '''conditionals'''. Lighty allows you to setup configuration options based on requests' conditions. Conditionals can be nested, so in term you can create complex but very effective configuration options. Conditionals are the key many solutions that people encounter when migrating. Here are some examples:
'''Problem''': I want to disable directory listing for directory /download:
Entry in Configuration file:
- Enable dir listing for all directories
dir-listing.activate = "enable"
- If the URL is like /download/ then disable dir-listing
$HTTP["url"] =~ "/download/" {
dir-listing.activate = "disable"
}
}}}
You must familiarize yourself with regular expressions to truly become familiar with conditionals. You will use conditionals in your configuration file for multitude of things. Authentication, URL Rewriting, Virtual Hosting, and many more. All the variables you can use in conditionals are listed here along with further explanation about the match operators [wiki:Docs:Configuration].
'''
Problem''': You want the status page to be available just for users from the local network:
Entry in configuration file:
{{{
$HTTP["remoteip"] == "10.0.0.0/8" {
status.status-url = "/server-status"
}
}}}
And here is a nested example.
'''Problem''': If the host is www2.example.org and the directory is /download enable directory listing:
{{{
$HTTP["host"] == "www2.example.org" {
server.document-root = "/var/www/servers/www2.example.org/pages/"
$HTTP["url"] =~ "^/download/" {
dir-listing.activate = "enable"
}
}}}
}
For more conditional examples read: * [wiki:HowToRedirectHttpToHttps] * [wiki:HowToRedirectWww] * [wiki:HowToAuthenticationFromMultipleFiles]
Basic Options
{{{
Options +FollowSymLinks
}}}
becomes
{{{
server.follow-symlink = "enable"
}}}
Accesslogs are written by mod_accesslog and support the same options in
{{{
accesslog.format = ...
}}}
as Apache.
If you need logfile rotation use one of two ways:
- [http://iain.cx/src/logrotate/ logrotate] as it is used in debian package
- [http://www.cronolog.org/ cronolog]
=== logrotate ===
If you don't use the debian package copy ./debian/lighttpd.logrotate to /etc/logrotate.d/
logrotate will send lighttpd a SIGHUP when it is time to rotate the logs and lighttpd will reopen the logs accordingly.
=== cronolog ===
With cronolog you pipe the accesslog to a pipe and let a external program handle the logfile writing:
{{{
accesslog.filename = "|/usr/sbin/cronolog /web/logs/%Y/%m/%d/access.log"
}}}
[http://www.lighttpd.net/documentation/rewrite.html mod_rewrite] is more trickier as the idea how it is handled is completely different.
First of all we always match on the full relative request-uri that is submitted by the user. That means we are always using the [QSA] (query string append) flag from [http://httpd.apache.org/docs/mod/mod_rewrite.html mod_rewrite in Apache].
This example is based on a problem from http://dir.onlinesearch.ws/ sent in by dbird@freenode.
{{{RewriteEngine On
RewriteBase /instadir/
RewriteCond %{REQUEST_FILENAME} -d
- Fix trailing slash problem
RewriteRule (.+[/])$ $1/ [R,L] - Do not try to treat the following resources as parameters to index.php
RewriteRule ^index.php.*$ - [L]
RewriteRule ^dmoz.css$ - [L]
RewriteRule ^admin[/]?.*$ - [L]
RewriteRule ^img[/]?.*$ - [L]
RewriteRule ^[/]{0,}(.*)$ index.php?area=browse&cat=$1 [QSA,L]
}}}
These rewrites want to rewrite everything that is not the index.php, dmoz.css, admin-interface or something from the image-directory to a parameter of the index.php page. The base directory for this match is ''/instadir/''.
{{{- for all URLs in /instadir/ that are not index.php, dmoz.css, admin or img, do ...
url.rewrite-once = ( "^/instadir/(?!index.php|dmoz.css|admin|img).*" => "$0",
"^/instadir/([^?]*)(?:\?(.*))?" => "/instadir/index.php?area=browse&cat=$1&$2")
}}}
The conditional is using regex-magic called [http://perlpod.com/5.9.1/pod/perlre.html#Extended%20Patterns zero-width negative look-ahead assertion] and is something from the advanced chapters of your [http://www.oreilly.com/catalog/regex/ regex book].
If you have 2 extensions assigned to the fastcgi handler in Apache like
{{{
AddType fastcgi-php .php .phtml
}}}
then you need two entries in the fastcgi.server config:
{{{
fastcgi.server = ( ".php" => (( "bin-path" => "/my/fastcgi-php",
"socket" => "/path/to/php.socket" )),
".phtml" => (( "socket" => "/path/to/php.socket-0" ))
)
}}}
The first entry will create the php-fcgi process and the second will reuse the same socket.
If you need to use PHP and Python in the same setup, just add two extensions:
{{{
fastcgi.server = ( ".php" => (( "bin-path" => "/my/fastcgi-php",
"socket" => "/path/to/php.socket" )),
".py" => (( "host" => "127.0.0.1", "port" => 3200 ))
)
}}}
For this setup python was spawned externally and is a waiting for requests at port 3200, localhost.
Directory !ForceType MigrationThere are several PHP packages and tutorials that use the apache !ForceType directive instead of mod_rewrite. They use it as a ''Search Engine'' friendly way to pass arguments as fake directories.
Let say you have this setup: * Your script is called ''news'' (note no php extension) * Your URLs look like /news/100/ (/news/''id of the news'') * Your script grabs $_GET!['PHP_SELF'] to determine the news id
and apache is configured with a Location or !LocationMatch entry like this:
{{{
<Location /news>
ForceType application/x-httpd-php
</Location>
}}}
The easiest way to migrate this is: * First setup PHP with lightty and make sure .php extension is working * Rename filename ''news'' to ''news.php'' * Use a lighttpd rewrite to replace the Forcetype entry
In lighttpd configuration file:
{{{
url.rewrite-once = ("^/news/.*" => "/news.php")
}}}
If your script is still not working, try to replace
$_GET!["PHP_SELF"] with $_GET!["REQUEST_URI"] You can find it usually at the top of the script.
PHP does not register PHP_SELF correctly when running in FastCGI.
I had a problem after migrating in duplicating my old Apache1.x + PHP setup had '''http://server.com/script/blah''' happily running ''script.php'' with arguments ''/blah''. This is really useful for easily making pretty URLs.
I couldn't see an easy solution to replicate this behaviour, or any entries in the docs here, so I decided to share my findings. Essentially there are two ways to go about replicating this in a semi-generic way so that you don't have to recode / rename your actual scripts.
If you were happy to rename you could probably make things work using lighttpd's forcetype support.
=== mod_rewrite solution ===
This is the one I picked because it's faster and seemed neater. Basically I added
{{{
include "mod_rewrite.conf"
}}}
... and then created that file with the contents ...
{{{
url.rewrite-repeat = ( "/script/(.*)" => "/script.php/$1" )
}}}
I guess you can also do this in a semi-generic way by naming each script:
{{{
url.rewrite-repeat = ( "/(?:script|script2|script3)/(.*)" => "/$1.php/$2" )
}}}
=== 404 handler solution ===
This is probably minutely slower but may be a better idea if you have more complex (ie: not pure regex) considerations in your URL rewriting. You can also replicate the regex above using PHP preg_match(). Just add:
{{{
server.error-handler-404 = "/404.php"
}}}
... then write your handler in that file.
Updated by Anonymous about 18 years ago · 27 revisions