XWiki on Ubuntu 16.04 LTS with Nginx Reverse Proxy

Install XWiki and all dependant programs on a 4 GB cloud server. This means:

1) Java
2) Tomcat
3) MySQL/MariaDB
4) XWiki
5) Nginx

Here we use Nginx as a reverse proxy to firstly redirect all HTTP to HTTPS and then forward all requests on port 80/443 to port 8080 (tomcat) on the localhost. Here I use LetsEncrytp for my SSL certificates.

Before we begin…

Setup DNS

wiki.dummydomains.org.uk ——>

Prepare the Server


Update and reboot the server.

apt-get update
apt-get dist-upgrade

Enable the firewall

ufw status
ufw enable
ufw allow ssh
ufw reload
ufw status

Install Oracle Java

This is a requirement before installing Tomcat or XWiki. At the time of writing, Java 8.x is recommended as 9.x is too new and has a number of known bugs still.

apt-get install software-properties-common
add-apt-repository ppa:webupd8team/java
apt-get update
apt-get install oracle-java8-installer

You will need to accept the license agreement:

Accept license agreement

Binary code license terms

Because many programs check for $JAVA_HOME, it is a good idea to set it now. If you don’t know the path, check with:

root@wiki:~# update-alternatives --config java
There is 1 choice for the alternative java (providing /usr/bin/java).

  Selection    Path                                     Priority   Status
  0            /usr/lib/jvm/java-8-oracle/jre/bin/java   1081      auto mode
* 1            /usr/lib/jvm/java-8-oracle/jre/bin/java   1081      manual mode

Press <enter> to keep the current choice[*], or type selection number:

Then edit your system $PATH variable so that the /usr/lib/jvm/java-8-oracle is the first path.

nano /etc/environment

Mine looks like this:

root@wiki:~# cat /etc/environment

You will need to log out and back in first but you can test with the below command.

root@wiki:~# echo $JAVA_HOME

Create Virtual Host and Generate SSL

Install Nginx and LetsEncrypt.


Install and configure Nginx.

apt-get install apache2-utils nginx
systemctl enable nginx

Create a very basic virtual host by editing the nginx configuration file and inserting your server name in the server_name variable.

vim /etc/nginx/sites-enabled/default

Mine looks like this.

root@wiki:~# egrep -v "^$|^[[:space:]]*#" /etc/nginx/sites-available/default 
server {
	listen 80 default_server;
	listen [::]:80 default_server;
	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	server_name wiki.dummydomains.org.uk;
	location / {
		try_files $uri $uri/ =404;


systemctl restart nginx

Check it works!

Nginx test page
If it doesn’t, check the firewall…

Allow HTTP and HTTPS Traffic

If you use a local firewall like UFW or iptables, you will need to allow port 80 and 443.

ufw status
ufw allow http
ufw allow https
ufw status
ufw reload


add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install python-certbot-nginx
certbot --nginx -d wiki.dummydomains.org.uk -d dummydomains.org.uk

Your certificate will get saved to /etc/letsencrypt/live/wiki.dummydomains.org.uk.

LetsEncrypt will edit your virtual hosts file.  The parts we are interested in are:

  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/wiki.dummydomains.org.uk/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/wiki.dummydomains.org.uk/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

  if ($scheme != "https") {
    return 301 https://$host$request_uri;
  } # managed by Certbot


Install XWiki

Install XWiki.

wget -q "https://maven.xwiki.org/public.gpg" -O- | apt-key add -
wget "https://maven.xwiki.org/stable/xwiki-stable.list" -P /etc/apt/sources.list.d/
apt-get update

Search for XWiki packages to install.

apt-cache search xwiki

According to the official documentation, the enterprise version is out-of-date and the non-enterprise version should be used.

apt-get install xwiki-tomcat8-mysql

Set the root MySQL password:


Set root MySQL password
Set root MySQL password

When asked if you should configure the database with dbconfig-common, say yes.

Configure with dbconfig-common
Configure with dbconfig-common

MySQL application password:


Select application password
Select application password

Check tomcat8 is listening on port 8080:

root@wiki:~# netstat -plnt | grep :8080
tcp6       0      0 :::8080                 :::*                    LISTEN      15840/java

Check your memory usage:

root@wiki:~# free -h
              total        used        free      shared  buff/cache   available
Mem:           3.9G        487M        1.9G         10M        1.5G        3.3G
Swap:            0B          0B          0B

You will need to increase the default about of memory allocated to Java. Here’s how:

vim /etc/default/tomcat8


root@wiki:~# grep ^JAVA_OPTS /etc/default/tomcat8
JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC"


root@wiki:~# grep ^JAVA_OPTS /etc/default/tomcat8
JAVA_OPTS="-Djava.awt.headless=true -Xmx1024m -XX:+UseConcMarkSweepGC"

Restart Tomcat

systemctl restart tomcat8

Test using using a browser:


If you’ve enabled a firewall and you want to test:

ufw allow 8080/tcp
ufw reload

However I’m not going to do this – I’m going to setup Nginx as a proxy first.

Configure Nginx

Remove the default virtual host configuration.

rm -v /etc/nginx/sites-enabled/default.conf
vim /etc/nginx/sites-available/wiki.dummydomains.org.uk.conf

My site configuration look as follows:

upstream tomcat {
  server fail_timeout=0;
  keepalive 64;

server {
  listen [::]:80;
  listen ssl;
  listen [::]:443 ssl;
  server_name wiki.dummydomains.org.uk dummydomains.org.uk;
  ssl_certificate /etc/letsencrypt/live/wiki.dummydomains.org.uk/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/wiki.dummydomains.org.uk/privkey.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  # redirect http to https
  if ($scheme != "https") {
    return 301 https://$host$request_uri;

  auth_basic "Authentication Required";
  auth_basic_user_file xwiki-access;

  location / {
    client_max_body_size 20M;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass_request_headers on;
    proxy_set_header Connection "keep-alive";
    proxy_store off;
    proxy_headers_hash_max_size 512;
    deny all;

    proxy_pass http://tomcat/;

I also want to password protect my wiki:

htpasswd -c /etc/nginx/xwiki-access andy

Enable the site:

cd /etc/nginx/sites-enabled/
ln -s ../sites-available/xwiki.dummydomains.org.uk.conf .

….and check configuration file for errors.

root@wiki:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Check config and restart Nginx:

systemctl restart nginx

Now try entering the following into your browser and complete the on-screen installation instructions:


Complete Installation

Here are few things I normally do after an installation.

Make Root Application

I want to make this Wiki instance the root web application and remove the trailing /xwiki from the URL.

systemctl stop tomcat8.service
mv -v /etc/tomcat8/Catalina/localhost/xwiki.xml /etc/tomcat8/Catalina/localhost/ROOT.xml
vim /etc/xwiki/xwiki-tomcat8.xml


<Context path="/xwiki" docBase="/usr/lib/xwiki" privileged="true" crossContext="true">
  <!-- make symlinks work in Tomcat -->
  <Resources allowLinking="true" />


<Context path="/" docBase="/usr/lib/xwiki" privileged="true" crossContext="true">
  <!-- make symlinks work in Tomcat -->
  <Resources allowLinking="true" />

Don’t forget to start Tomcat again:

systemctl start tomcat8.service

Now the URL is simply:


Enable superadmin

This is needed if you plan to import XWiki pages from a previous installation.

vim /etc/xwiki/xwiki.cfg

Find the following section.

#-# Enable to allow superadmin. It is disabled by default as this could be a
#-# security breach if it were set and you forgot about it. Should only be enabled
#-# for recovering the Wiki when the rights are completely messed.
# xwiki.superadminpassword=system

….and change to:

#-# Enable to allow superadmin. It is disabled by default as this could be a
#-# security breach if it were set and you forgot about it. Should only be enabled
#-# for recovering the Wiki when the rights are completely messed.

Don’t forget to restart Tomcat if necessary.

Update Cookie Encryption Keys

When a user logs in, three cookies are saved to their machine. These cookies are encrypted with the below details. First we need to get the two random strings of equal length.

root@wiki:~# date +%s | sha256sum | base64 | head -c 32 ; echo
root@wiki:~# date +%s | sha256sum | base64 | head -c 32 ; echo

Then edit the xwiki.cfg file.

vim /etc/xwiki/xwiki.cfg

Find the relevant section and edit to look like the below.


Don’t forget to restart Tomcat if necessary.

Complete the Installation

Login to complete the installation.

Log in
Log in

Click continue.

Installation wizard
Installation wizard

Register and log in.

Register and login
Register and login


Install xwiki
Install xwiki

Select 9.9 and continue.

Install 9.9
Install 9.9

Confirm installation again.

Confirm installation
Confirm installation



Continue again.

Continue again
Continue again

Confirm the report by clicking continue.

Confirm installation report
Confirm installation report

Installation complete!

Installation Complete
Installation Complete

Import old XWiki Content

Lets see if the import feature works!  Log in as the superadmin user and then navigate to the Administration section:


Then select Content, followed by Import:


Select the backup.xar that you (hopefully) took earlier and import all the content.

Package content
Package content

Select the following options.

Import options
Import options


Install Apache on Ubuntu Server 13.10

First you need to prepare the machine that you are going to use. I’m using a Rackspace cloud server. In which case, all I need to do is spin up a server and update the Operating System software.

Install Apache2

Installing Apache is easy, simply run apt-get install apache2 as the root user.

root@apache:~# apt-get install apache2
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  apache2-bin apache2-data libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
Suggested packages:
  www-browser apache2-doc apache2-suexec-pristine apache2-suexec-custom apache2-utils openssl-blacklist
The following NEW packages will be installed:
  apache2 apache2-bin apache2-data libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap
0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,302 kB of archives.
After this operation, 5,314 kB of additional disk space will be used.
Do you want to continue [Y/n]? 

Once the installation has finished, open up a web browser and enter the IP address into the address bar. Hopefully you should see a page like the below.

Installing Apache
Testing apache

And that’s it! Apache is now installed and working!

Set the Hostname

Your likely to see the below error message.

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 2a00:1a48:7806:117:936d:610a:ff08:747d. Set the 'ServerName' directive globally to suppress this message
                                                                                                  [ OK ]

This is caused by the hostname not being set correctly. Open up /etc/hosts and enter something similar to the below, adjusting for your own environment.

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters www.yourdomain.co.uk www localhost

2a00:1a48:7806:0117:936d:610a:ff08:747d	www.yourdomain.co.uk www	www.yourdomain.co.uk www	www.yourdomain.co.uk www

If you too are using a Rackspace cloud server, the most important line is shown below.

2a00:1a48:7806:0117:936d:610a:ff08:747d	www.yourdomain.co.uk www

This will stop the warning message.

Update Ubuntu Rackspace Cloud Server

Assuming you’ve already “spun-up” a Linux cloud server of your choice, the first thing to do is update the system. Here I’m using Ubuntu Server 13.10.

SSH onto your box with the below command, replacing the IP address with that of your server. You will need to accept the key when prompted.

andy@work-pc:~$ ssh root@
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is 12:af:51:e2:bf:ed:b8:2c:dc:89:de:ca:55:a7:36:6a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
root@'s password: 

Then update the system and reboot if needed.

root@apache:~# apt-get update
root@apache:~# apt-get upgrade
root@apache:~# reboot

Delete Unused Rackspace Cloud Servers

To avoid any unnecessarily high Rackspace bills, make sure you delete any unused cloud servers or products.

Here I have three servers. One is in production, another is occasionally used for testing and development. I am half-way through setting the last one up but it is not yet in production.

You might think that you can just power-off the server to stop being billed for it….but you’d be wrong! If you simply shut down the server, you will still be billed per hour for it’s use.

If like me, you have any servers that are not currently in use, either by you or your customers, it makes sense to take an image of the device and then delete it. You can always spin up a new server from the image you create.

Take an Image

To take an image, click the cog icon next to the server. That will create a drop-down menu. Within there, you will see “Create Image” – select that.

Taking an image
Taking an image

You will then be asked to give the saved image a name. If you hover over the small pound sign symbol, you will also see the associated costs.

Give the image a name.
Give the image a name.

Delete Server

Before I delete a server I might come to rely on later, I like to first make sure the image was created successfully. To do that, navigate to the “Saved Images” section/tab.

Saving images.
Saving images.

Once imaged, simply select the servers you wish to delete and click on the “Delete” button.

Deleting servers
Deleting servers

Rebuild Server from an Image

When you next require the deleted server, we can spin up a new server from the image we took.

One downside to this is that the newly created server will have a different public IP address than it did previously. If this is an issue for you, I would recommend creating a load-balancer to sit in front of the device. It is possible to have a load-balancer with one node behind it. Load-balancers IP addresses do not change.

To spin up a new server from an existing image, simply navigate to the “Saved Images” section of the server tab. Click on the cog next to the image you wish to use and select “Create Server with Image...“.

Then simply give the server a name, select a flavour and/or alter any other details. Then click on “Create Server“.

You will be given a new password for the server. Make a note of this and “Dismiss Password” when ready.

Root Admin Password
Root Admin Password

You can monitor the progress from the cloud servers tab.

Cloud Server Rebuilding
Cloud Server Rebuilding

Job done!

“Spinning up” a Rackspace Cloud Server

Assuming you’ve already created yourself a Rackspace cloud account and that you’ve just logged in, you will see a list of cloud servers (if you have any yet). These are your current servers. If a server is listed here, you will be getting charged for it at an hourly rate. Even if you shutdown your server through the Operating System! To avoid getting charged for something you are not using, take a snapshot and then delete it. You can always build a new server instance from that snapshot at a later point in time when it is required.

Servers tab
Servers tab

To create a new server, you simply click “create server“, then provide the following information.

Server name:

Once filled out, kick the build process off by clicking “create server” at the bottom of the page.

Select flavour and instance type
Select flavour and instance type

The server will then go into “building” state until complete when it then goes into “active". Although it only takes a few minutes to be deployed, you are free to continue using other parts of the website. You can even spin up more servers while you wait if you want!!

Building server
Building server

And that is it! Your first cloud server! Easy!

Your new server details
Your new server details

How to connect to your new cloud server depends on what Operating System you chose to install, Windows or Linux? If you chose Linux, you will need to use SSH. If Windows, you can use RDP. Here we chose CentOS – which is essentially just a free, re-branded release of Red Hat Enterprise Linux. If using SSH, issue below command.

[root@server ~]# ssh root@

Don’t forget to replace with the public IP address of your cloud server!