cd /path/to/foswiki perl tools/extension_installer <NameOfExtension> installIf you have any problems, or if the extension isn't available in
configure
, then you can still install manually from the command-line. See https://foswiki.org/Support/ManuallyInstallingExtensions for more help.
/foswiki/bin/view
are actually handled by
the /foswiki/bin/virtualhosts
CGI script. Such script will play the role of
all the other scripts, but before serving each request it will setup the
appropriate environment for the virtual host being used.
virtualhosts
script is a regular CGI script, and as such it may exhibit
poor performance in sites with low computing power or high usage, just like
regular Foswiki. VirtualHostingContrib provides a FastCGI version of the
script.
To use it:
foswiki.fcgi
script provided by FastCGIEngineContrib with virtualhosts.fcgi
provided by VirtualHostingContrib. Setting | Meaning | Default value |
---|---|---|
VirtualHostsDir |
The directory in which you virtual hosts are stored | (empty) uses /path/to/foswiki/virtualhosts |
ServerAlias |
a mapping of aliases to real hostnames | |
DisabledServers |
a list of servers that are disabled temporarily even though there's a valid environment present in VirtualHostsDir |
$Foswiki::cfg{VirtualHostingContrib}{VirtualHostsDir}
, named after the
hostname it is intended to serve. Take the following example:
virtualhosts/ example.com/ ... mydomain.net/ ...In this case, there are two virtual hosts, one for the
example.com
domain and
other for the mydomain.net
domain.
Inside each virtual host directory, there are some directories that resemble
the ones in the main Foswiki installation:
Directory | Stores |
---|---|
data/ |
topic data |
pub/ |
attachments and other files that must be directly accessible by clients |
templates/ |
custom templates for this virtual host only |
working/ |
all sorts of temporary data |
VirtualHost.cfg
, which may contain Foswiki configuration variables. This way
you can have different settings for different virtual hosts. For example, you
can have some virtual hosts using the standard .htpasswd Foswiki user
management, and others using LDAP to authenticate users.
To create your local configuration, just create a file called VirtualHost.cfg
inside the virtual host directory. Inside the file, you use the $VirtualHost
hash the same way you would use $Foswiki::cfg
in the global Foswiki
configuration.
Example:
# disable FooPlugin in this virtual host $VirtualHost{Plugins}{FooPlugin}{Enabled} = 0; # use LDAP contrib in this virtual host $VirtualHost{PasswordManager} = 'Foswiki::Users::LdapPasswdUser'; $VirtualHost{UserMappingManager} = 'Foswiki::Users::LdapUserMapping'; # ...Note that all occurrances of
$Foswiki::cfg
in the virtual host
configuration will be replaced by $VirtualHost
. This way you can
still copy and paste configuration examples into your virtual host
configuration, but the virtual host configuration won't affect the global
configuration. A side effect of this is that you cannot do smart things such
as:
$Foswiki::cfg{AuthScripts} .= ',view';Warning: just like Foswiki's global configuration file
LocalSite.cfg
, virtual host configuration files are executed as Perl code.
So the system administrator must be completely sure of what to put in that
configuration file.
{VirtualHostingContrib}{VirtualHostsDir}
key.
Click the button, and enter the name of the desired hostname into the next
dialog, and select the desired options. (Don't enter the hostname into the directory field.) Other fields in
the dialog include:
Host template name
If you have one or more special virtual hosts named with a leading underscore (ie. _template
),
you can choose it in a drop-down box in the dialog. It will be copied
over to the new virtual host.
If there is no _template
virtual host or you chose the -none-
option, the
script will create the virtual host by copying files from the main Foswiki
data; this is suggested if your installation contains only virtual hosts, so
the main Foswiki data will always be clean. If the host supports symbolic
links, the System, and the _empty
and _default
template webs will be linked
rather than copied.
You can also create a _template
virtual host manually by copying the files from a Foswiki release tarball,
or by manually creating the data you want for every newly created virtual hosts.
If your installation is brand new and you plan to use the main Foswiki data
afterwards, you can also create the _template
virtual host using the script,
and that will freeze a copy of the main Foswiki data for new virtual hosts
created later. (caution If you are running from a git checkout using
pseudoinstall, any symbolic links in the webs will be preserved in the copy.)
Config template name
If you have a text file(s) named with a leading underscore (ie. _template.conf
)
in your virtual hosts directory, you can chose the template config name in the
dialog.
When you create a virtual host for example.com you'll also get a
example.com.conf
file which is copied from the selected _template.conf
file,
All occurrences of %VIRTUALHOST%
will be replaced by the
virtual host name (example.com
in this example). Note that
VirtualHostingContrib does not care about the contents of the file, it just
takes the content of _template.conf
, replaces all occurrences of
%VIRTUALHOST% by the virtual host name.
Caution: The config file must be an executable perl file following the rules
of the LocalSite.cfg, and as described above in VirtualHostingContrib.
Create .htpasswd file
By default, a new .htpasswd
file will be created in the virtual hosts's data
directory. If you un-check the checkbox and bypass creation of .htpasswd,
registration will be disabled in the new virtual host.
$Foswiki::cfg{SystemWebName}
$Foswiki::cfg{UsersWebName}
$Foswiki::cfg{SandboxWebName}
$Foswiki::cfg{TrashWebName}
virtualhost.conf
must be
used.
tools/configure
CreateVHost
wizard can be run from the CLI as well. The arguments are:
Parameter | Description | default | Example |
---|---|---|---|
name |
virtual hostname to create | (required) | -args name=foo.mysite.com |
createpasswd |
Create the .htpasswd file. |
no password file created | -args createpasswd=1 |
template |
Template host to copy | host will be copied from master webs | -args template=_templateweb |
templatecfg |
Template file to copy into configuration | no config created | -args templatecfg=_template.conf |
sudo -u www-data tools/configure -wizard CreateVHost -method create_vhost_2 -args name=foo.site.com -args createpasswd=1 sudo -u www-data tools/configure -wizard CreateVHost -method create_vhost_2 -args name=foo2.site.com -args template=_template templatecfg=_template.conf
DisabledServers
. This
is a comma-separated list of those hosts that are temporarily inactive and won't
be served anymore until you either remove it from the DisabledServers
list again or remove the files of the virtual host permanently.
To remove a virtual host, just remove the its files. If you are removing the
virtual host for example.com
, and your virtual hosts are stored in
/var/lib/foswiki/virtualhosts (see VirtualHostingContrib), then it is enough to remove
the /var/lib/foswiki/virtualhosts/example.com
directory, plus any webserver
configuration you have for that virtual host.
To rename a virtual host, you just have to rename it's directory, and if it's
the case, change the configuration files accordingly. Beware that after
renaming a virtual host its data will no longer be available at the old
domain name.
To create an alias name for a virtual host, add a name mapping to the
ServeraAlias
hash of your global configuration in LocalSite.cfg
. For
instance use the following to access the example.com
domain using the
a different network interface as well:
$Foswiki::cfg{VirtualHostingContrib}{ServerAlias} = { '127.0.0.1' => 'example.com',Note that you also need to configure your http server to listen to the alias name to make use of this feature. Warning: in most cases where both domains, the canonical domain and the alias one, are reachable on the same network interface it is preferable to use a http redirect from one domain to the other instead of creating another domain that basically serves the same content. Also, SSL certificates appear to be invalid when served from the wrong domain. Don't use server aliases for in that case. Using a server alias does make sense when the same domain isn't reachable on a second network interface from where you'll only be able to reach the server using the alias name. This might also be the case when maintaining the site on a different server offline and syncing content later on to the machine that is able to serve the canonical domain.
tools/virtualhosts-create.sh
. To create a virtual host for the example.com
domain, you should run it like that:
$ ./tools/virtualhosts-create.sh example.comIf you run this script as a user different from the one that runs the Foswiki code (e.g. you create the virtualhost as
root
but your web server runs as
www-data
or nobody
), the data/
and pub/
directories will be their
ownership properly set to the correct user (i.e. www-data
or nobody
).
tools/
subdirectory of your Foswiki installation
and can be called from the commandline. They all understand the usual parameters
that their non-vhost-aware counterparts have. In addition, they all take an
optional host
parameter that lets you specify on which virtual host to run
the command. When no host parameter is specified, the command will be run on
all known virtual hosts known.
For example, to run a REST handler check
implemented by a MyNewPlugin extension, use
cd tools ./virtualhosts-rest host=example.com /MyNewPlugin/check topic=Main.WebHome option=foo(TODO: virtualhosts-mailnotify doe not yet understand
host
).
DataDir
and PubDir
(the directories where topic text and attachments are
stored, respectively).
The Foswiki configuration is loaded during compilation time, but when using
persistent execution models (e.g. ModPerl, FastCGI), the Foswiki Perl code is
compiled only once for multiple requests. This wat, the needed configuration
tweaking must be done once for each request, and moreover must not not leave
any trail for the next request, which will possibly be handlind a different
virtual host (and thus different settings for DataDir
, PubDir
, etc.).
We need something like this:
+-----------------+ | | +----------+ Foswiki startup + | | | | +-----------------+ | Main | configuration | loaded | | Configuration cleaned | +---------------------------------+ | | | | V | +------------------+ +---------+---------+ | Incoming Request + | Outgoing Response + +--------+---------+ +-------------------+ | ^ | Configuration ajusted | | for current virtual host | | | | | | +--------------------+ | | | | | +---->| Request processing +------+ | (conf. loaded) | +--------------------+Since all Foswiki-specific processing happens inside the "Request processing" box, then if we manage to tweak the configuration before it is run and to restore it after the request is processed, we are all set. For that, we hook in the Foswiki engines system.
$self
is the engine object):
1 | A Request object is prepared, | $req = $self→prepare() |
2 | The processing is delegated to the Foswiki::UI module. This module detects what was the called script (view, edit, attach etc.), instantiates a Foswiki session and does all of the actual processing to produce a result for the client. In special, this phase is the only one in which the vast majority of the Foswiki configuration matters. |
$res = Foswiki::UI::handleRequest($req) |
3 | The engine does a cleanup and sends the response back to the client | $self→finalize($req, $req) |
Foswiki::UI::handleRequest
, and restore the configuration just after it
finishes.
local()
construct local()
construct enables the programmer to set a global variable
until the end of the current block. After the current block exits, the value is
restored to its original value. This can be also used with hash elements: in
this case, only the elements changed with local
are restored when the scope
ends.
Example:
use Foswiki; # Assume that DataDir is set initially to "/path/to/foswiki/data" print $Foswiki::cfg{DataDir}, "\n" { local = $Foswiki::cfg{DataDir} = "/path/to/virtualhosts/example.com/data"; print $Foswiki::cfg{DataDir}, "\n"; } print $Foswiki::cfg{DataDir}, "\n"The above example will print the following:
/path/to/foswiki/data /path/to/virtualhosts/example.com/data /path/to/foswiki/dataThis way we can override the settings we need, and also gain the cleanup step for free since Perl will automatically revert all changes done with local when the block ends. For more information on
local()
, please refer to "Temporary Values via
local()" in the perlsub(1) manpage (you must have Perl's documentation
installed in your system).
use vars qw($RE); BEGIN { $RE = qr/$Foswiki::cfg{SomeOption}/; }If this code runs under ModPerl, FastCGI or other persistent engine, Then the
$RE
variable will be initialized in the first time that code is
loaded, and that may be in the context of a specific virtual host. In a future
request, $RE will still contain a value derived from the value of
$Foswiki::cfg{SomeOption}
for the original virtualhost, even if
the current virtualhost redefines $Foswiki::cfg{SomeOption}
.
To fix this, you should avoid initializing values that depend on the
configuration during compile-time. Instead, compose the values you need during
runtime:
sub do_stuff { my $RE = qr/$Foswiki::cfg{SomeOption}/; // use $RE here ... }or in a OO context:
sub new { // ... $this->{RE} = qr/$Foswiki::cfg{SomeOption}/; // ... } sub method { my $this = shift; // use $this->{RE} ... }
$Foswiki::cfg{SomeOption}
will be expanded only in the first time
the expression is evaluated:
my $RE = qr/$Foswiki::cfg{SomeOption}/o;Even is a virtualhost redefined
$Foswiki::cfg{SomeOption}
, the
value used in that regular expression will be the value defined in the context
of the virtualhost that was being processed during the first time that
expression was evaluated.
So, avoid the 'o' flag when interpolating configuration values in regular
expressions. The following real code shows the problem:
use vars qw($GLOBAL); $GLOBAL = 'Main'; sub f { my $re = qr/(?:$GLOBAL\.)/o; print $re, "\n"; } f(); $GLOBAL = 'Users'; f();The two calls to f() will print the same value, based on the value
$GLOBAL
has in the first time the regular expression was
evaluated:
$ perl test.pl (?-xism:(?:Main\.)) (?-xism:(?:Main\.))If you remove the 'o' flag from the regular expresion, you will obtain the desired result:
$ perl test.pl (?-xism:(?:Main\.)) (?-xism:(?:Users\.))
Name | Version | Description |
---|---|---|
File::Copy::Recursive | >=0 | Required. |
Foswiki::Contrib::FastCGIEngineContrib | >=1.20 | Required. |
05 May 2022 | rewrite to prevent monkey-patching the core engine; support warming up in newer FastCGIEngineContrib; fixed multiple memory and filehandler leaks; added virtualhosts-save tool |
20 Jun 2017 | Foswikitask:Item14424: remove pending registrations. Foswikitask:Item14423: adjust to newer versions of MailerContrib |
30 May 2017 | Foswikitask:Item9958: virtualhosts-create.sh has issues. Foswikitask:Item11629: Add config checker and fail more gracefully. Foswikitask:Item14408: VirtualHostingContrib needs to support convertTopicSettings. Foswikitask:Item14409: Add checker and wizard to help manage virtual hosts. Foswikitask:Item14410: VirtualHostingContrib not compatible with CharsetConverterContrib. Foswikitask:Item14411: virtualhost.fcgi out of sync with foswiki.fcgi. |
18 Mar 2014: | exclude server aliases running a command on all hosts; added quiet commandline parameter |
10 Jul 2013: | added feature to temporarily disable virtual hosts; -- Foswiki:Main/MichaelDaum |
01 Jul 2013: | added support for WebStatistics and a couple of other commandline tools |
04 Jul 2012: | added foswiki maintenance tools for virtual hosting; -- Foswiki:Main/MichaelDaum |
20 Aug 2011: | added server aliases; fixed interfacing new logger api; added run_on() api; -- Foswiki:Main/MichaelDaum |
02 Nov 2010(2): | code cleanup and performance optimization -- Foswiki:Main/AntonioTerceiro |
02 Nov 2010: | added support for listening on non-standard ports; performance optimization -- Foswiki:Main/AntonioTerceiro |
16 Jul 2010: | first release (Antonio Terceiro) |