Docs Configuration » History » Revision 60
Revision 59 (gstrauss, 2023-11-18 09:19) → Revision 60/61 (gstrauss, 2023-11-19 12:25)
{{>toc}} h1. Configuration syntax h2. Overview lighttpd configuration syntax is basic and many configurations can be expressed simply in the configuration syntax. However, the configuration syntax is not a full programming language, nor does it pretend to be. For any complex logic, it is recommended to create a script which produces lighttpd configuration syntax as output. h2. BNF like notation of the basic syntax <pre> option : NAME = VALUE merge : NAME += VALUE replace : NAME := VALUE (replace/overwrite earlier value) (since 1.4.46) NAME : modulename.key VALUE : ( <string> | <integer> | <boolean> | <array> | VALUE [ + VALUE ]*) <string> : "text" <integer>: digit+ <boolean>: ( "enable" | "disable" ) <array> : "(" [ <string> "=>" ] <value> [, [ <string> "=>" ] <value> ]* ")" INCLUDE : "include" VALUE INCLUDE_SHELL : "include_shell" STRING_VALUE </pre> *Example* <pre> # default document-root server.document-root = "/var/www/example.org/pages/" # TCP port server.port = 80 # selecting modules server.modules = ( "mod_access", "mod_rewrite" ) # variables, computed when config is read. var.mymodule = "foo" server.modules += ( "mod_" + var.mymodule ) # var.PID is initialised to the pid of lighttpd before config is parsed # include, relative to dirname of main config file include "mime.types.conf" # read configuration from output of a command include_shell "/usr/local/bin/custom-create-mime.conf.pl /etc/mime.types" </pre> h2. Conditional Configuration Most options can be configured conditionally by using the following syntax (including nesting). <pre> <field> <operator> <value> { # (since 1.4.74, may be preceded by literal "if") ... <field> <operator> <value> { ... nesting: match only when parent match } } else <field> <operator> <value> { # (since 1.4.74, "elif", "elsif", "elseif", or "else if" "elseif" are also accepted in lieu of "else") ... the "elseif" block } else { # (since 1.4.46) ... the "else" block } </pre> where <field> is one of one of the following: |_.Field name|_.Description| |$REQUEST_HEADER["..."]|match on arbitrary HTTP request header (case-insensitive) (since 1.4.46)| |$HTTP["request-method"]|match on the request method (since 1.4.19)| |$HTTP["scheme"]|match on the scheme used by the incoming connection. This is either "http" or "https" (since 1.4.19)| |$HTTP["host"]|match on host| |$HTTP["url"]|match on url path (not including host or query-string)| |$HTTP["querystring"]|match on querystring, e.g. after the ? in this type url: index.php?module=images...| |$HTTP["remoteip"]|match on the remote IP address or a remote network @==@ or @!=@ CIDR mask (works with IPv6 since 1.4.40)| |$HTTP["cookie"]|(subsumed by $REQUEST_HEADER["Cookie"] since 1.4.46) match on Cookie| |$HTTP["useragent"]|(subsumed by $REQUEST_HEADER["User-Agent"] since 1.4.46) match on User-Agent| |$HTTP["language"]|(subsumed by $REQUEST_HEADER["Accept-Language"] since 1.4.46) (since 1.4.21) match on Accept-Language| |$HTTP["referer"]|(subsumed by $REQUEST_HEADER["Referer"] since 1.4.46) match on Referer| |$SERVER["socket"]|match on socket (local address, not remote address). Value must be on the format "ip:port" -- where ip is an IP address(optional) and port is a port number -- or must be unix domain path. If IP address is omitted, then use INADDR_ANY (0.0.0.0), unless @server.use-ipv6 = "enable"@ _inside this block_, in which case use in6addr_any ([::]). Setting this directive with @==@ also instructs lighttpd to bind to this socket and listen for requests. $SERVER["socket"] is valid in global scope; placing $SERVER["socket"] inside other conditions may have undesirable results (and would be rejected if not for historic (mis)use).| {{collapse(.) |$PHYSICAL["path"]|(Introduced in version 1.5.0 (note: abandoned; never released)) - match on the mapped physical path of the file / cgi script to be served.| |$PHYSICAL["existing-path"]|(Introduced in version 1.5.0 (note: abandoned; never released)) - match on the mapped physical path of the file / cgi script to be served only if such a file exists on the local filesystem.| }} <operator> is one of: |_.Operator|_.Value| |==|string equal match| |!=|string not equal match| |=~|perl style regular expression match| |!~|perl style regular expression not match| |=^|string prefix match (since 1.4.65)| |=$|string suffix match (since 1.4.65)| and <value> is a quoted ("") string, either a string literal or "regular expression":https://www.regular-expressions.info/. *Example:* <pre> # disable directory-listings for /download/* dir-listing.activate = "enable" $HTTP["url"] =~ "^/download/" { dir-listing.activate = "disable" } # handle virtual hosting # map all domains of a top-level-domain to a single document-root $HTTP["host"] =~ "(^|\.)example\.org$" { server.document-root = "/var/www/htdocs/example.org/pages/" } # multiple sockets $SERVER["socket"] == "127.0.0.1:81" { server.document-root = "..." } $SERVER["socket"] == "127.0.0.1:443" { ssl.pemfile = "/var/www/certs/localhost.pem" ssl.engine = "enable" server.document-root = "/var/www/htdocs/secure.example.org/pages/" } # deny access for all googlebot $HTTP["useragent"] =~ "Google" { url.access-deny = ( "" ) } # deny access for all image stealers (anti-hotlinking for images) $HTTP["referer"] !~ "^($|http://www\.example\.org)" { url.access-deny = ( ".jpg", ".jpeg", ".png" ) } # deny the access to www.example.org to all user which # are not in the 10.0.0.0/8 network $HTTP["host"] == "www.example.org" { $HTTP["remoteip"] != "10.0.0.0/8" { url.access-deny = ( "" ) } } # Allow only 200.19.1.5 and 210.45.2.7 to # have access to www.example.org/admin/ $HTTP["host"] == "www.example.org" { #!~ is a perl style regular expression not match $HTTP["remoteip"] !~ "^(200\.19\.1\.5|210\.45\.2\.7)$" { $HTTP["url"] =~ "^/admin/" { url.access-deny = ( "" ) } } } </pre> h2. Conditional Configuration Merging lighttpd configuration is parsed and optimized at startup. The configuration is static after startup. At runtime, dynamic configuration selection is limited to matching the lighttpd condition syntax and to matching the static configuration, e.g. matching against static lists parsed at startup. Put another way, various configurations objects are static after startup, including backend server configuration. When parsing requests at runtime, a backend server may be selected, but the configuration of the backend is static after startup. Different sections of the configuration +are not+ merged dynamically at runtime. For a given option, the value of that option +in the last matching condition+ is the value that is applied. Within the same lighttpd condition @{@ ... @}@ and same nesting level of @{@ ... @}@, you can use @+=@, which is parsed at startup, but @+=@ +does not apply+ across different lighttpd conditions @{@ ... @}@ or different nesting levels @{@ ... @}@ within a condition. h2. Troubleshooting If you're not running on the default port, $HTTP["host"] will have the port appended to it, so "regular expressions":https://www.regular-expressions.info/ ending in $ (without allowing for a port) won't match. To match with or without a port, change <pre>"(^|\.)example\.org$"</pre> to <pre>"(^|\.)example\.org(\:[0-9]*)?$"</pre> Note that some earlier versions of lighttpd do not support the full configuration file syntax listed here. In particular, some versions do not support "var." variables, appending with "+=", nested conditionals, or "else" blocks. The names of some options (for example, "server.dir-listing") have also changed (i.e. to "dir-listing.activate") between versions of lighttpd. If you're having trouble configuring lighttpd, consider using the "-t" or "-p" options to debug your configuration. Note that some earlier versions of lighttpd not support the "-t" or "-p" options. h2. Advanced usage Check the blog: http://blog.lighttpd.net/articles/2005/05/07/advanced-configuration-in-up-upcoming-1-4-x h2. Using variables You can set your own variables in the configuration to simplify your config. Note: Variables are expanded at startup when the configuration is parsed; variables +are not+ expanded at runtime for each request. <pre> var.basedir = "/home/www/servers/" $HTTP["host"] == "www.example.org" { server.name = "www.example.org" include "incl-base.conf" } </pre> In incl-base.conf: <pre> server.document-root = basedir + server.name + "/pages/" accesslog.filename = basedir + server.name + "/logs/access.log" </pre> You can also use environment variables or the default variables var.PID and var.CWD. <pre> var.basedir = env.LIGHTTPDBASE $HTTP["host"] == "www.example.org" { server.name = "www.example.org" include "incl-base.conf" include "incl-fastcgi.conf" } </pre> In incl-fastcgi.conf: <pre> fastcgi.server = ( ... => (( "socket" => basedir + server.name + "/tmp/fastcgi-" + PID + ".sock" )) ) </pre> Or like the lighttpd script for rails does: <pre> var.basedir = var.CWD server.document-root = basedir + "/public/" </pre> Some useful things that can NOT be done in lighttpd config (you need to create a script in a real programming language and then use include_shell): <pre> # testing if a variable has been set is NOT possible # INVALID var.not_sure_if_it_exists == undefined { ... set to default value ... } # INVALID # removing from arrays is NOT possible # INVALID server.modules -= ( "mod_idontwantyou" ) # INVALID </pre> h2. Global context <pre> global { ... } </pre> You don't need it in the main configuration file. But you might have difficulty setting a server wide configuration inside a included-file from conditionals. *Example* In lighttpd.conf: <pre> server.modules = () $HTTP["host"] == "www.example.org" { include "incl-php.conf" } </pre> In incl-php.conf: <pre> global { server.modules += ("mod_fastcgi") static-file.exclude-extensions += (".php") } fastcgi.server = "..." </pre> h2. Options All Configuration Options can be found at: [[lighttpd:Docs_ConfigurationOptions|Configuration Options]]