Installing XWiki on a VPS (Digital Ocean or OVH) for less than $10/month

Last modified by XWikiGuest on 2023/03/09 11:37

Mar 02 2015

Nowadays, having our own Virtual Private Server (VPS) is very not expensive. I have taken this opportunity to host my own XWiki instance. In this article, I will report how I have done so you can easily do the same.

Table of content

1. Chose a provider

The first step is to chose a VPS provider. They are many on the market. I have chosen 2 of them:

  • Digital Ocean: Good prices, SSD Drive, very nice UI, good support and nice tutorials on their site. The billing is per hour, so if your VPS is created just for a few hours, you will pay for what you have used only.
  • OVH: The famous French provider. Very low prices. 

2. Create a VPS on Digital Ocean

After creating an account, you just need to click on "create Droplet" (that is how Digital Ocean call their VPS).

You fill a name and you select the size that you need. 512MB of RAM is not enough for XWiki, so I have picked up 1GB.

do-create1.png

Then you select where your VPS will be hosted. I have chosen Amsterdam, since I am European. I also pick the option "enable backups" to have automatic backups done by the provider.

do-create2.png

Then you chose which Operating System you want. I have chosen Ubuntu because it is the OS I use on my laptop and the one I know best. I have taken the version 14.04 because it is a LTS (Long Term Support) with 5 years of support.

do-create3.png

Then you fill your SSH key, to be able to connect to your VPS.

do-create4.png

After all that, you can create your droplet.

do-create5.png

The installation takes a few minutes.

do-create6.png

When it's done, you will receive an e-mail with the IP of your VPS. To connect, you just need to use SSH.

gdelhumeau@laptop:~$ ssh root@my_server_IP

For the first access, the server will ask you to change the root's password.

2bis. Create a VPS on OVH

I did not take screenshot, but the process is quite simple too. I have chosen the VPS Cloud Classic that costs 2.39€/month (including taxes), with 1GB of RAM. But no real backups.

Same, I have chosen an Ubuntu Server 14.04.

When you receive the e-mail, you just need to use SSH to connect:

gdelhumeau@laptop:~$ ssh root@my_server_IP

I suggest you to change the root's password, even if the VPS does not ask you.

3. Create a user

It is not a good practice to work with the "root" user. So we create our own:

root@vps:~$ adduser gdelhumeau

We give him the right to use the "sudo" command:

root@vps:~$ gpasswd -a gdelhumeau sudo

Then we add our SSH public key in the authorized keys of that user:

root@vps:~$ su - gdelhumeau
gdelhumeau@vps:~$ mkdir .ssh
gdelhumeau@vps:~$ chmod 700 .ssh
gdelhumeau@vps:~$ vim .ssh/authorized_keys
## We copy our public keys
gdelhumeau@vps:~$ chmod 600 .ssh/authorized_keys
gdelhumeau@vps:~$ exit
root@vps:~$ exit

Now we can connect with our user:

gdelhumeau@laptop:~$ ssh gdelhumeau@my_server_IP

It's done

4. Configure a firewall

To avoid security problems with people trying to access our server, we set a basic firewall. The Linux firewall is "iptables", but Ubuntu provides a wrapper called "UFW" that is easier to use.

So, first, we install it:

gdelhumeau@vps:~$ sudo apt-get install ufw

Then we set some basic rules:

## We allow to connect to the ssh server
gdelhumeau@vps:~$ sudo ufw allow ssh
## We allow to connect to the web server
gdelhumeau@vps:~$ sudo ufw allow 80/tcp
## Our server needs to access other web servers
gdelhumeau@vps:~$ sudo ufw allow out 80/tcp
## Then we enable the firewall
gdelhumeau@vps:~$ sudo ufw enable
## And we check that everything work fine
gdelhumeau@vps:~$ sudo ufw status
To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)

80/tcp                     ALLOW OUT   Anywhere
80/tcp (v6)                ALLOW OUT   Anywhere (v6)

It's done.

5. Minor config

We configure the time-zone of our server:

gdelhumeau@vps:~$ sudo dpkg-reconfigure tzdata

and we install NTP to have a synchronized clock:

gdelhumeau@vps:~$ sudo apt-get install ntp

6. Install MySQL

I use MySQL simply because it is the database I know the best. But you could use PostGreSQL or any SQL database that XWiki supports (Oracle, HSQLDB).

So we install it:

gdelhumeau@vps:~$ sudo apt-get install mysql-server

We also change the default configuration:

gdelhumeau@vps:~$ sudo vim /etc/mysql/my.cnf

In this file, we change the following line:

max_allowed_packet      = 16M

to:

max_allowed_packet      = 32M

We also enable the option "innodb_file_per_table" because it is better for performances. We do it by adding a new line just above [mysqld]:

[mysqld]
innodb_file_per_table

Now we restart MySQL:

gdelhumeau@vps:~$ sudo service mysql restart

We need to create a database for XWiki, so we connect to the server:

gdelhumeau@vps:~$ mysql -u root -p

The default database that XWiki uses is called "xwiki". In my opinion, it is a good practice to prefix all XWiki databases by "xwiki_", because XWiki will create one database per wiki, and it prevents mixing up with other databases not related to XWiki. So we create the database "xwiki_xwiki":

create database xwiki_xwiki default character set utf8 collate utf8_bin;

It's done.

7. Install Java

I have made the choice of using the Oracle Virtual Machine because we usually have better performances with it. But it should work with OpenJDK too.

To install it, we add a package repository that simplifies the installation of the Oracle JVM:

gdelhumeau@vps:~$ sudo add-apt-repository ppa:webupd8team/java

With OVH, it does not work. We have to manually add the following lines to /etc/apt/sources.list:

deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main
deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main

Then we update the package list and we install java:

gdelhumeau@vps:~$ sudo apt-get update
gdelhumeau@vps:~$ sudo apt-get install oracle-java8-installer

We make sure java is well configured:

gdelhumeau@vps:~$ java -version

It should return something like: 

java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

It's done.

8. Install Tomcat

XWiki should works with every Servlet Container, but I have chosen Tomcat because XWiki provides a script to handle it.

So we install Tomcat 7:

gdelhumeau@vps:~$ sudo apt-get install tomcat7

Now we need to change the options by editing the launcher file:

gdelhumeau@vps:~$ sudo vim /etc/default/tomcat7

We replace:

#JAVA_HOME=/usr/lib/jvm/openjdk-6-jdk

by:

JAVA_HOME=/usr/lib/jvm/java-8-oracle/

We also change the JAVA_OPTS variable:

JAVA_OPTS="-Djava.awt.headless=true -Xmx600m -XX:MaxPermSize=192m -XX:+UseConcMarkSweepGC"

Here we give 600Mb of RAM to tomcat.

If you use Digital Ocean, the tomcat launch will be very slow. It is because Tomcat computes some random numbers, and your newly created VPS lacks of entropy. To fix this, we add to the JAVA_OPTS variable the following option: 

-Djava.security.egd=file:/dev/./urandom

For OVH, I have not noticed this problem. They probably handle this problem on their own.

Now we restart Tomcat:

gdelhumeau@vps:~$ sudo service tomcat7 restart

We also add a temporary rule to our firewall to be able to connect to tomcat from the outside:

gdelhumeau@vps:~$ sudo ufw allow 8080/tcp
gdelhumeau@vps:~$ sudo ufw reload

Now, with your favourite browser, you go to the URL: http://your_vps_ip:8080/ and after some time, you will see the success page:

tomcat.png

It's done.

9. Install XWiki

Now we can install XWiki. First we download it:

gdelhumeau@vps:~$ wget http://download.forge.ow2.org/xwiki/xwiki-enterprise-web-6.4.2.war

Then we unzip it inside the webapp folder:

gdelhumeau@vps:~$ sudo unzip xwiki-enterprise-web-6.4.2.war -d /var/lib/tomcat7/webapps/xwiki

Now we need the MySQL connector that XWiki does not bundle:

gdelhumeau@vps:~$ wget http://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.9/mysql-connector-java-5.1.9.jar
gdelhumeau@vps:~$ sudo cp mysql-connector-java-5.1.9.jar /var/lib/tomcat7/webapps/xwiki/WEB-INF/lib

Then we need to change the XWiki database configuration:

gdelhumeau@vps:~$ sudo vim /var/lib/tomcat7/webapps/xwiki/WEB-INF/hibernate.cfg.xml

Here, we comment the default configuration:

    <!-- 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.

    <property name="connection.url">jdbc:hsqldb:file:${environment.permanentDirectory}/database/xwiki_db;shutdown=true</property>
    <property name="connection.username">sa</property>
    <property name="connection.password"></property>
    <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
    <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

    <mapping resource="xwiki.hbm.xml"/>
    <mapping resource="feeds.hbm.xml"/>
    <mapping resource="activitystream.hbm.xml"/>
    <mapping resource="instance.hbm.xml"/>
    <mapping resource="mailsender.hbm.xml"/>
-->

And we uncomment the MySQL section:

    <!-- MySQL configuration.
         Uncomment if you want to use MySQL and comment out other database configurations.
        -->

   <property name="connection.url">jdbc:mysql://localhost/xwiki</property>
   <property name="connection.username">root</property>
   <property name="connection.password">yourpassword</property>
   <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
   <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
   <property name="dbcp.ps.maxActive">20</property>
   <mapping resource="xwiki.hbm.xml"/>
   <mapping resource="feeds.hbm.xml"/>
   <mapping resource="activitystream.hbm.xml"/>
   <mapping resource="instance.hbm.xml"/>
   <mapping resource="mailsender.hbm.xml"/>

We have also changed the MySQL user and password. I personally use the MySQL "root" user since XWiki needs all privileges to create and drop databases. But you could create your own MySQL user and set it there.

Now we go to the XWiki configuration, which is split in 2 files (for legacy reason).

Let's edit the first file:

gdelhumeau@vps:~$ sudo vim /var/lib/tomcat7/webapps/xwiki/WEB-INF/xwiki.cfg

There, I have chosen to use the FileSystem Attachment Storage. It makes XWiki store its attachments in the FS instead of the database. You can have bigger attachments and I think it's better to now crowd the database with binary files.

#---------------------------------------
# Storage
#

#-# Role hints that differentiate implementations of the various storage components. To add a new implementation for
#-# one of the storages, implement the appropriate interface and declare it in a components.xml file (using a role-hint
#-# other than 'default') and put its hint here.
#
#-# The main (documents) storage. [Since 3.4M1] default is hibernate.
# xwiki.store.main.hint=hibernate
#-# The attachment storage. [Since 3.4M1] default is hibernate.
xwiki.store.attachment.hint=file
#-# The document versioning storage. [Since 3.4M1] default is hibernate.
# xwiki.store.versioning.hint=hibernate
#-# The attachment versioning storage. Use 'void' to disable attachment versioning. [Since 3.4M1] default is hibernate.
xwiki.store.attachment.versioning.hint=file
#-# The document recycle bin storage. [Since 3.4M1] default is hibernate.
# xwiki.store.recyclebin.hint=hibernate
#-# The attachment recycle bin storage. [Since 3.4M1] default is hibernate.
xwiki.store.attachment.recyclebin.hint=file
#-# [Since 3.4M1] The Migration manager.
# xwiki.store.migration.manager.hint=hibernate

I also extend the cache size for performances reasons:

#-# Maximum number of documents to keep in the cache.
xwiki.store.cache.capacity=1000

And I enable the "xwiki_" prefix on the databases:

#-# Maximum number of documents to keep in the cache.
xwiki.db.prefix=xwiki_

Now we don't forget to change the salt used for the cookies:

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

And that's all.

Now we modify the other file:

gdelhumeau@vps:~$ sudo vim /var/lib/tomcat7/webapps/xwiki/WEB-INF/xwiki.properties

Here, I set a different permanentDirectory (that should exists and that the user tomcat7 can write):

environment.permanentDirectory=/var/local/xwiki/

I also suggest to change the way the LESS cache works. By default, the LESS cache is flushed at every restart, but I think it's not needed and very bad for performances. So I edit:

gdelhumeau@vps:~$ sudo vim /var/lib/tomcat7/webapps/xwiki/WEB-INF/cache/infinispan/config.xml

And I change:

  <!-- LESS CSS cache -->
 <namedCache name="lesscss.skinfiles.cache">
   <loaders>
     <loader class="org.infinispan.loaders.file.FileCacheStore" purgeOnStartup="false">
       <!-- Let XWiki cache module set the proper location -->
     </loader>
   </loaders>
 </namedCache>

The configuration is done, we can restart Tomcat:

gdelhumeau@vps:~$ sudo service tomcat7 restart

Now, let's go to XWiki with your browser (http://your_vps_ip:8080/xwiki)

You should see the XWiki Distribution Wizard. Now you just have to follow the steps and XWiki will be ready! (BTW, the default admin user is "Admin" and the password is "admin").

dw.png

10. Install Nginx

XWiki is installed but our system is not ready. Tomcat is a servlet container and not a real web server, so we need to set up a reverse proxy. The usual choice for that is the Apache web server, but I have chosen Nginx which is becoming more and more popular, and that has better performances. It seems a better fit regarding the fact that we have only a little server.

So we install it:

gdelhumeau@vps:~$ sudo apt-get install nginx

Then we go to the URL with our browser: (http://your_server_ip). And we get:

nginx.png

Now we disable the default configuration:

gdelhumeau@vps:~$ sudo rm /etc/nginx/sites-enabled/default

and we create our own:

gdelhumeau@vps:~$ sudo vim /etc/nginx/sites-available/xwiki

Here is my configuration:

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /usr/share/nginx/html;
        index index.html index.htm;

        # Make site accessible from http://mydomain.com/
        server_name mydomain.com;

        location / {
                #All "root" requests will have /xwiki appended AND redirected to mydomain.com again
                rewrite ^ $scheme://$server_name/xwiki$request_uri? permanent;
        }

        location ^~ /xwiki {
                # If path starts with /xwiki - then redirect to backend: XWiki application in Tomcat
                proxy_pass http://localhost:8080/xwiki;
                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;
        }
}

This configuration redirects every requests for mydomain.com to mydomain.com/xwiki.

If you want to use a different domain name for each subwiki, I suggest to add:

proxy_set_header Host $host;

If not, XWiki will not be able to detect the current wiki from the domain name.

To finish, we enable our configuration and we reload Nginx:

gdelhumeau@vps:~$ sudo ln -s /etc/nginx/sites-available/xwiki /etc/nginx/sites-enabled/xwiki
gdelhumeau@vps:~$ sudo service nginx reload

It's almost done. Now that we have a proper web server, we should stop allowing access to the port 8080 (the tomcat port).

gdelhumeau@vps:~$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere
[ 2] 80/tcp                     ALLOW IN    Anywhere
[ 3] 8080/tcp                   ALLOW IN    Anywhere
[ 4] 22 (v6)                    ALLOW IN    Anywhere (v6)
[ 5] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 6] 8080/tcp (v6)              ALLOW IN    Anywhere (v6)

It displays all the firewall rules. Now we delete the rules concerning the port 8080:

gdelhumeau@vps:~$ sudo ufw delete 6
gdelhumeau@vps:~$ sudo ufw delete 3

And we can reload the firewall:

gdelhumeau@vps:~$ sudo ufw reload

It's done.

11. Going further

The server is ready, but we can improve the set-up. I will write other articles about that in the future. Here is the list of suggestions I propose:

  • Installing XInit, a script that monitorizes XWiki, restarts tomcat if needed, sends e-mails in case of errors, etc...
  • Installing an e-mail server to allow XWiki to send messages (registration form, watchlist, etc...)
  • Installing OpenOffice, to enable the import/export of office documents.
  • Using short URLS, to get rid of the xwiki/bin/view part of the URL (the tutorial is very clear and I managed to make it work without difficulty).
  • Make automatic back-ups of the database and the permanent directory.

Stay tuned!

Other solutions

If you are discouraged about hosting XWiki yourself, you can still use an XWiki hoster:

  • MyXWiki: a free service for non-profit organizations and individuals.
  • XWiki SAS: the company I work for. Provide a professional hosting and support.

References