Docker for JSPWiki#

After some experiments with DockerContent unavailable! (broken link)https://jspwiki-vm1.apache.org/images/out.png I came up with a working solution for running JSPWiki in Tomcat on Linux in a Docker container.

What container is it ?#

The JSPWiki Docker image has 3 level parents :

  • centos7 (the base OS we use, pulled from official centos docker hub)
  • java7 installed (see dockerfile for details)
  • tomcat 8.0.21 installed (see dockerfile for details)

As locally seen with the docker images command :

[root@vbox dockerfiles]# docker images
REPOSITORY          TAG                     IMAGE ID            CREATED             VIRTUAL SIZE
harry               docker-jspwiki          7777554fc2fc        2 minutes ago       618.3 MB
harry               tomcat-8.0.21           8c64fd348c41        11 minutes ago      542.7 MB
harry               java7                   c5eb18fad024        7 days ago          501.5 MB
centos              7                       dade6cb4530a        4 weeks ago         224 MB
centos              centos7                 dade6cb4530a        4 weeks ago         224 MB
centos              latest                  dade6cb4530a        4 weeks ago         224 MB

What are the prereqs to run it ?#

Well, you "only" need a docker runtime. See the installation instructionsContent unavailable! (broken link)https://jspwiki-vm1.apache.org/images/out.png on the docker site for details.

Then you need the image, you can download it from the docker hubContent unavailable! (broken link)https://jspwiki-vm1.apache.org/images/out.png. Just download it with the docker pull metskem/docker-jspwiki command :

How do I run it#

The most simple way to go is :

docker run -d -p 80:8080 --env="jspwiki_baseURL=http://10.0.0.196/" metskem/docker-jspwiki

This means :

  • -d - detached mode, run the container in the background
  • -p 80:8080 - bind the host port (80) to the container port (8080). JSPWiki always runs on port 8080 inside the container.
  • --env="jspwiki_baseURL=http://10.0.0.196/" - you have to override this variable, because the jspwiki baseURL must match the URL that you use to access the wiki (the 10.0.0.196 is just an example of course) . Be aware that the context root can only by "/" for now, because we always install JSPWiki in the <tomcat_home>/webapps/ROOT folder. Also, envvars should container underscores instead of the dots in the normal property.
  • metskem/docker-jspwiki - the name of the image to run

How can I check it ?#

You can point your browser at the baseURL of course, that should give you a working wiki right away !

You should also see a running docker container now :

metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                  NAMES
c8c73ddd9876        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   3 minutes ago       Up 3 minutes        0.0.0.0:80->8080/tcp   focused_goldstine   
metskem@athena:~$         

You can also "log in" to your container with the docker exec command and, for example, look what is in /var/jspwiki :

metskem@athena:~$ docker exec -ti c8c73ddd9876 bash
[tomcat@c8c73ddd9876 /]$ find /var/jspwiki|head -5
/var/jspwiki
/var/jspwiki/pages
/var/jspwiki/pages/OLD
/var/jspwiki/pages/LoginHelp.txt
/var/jspwiki/pages/ApprovalRequiredForUserProfiles.txt
[tomcat@c8c73ddd9876 /]$ exit
exit
metskem@athena:~$ 

Stopping and starting the container#

To stop the container, simply issue the docker stop command against the containerid (or container name if you gave it a name during first run):

metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                  NAMES
e1892e0fe60a        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   3 seconds ago       Up 2 seconds        0.0.0.0:80->8080/tcp   jspwiki_80          
metskem@athena:~$ docker stop jspwiki_80
jspwiki_80
metskem@athena:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
metskem@athena:~$ docker ps -a
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS                            PORTS               NAMES
e1892e0fe60a        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   46 seconds ago      Exited (143) 7 seconds ago                            jspwiki_80          
c8c73ddd9876        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   6 minutes ago       Exited (143) About a minute ago                       focused_goldstine   

You can restart it again with the docker start command, you have to find the containerid with the docker ps -a command first , (or simply use the container name if you gave the container a name during first run):

metskem@athena:~$ docker start jspwiki_80
jspwiki_80
metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                  NAMES
e1892e0fe60a        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   2 minutes ago       Up About a minute   0.0.0.0:80->8080/tcp   jspwiki_80          

As you will notice, after a stop/start you still have the data (pages) that were created after the first container start. (you can check easily with the Recent Changes page)

Removing the container#

If you want to get rid of the container (and all of the data in it !) you first should stop it, then you can remove it with the docker rm command:

metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                  NAMES
e1892e0fe60a        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   2 minutes ago       Up About a minute   0.0.0.0:80->8080/tcp   jspwiki_80          
metskem@athena:~$ docker stop jspwiki_80
jspwiki_80
metskem@athena:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
metskem@athena:~$ docker ps -a
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS                       PORTS               NAMES
e1892e0fe60a        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   2 minutes ago       Exited (143) 6 seconds ago                       jspwiki_80          
c8c73ddd9876        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   8 minutes ago       Exited (143) 3 minutes ago                       focused_goldstine   
metskem@athena:~$ docker rm jspwiki_80
jspwiki_80
metskem@athena:~$ docker ps -a
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS                       PORTS               NAMES
c8c73ddd9876        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   8 minutes ago       Exited (143) 3 minutes ago                       focused_goldstine   

Note that all your data is lost when you remove the container. (You can keep data apart using docker volumes, see next paragraph)

Persistent data#

If you use docker to run jspwiki only for quick test purposes, you probably are not interested in keeping the data (created/changed pages, registered users, logfiles).
But you can also run a jspwiki docker container in production like environments where you want to keep your data even after you removed a container.
As an example you might sometimes want to run a newer version of your jspwiki docker container.

To keep data outside of the container, you can use the --volume switch when you fire up the container :

metskem@athena:~$ docker run -d -p 80:8080 --env="jspwiki_baseURL=http://10.0.0.196/" --name jspwiki_80 --volume="/home/metskem/jspwiki-pages:/var/jspwiki/pages"  metskem/jspwiki:2.10.2-svn-15
240232ebb32e58dee7ad95471128210f71007bbeb11735ffd5394113959ace75
metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                  NAMES
240232ebb32e        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   6 seconds ago       Up 6 seconds        0.0.0.0:80->8080/tcp   jspwiki_80          

This way you will get your pages in a directory on the host OS in /home/metskem/jspwiki-pages.
Obviously, in this case you will not have the initial set of default pages loaded.

Running multiple instances#

You can run multiple instances of the image of course. You only have to make sure they use different TCP ports.
So for example starting 5 containers (with also a limit on memory usage added) :

metskem@athena:~$ for PORT in `seq 9080 9084`; do docker run -d -p ${PORT}:8080 --memory=128m --env="jspwiki_baseURL=http://10.0.0.196:${PORT}/" --name jspwiki-${PORT} metskem/docker-jspwiki; done
68481eed8d609ac91711a78bd80505b398a8a37c9cc435e44eb0b2b7f881444b
b3b967dc4fe721d5efce65959bfd5b4fa6061e053b3fd7b6d814bfc68a0a5261
6a23a3ac3df9aaf1a7f2dda96b6a535d58d06a429f458edaa4101ec89a6416e1
b55b716ed49ff6ca6ba581794fe4ba5bde0439e10301f78acb62d5dec1118304
73d4cd8f29a072884a965ad3a86a5d090762fc046fe424c7b842b1c0b3a72122
metskem@athena:~$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                    NAMES
73d4cd8f29a0        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   4 seconds ago       Up 3 seconds        0.0.0.0:9084->8080/tcp   jspwiki-9084        
b55b716ed49f        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   4 seconds ago       Up 3 seconds        0.0.0.0:9083->8080/tcp   jspwiki-9083        
6a23a3ac3df9        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   4 seconds ago       Up 3 seconds        0.0.0.0:9082->8080/tcp   jspwiki-9082        
b3b967dc4fe7        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   5 seconds ago       Up 4 seconds        0.0.0.0:9081->8080/tcp   jspwiki-9081        
68481eed8d60        metskem/docker-jspwiki   "/bin/sh -c '/usr/lo   5 seconds ago       Up 4 seconds        0.0.0.0:9080->8080/tcp   jspwiki-9080        
      

And you can easily get rid of them too :

metskem@athena:~$ docker stop `docker ps -aq` 
73d4cd8f29a0
b55b716ed49f
6a23a3ac3df9
b3b967dc4fe7
68481eed8d60
240232ebb32e
c8c73ddd9876
metskem@athena:~$ docker rm `docker ps -aq`
73d4cd8f29a0
b55b716ed49f
6a23a3ac3df9
b3b967dc4fe7
68481eed8d60
240232ebb32e
c8c73ddd9876
metskem@athena:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Used docker files#

I have been using the following docker files for this JSPWiki images:

Java 7#

1
2
3
4
5
6
7
8
#
#  Dockerfile with OpenJDK7 on top of CentoS 7
#
FROM centos:centos7
MAINTAINER Harry Metske <harry.metske@gmail.com>
RUN yum -y update
RUN yum -y install java-1.7.0-openjdk
CMD /bin/bash

Tomcat #

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#
#  Dockerfile for a running tomcat on top of OpenJDK7 on top of CentoS 7
#  Also install tar, needed for unpacking the tomcat archive.
#
FROM java7
MAINTAINER Harry Metske <harry.metske@gmail.com>
RUN yum -y update && \
    yum -y install tar
RUN curl http://apache.proserve.nl/tomcat/tomcat-8/v8.0.30/bin/apache-tomcat-8.0.30.tar.gz | gunzip | tar -x -C /usr/local
RUN useradd tomcat && \
    cd /usr/local && ln -s apache-tomcat-8.0.30 tomcat && \
    chown -R tomcat.tomcat /usr/local/tomcat /usr/local/apache-tomcat-8.0.30
ENV HOME /home/tomcat
USER tomcat
EXPOSE 8080
# remove stuff we don't need
RUN rm -rf /usr/local/tomcat/bin/*.bat 
# provide access to tomcat manager application with user/pw = admin/admin :
RUN echo -e '<?xml version="1.0" encoding="utf-8"?>\n<tomcat-users>\n<role rolename="manager-gui"/>\n<role rolename="manager-script"/>\n<role rolename="manager-jmx"/>\n<role rolename="manager-status"/>\n<role rolename="admin"/>\n<user username="admin" password="admin" roles="manager,manager-gui,manager-script,manager-jmx,manager-status"/>\n</tomcat-users>' > /usr/local/tomcat/conf/tomcat-users.xml
# We want logging to get out of the container:
# VOLUME /usr/local/tomcat/logs
# 
# by default we start the Tomcat container when the docker container is started.
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]

JSPWiki#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#
#  Dockerfile for JSPWiki running in a tomcat 8 on top of OpenJDK7 on top of CentoS 7
#  Also install unzip, needed to unzip the default wikipages.
#
FROM tomcat:8.0.30
MAINTAINER Harry Metske <metskem@apache.org>
# we need the unzip command to unpack the war and zip files
USER root
RUN yum -y update
RUN yum install -y unzip
# create a directory where all jspwiki stuff will live
RUN mkdir /var/jspwiki && \
    chown tomcat.tomcat /var/jspwiki && \
#
# first remove default tomcat applications, we dont need them to run jspwiki
   cd /usr/local/tomcat/webapps && rm -rf examples host-manager manager docs ROOT && \
# create subdirectories where all jspwiki stuff will live
   cd /var/jspwiki && mkdir pages logs etc work && mkdir /usr/local/tomcat/webapps/ROOT
#
# add jspwiki war, create JSPWiki webapps dir, unzip it there.
ADD JSPWiki.war /tmp/jspwiki.war
RUN unzip -q -d /usr/local/tomcat/webapps/ROOT /tmp/jspwiki.war && rm /tmp/jspwiki.war && \
#
# download the default set of pages
   TF=/tmp/jspwikipages-download.zip && curl --silent http://apache.xl-mirror.nl/jspwiki/2.10.1/wikipages/jspwiki-wikipages-en-2.10.1.zip > $TF && unzip -q -d /tmp $TF && mv /tmp/jspwiki-wikipages-en-2.10.1/*  /var/jspwiki/pages && rm -r $TF /tmp/jspwiki-wikipages-en-2.10.1 && \
#
# move the userdatabase.xml and groupdatabase to /var/jspwiki/etc
   cd /usr/local/tomcat/webapps/ROOT/WEB-INF && mv userdatabase.xml groupdatabase.xml /var/jspwiki/etc && \
#
# arrange proper logging (jspwiki.use.external.logconfig = true needs to be set)
  echo -e \
"log4j.rootLogger=info,FileLog\n\
log4j.appender.FileLog = org.apache.log4j.RollingFileAppender\n\
log4j.appender.FileLog.MaxFileSize = 10MB\n\
log4j.appender.FileLog.MaxBackupIndex = 14\n\
log4j.appender.FileLog.File = /var/jspwiki/logs/jspwiki.log\n\
log4j.appender.FileLog.layout = org.apache.log4j.PatternLayout\n\
log4j.appender.FileLog.layout.ConversionPattern = %d [%t] %p %c %x - %m%n\n" > /usr/local/tomcat/lib/log4j.properties && \
# chown to tomcat
   chown -R tomcat.tomcat /usr/local/tomcat /var/jspwiki
#
# set default environment entries to configure jspwiki
ENV LANG en_US.UTF-8
ENV jspwiki_pageProvider VersioningFileProvider
ENV jspwiki_fileSystemProvider_pageDir /var/jspwiki/pages
ENV jspwiki_basicAttachmentProvider_storageDir /var/jspwiki/pages
ENV jspwiki_workDir /var/jspwiki/work
ENV jspwiki_xmlUserDatabaseFile /var/jspwiki/etc/userdatabase.xml
ENV jspwiki_xmlGroupDatabaseFile /var/jspwiki/etc/groupdatabase.xml
ENV jspwiki_use_external_logconfig true
# ENV jspwiki_templateDir
ENV jspwiki_baseURL http://localhost:8080/

# run with user tomcat
USER tomcat
# make port visible in metadata
EXPOSE 8080
# 
# by default we start the Tomcat container when the docker container is started.
CMD ["/usr/local/tomcat/bin/catalina.sh","run", ">/usr/local/tomcat/logs/catalina.out"]