Categories
WebOps

How to install XWiki

Install the Advanced Open Source Enterprise Wiki.

I am using it daily since the beginning of last November. The main XWiki advantages are a very straightforward experience, customizability, and REST API. The only drawback I can think of is the memory requirement, as it requires at least 1 GB of RAM. I enjoy it a lot!

Install essential packages

Install essential packages.

$ sudo apt install curl gnupg2

Install Java 11

Import the AdoptOpenJDK GPG public key.

$ curl --silent https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -

Define the AdoptOpenJDK repository.

$ cat <<EOF | sudo tee -a /etc/apt/sources.list.d/adoptopenjdk.list
deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ $(lsb_release --codename --short) main
EOF

Update package index.

$ sudo apt update

Install Java 11 JRE.

$ sudo apt install adoptopenjdk-11-hotspot-jre

Prepare PostgreSQL database

Create a designated database user.

$ sudo -u postgres createuser xwiki --pwprompt
Enter password for new role:     *************
Enter it again:                  *************

Create a designated database.

$ sudo -u postgres createdb xwiki --encoding unicode --owner xwiki

Remember to update pg_hba.conf configuration file to allow client authentication.

You do not need to install a Java database driver for PostgreSQL on the XWiki server.

Prepare MariaDB database

Create a designated database.

$ mysql --execute "CREATE DATABASE xwiki"

Create a designated database user.

$ mysql --execute "CREATE USER 'xwiki'@'xwiki' IDENTIFIED BY 'xwiki'"

Grant database permissions.

$ mysql --execute "GRANT ALL ON xwiki.* TO 'xwiki'@'localhost'"

Install Java database driver for MariaDB on the XWiki server.

$ sudo apt install libmariadb-java

Install XWiki

Import the XWiki public key.

$ curl -s https://maven.xwiki.org/public.gpg | sudo apt-key add -

Define the XWiki repository.

$ echo "deb https://maven.xwiki.org stable/" | sudo tee /etc/apt/sources.list.d/xwiki.list

Update package index.

$ sudo apt update

Install XWiki and Apache Tomcat 9.

$ sudo apt install xwiki-tomcat9-common

Perform initial configuration

Edit /etc/xwiki/xwiki.cfg configuration file to set cookie encryption/validation keys.

#-# Cookie encryption keys. You SHOULD replace these values with any random string,
#-# as long as the length is the same.
xwiki.authentication.validationKey=K3ZVum5H1IsM9lDCa0I0vIo2dnhI5ZM5
xwiki.authentication.encryptionKey=jfHMyJ1AM990jl8OS5gw8dn3msxEnr4X

Determine JAVA_HOME value.

$ readlink -f $(which java) | sed s:bin/java::
/usr/lib/jvm/adoptopenjdk-11-hotspot-jre-amd64/

Update /etc/default/tomcat9 Apache Tomcat 9 service configuration to define JAVA_HOME.

The home directory of the Java development kit (JDK). You need at least
JDK version 8. If JAVA_HOME is not set, some common directories for
OpenJDK and the Oracle JDK are tried.
JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-hotspot-jre-amd64/

Update /etc/default/tomcat9 Apache Tomcat 9 service configuration to define the maximum size of the memory allocation pool. 

You may pass JVM startup parameters to Java here. If you run Tomcat with
Java 8 instead of 9 or newer, add "-XX:+UseG1GC" to select a suitable GC.
If unset, the default options will be: -Djava.awt.headless=true
JAVA_OPTS="-Djava.awt.headless=true -Xmx1024m"

Set XWiki as ROOT application.

$ sudo mv /etc/tomcat9/Catalina/localhost/{xwiki.xml,ROOT.xml}

Create /etc/xwiki/hibernate.cfg.xml configuration file and define database connection settings.

<?xml version="1.0" encoding="UTF-8"?>

<!--
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->

<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>

    <!-- Please refer to the installation guide on
         https://www.xwiki.org/xwiki/bin/view/Documentation/AdminGuide/Installation/ for configuring your database.
         You'll need to do 2 things:
         1) Copy your database driver JAR in WEB-INF/lib or in some shared lib directory
         2) Uncomment the properties below for your specific DB (and comment the default
            database configuration if it doesn't match your DB)
    -->

    <!-- Generic parameters common to all Databases -->

    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.use_outer_join">true</property>

    <!-- Without it, some queries fail in MS SQL. XWiki doesn't need scrollable result sets, anyway. -->
    <property name="hibernate.jdbc.use_scrollable_resultset">false</property>

    <!-- DBCP Connection Pooling configuration. Only some properties are shown. All available properties can be found
         at https://commons.apache.org/proper/commons-dbcp/configuration.html
    -->
    <property name="hibernate.dbcp.defaultAutoCommit">false</property>
    <property name="hibernate.dbcp.maxTotal">50</property>
    <property name="hibernate.dbcp.maxIdle">5</property>
    <property name="hibernate.dbcp.maxWaitMillis">30000</property>

    <!-- Enable JMX monitoring for DBCP -->
    <property name="hibernate.dbcp.jmxName">org.apache.dbcp:DataSource=dbcp</property>

    <!-- Tell Hibernate to use XWiki's custom DBCP Connection Provider so that the DBCP pool is used -->
    <property name="hibernate.connection.provider_class">com.xpn.xwiki.store.DBCPConnectionProvider</property>

    <!-- Enable JMX monitoring for Hibernate -->
    <property name="hibernate.jmx.enabled">true</property>
    <property name="hibernate.jmx.sessionFactoryName">XWiki</property>
    <property name="hibernate.generate_statistics">true</property>

    <!--
      Keep the old behavior. The new version of hibernate tries to delete and recreate unique
      constraints when updating the database schema. The problem is that an exception is thrown
      when the constraint to be deleted does not exists, which is the case with a new XWiki
      instance.
      See https://hibernate.atlassian.net/browse/HHH-8162
    -->
    <property name="hibernate.schema_update.unique_constraint_strategy">skip</property>

    <!-- Setting "hibernate.dbcp.poolPreparedStatements" to true and "hibernate.dbcp.maxOpenPreparedStatements" will tell DBCP to cache
         Prepared Statements (it's off by default). Note that for backward compatibility the "hibernate.dbcp.ps.maxActive" is also
         supported and when set it'll set "hibernate.dbcp.poolPreparedStatements" to true and "hibernate.dbcp.maxOpenPreparedStatements" to
         value of "hibernate.dbcp.ps.maxActive".

         Note 1: When using HSQLDB for example, it's important to NOT cache prepared statements because HSQLDB
         Prepared Statements (PS) contain the schema on which they were initially created and thus when switching
         schema if the same PS is reused it'll execute on the wrong schema! Since HSQLDB does internally cache
         prepared statement there's no performance loss by not caching Prepared Statements at the DBCP level.
         See https://jira.xwiki.org/browse/XWIKI-1740.
         Thus we recommend not turning on this configuration for HSQLDB unless you know what you're doing :)

         Note 2: The same applies to PostGreSQL.
    -->

    <!-- BoneCP Connection Pooling configuration.
    <property name="hibernate.bonecp.idleMaxAgeInMinutes">240</property>
    <property name="hibernate.bonecp.idleConnectionTestPeriodInMinutes">60</property>
    <property name="hibernate.bonecp.partitionCount">3</property>
    <property name="hibernate.bonecp.acquireIncrement">10</property>
    <property name="hibernate.bonecp.maxConnectionsPerPartition">60</property>
    <property name="hibernate.bonecp.minConnectionsPerPartition">20</property>
    <property name="hibernate.bonecp.statementsCacheSize">50</property>
    <property name="hibernate.bonecp.releaseHelperThreads">3</property>
    <property name="hibernate.connection.provider_class">com.xpn.xwiki.store.DBCPConnectionProvider</property>
    -->

    

    <!-- Configuration for the default database.
         Comment out this section and uncomment other sections below if you want to use another database.
         Note that the database tables will be created automatically if they don't already exist.

         If you want the main wiki database to be different than "xwiki" (or the default schema for schema based engines)
         you will also have to set the property xwiki.db in xwiki.cfg file
    -->
    <property name="hibernate.connection.url">jdbc:mariadb://localhost/xwiki?useSSL=false</property>
    <property name="hibernate.connection.username">xwiki</property>
    <property name="hibernate.connection.password">xwiki</property>
    <property name="hibernate.connection.driver_class">org.mariadb.jdbc.Driver</property>
    <property name="hibernate.dbcp.poolPreparedStatements">true</property>
    <property name="hibernate.dbcp.maxOpenPreparedStatements">20</property>

    <property name="hibernate.connection.charSet">UTF-8</property>
    <property name="hibernate.connection.useUnicode">true</property>
    <property name="hibernate.connection.characterEncoding">utf8</property>

    <mapping resource="xwiki.hbm.xml"/>
    <mapping resource="feeds.hbm.xml"/>
    <mapping resource="instance.hbm.xml"/>
    <mapping resource="notification-filter-preferences.hbm.xml"/>
    <mapping resource="mailsender.hbm.xml"/>

    <!-- MariaDB configuration.
         Uncomment if you want to use MariaDB and comment out other database configurations.
         Notes:
           - if you want the main wiki database to be different than "xwiki"
             you will also have to set the property xwiki.db in xwiki.cfg file

    <property name="hibernate.connection.url">jdbc:mariadb://localhost/xwiki?useSSL=false</property>
    <property name="hibernate.connection.username">xwiki</property>
    <property name="hibernate.connection.password">xwiki</property>
    <property name="hibernate.connection.driver_class">org.mariadb.jdbc.Driver</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MariaDBDialect</property>
    <property name="hibernate.dbcp.poolPreparedStatements">true</property>
    <property name="hibernate.dbcp.maxOpenPreparedStatements">20</property>

    <property name="hibernate.connection.charSet">UTF-8</property>
    <property name="hibernate.connection.useUnicode">true</property>
    <property name="hibernate.connection.characterEncoding">utf8</property>

    <mapping resource="xwiki.hbm.xml"/>
    <mapping resource="feeds.hbm.xml"/>
    <mapping resource="instance.hbm.xml"/>
    <mapping resource="notification-filter-preferences.hbm.xml"/>
    <mapping resource="mailsender.hbm.xml"/>
    -->

    <!-- PostgreSQL configuration.
         Uncomment if you want to use PostgreSQL and comment out other database configurations.
         Notes:
           - "hibernate.jdbc.use_streams_for_binary" needs to be set to "false",
             see https://community.jboss.org/wiki/HibernateCoreMigrationGuide36
           - "xwiki.virtual_mode" can be set to either "schema" or "database". Note that currently the database mode
             doesn't support database creation (see https://jira.xwiki.org/browse/XWIKI-8753)
           - if you want the main wiki database to be different than "xwiki" (or "public" in schema mode)
             you will also have to set the property xwiki.db in xwiki.cfg file

    <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/xwiki</property>
    <property name="hibernate.connection.username">xwiki</property>
    <property name="hibernate.connection.password">xwiki</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.jdbc.use_streams_for_binary">false</property>
    <property name="xwiki.virtual_mode">schema</property>

    <property name="hibernate.connection.charSet">UTF-8</property>
    <property name="hibernate.connection.useUnicode">true</property>
    <property name="hibernate.connection.characterEncoding">utf8</property>

    <mapping resource="xwiki.postgresql.hbm.xml"/>
    <mapping resource="feeds.hbm.xml"/>
    <mapping resource="instance.hbm.xml"/>
    <mapping resource="notification-filter-preferences.hbm.xml"/>
    <mapping resource="mailsender.hbm.xml"/>
    -->


  </session-factory>
</hibernate-configuration>

Edit /etc/xwiki/xwiki.cfg XWiki configuration and unset the name of the web application.

#-# The default protocol to use when generating an external URL. Can be overwritten in the wiki descriptor ("secure" property).
#-# If not set, the following is used:
#-#   * during client request for the current wiki: the protocol from the URL used by the client
#-#   * for a different wiki or during background tasks (mails, etc.): information come from the wiki descriptor (also fallback on main w
iki)
#-# For example:
#-# xwiki.url.protocol=https
# xwiki.url.protocol=
#-# The name of the webapp to use in the generated URLs. If not specified, the value is extracted from the request URL
#-# and thus it's generally not required to set it. However if you're deploying XWiki as ROOT in your Servlet Container
#-# and you're using XWiki 6.2.8+/6.4.3+/7.0+ you must set it to an empty value as otherwise the code cannot guess it.
#-# Note that not setting this property seemed to work on previous versions when deploying as ROOT but it was actually
#-# leading to errors from time to time, depending on what URL was used when doing the first request on the XWiki
#-# instance.
#-# For example:
#-# xwiki.webapppath=xwiki
xwiki.webapppath=

Restart Apache Tomcat.

$ sudo systemctl restart tomcat9

Perform initial setup

Open distribution wizard using a web browser.

Create an XWiki administrator.

Select an XWiki flavor.

Install an XWiki flavor.

Inspect installation report.

Play with XWiki.

Additional steps

Inspect and secure Apache Tomcat configuration.

Inspect Global Administration: Rights to prevent unregistered users from registering or viewing pages.

Additional notes