Run XWiki with a Read-Only Root Filesystem

Last modified by Vincent Massol on 2026/07/29 11:29

Steps

XWiki 17.10.11+, 18.4.3+, 18.7.0+

Run the XWiki container with a read-only root filesystem by mounting the few paths it writes to: the configuration files it rewrites on every start, the permanent directory, and the working directories of Tomcat and of LibreOffice.

  1. Copy the three configuration files that the container rewrites out of the XWiki container, into a directory on the host.
    container=$(docker create xwiki:stable-postgres-tomcat)
    for file in hibernate.cfg.xml xwiki.cfg xwiki.properties; do
      docker cp "$container:/usr/local/tomcat/webapps/ROOT/WEB-INF/$file" /my/xwiki/config/path/
    done
    docker rm "$container"
  2. Set read_only on the web service of docker-compose.yml, bind-mount those three files, and add a tmpfs mount for each directory that Tomcat and LibreOffice write to.
    [...]
    services:
      web:
        image: "xwiki:stable-postgres-tomcat"
        read_only: true
        [...]
        volumes:
          # The permanent directory, which also holds the temporary directory XWiki and Tomcat write to.
          - xwiki-data:/usr/local/xwiki
          # The configuration files, rewritten from the environment variables on every start.
          - /my/xwiki/config/path/hibernate.cfg.xml:/usr/local/tomcat/webapps/ROOT/WEB-INF/hibernate.cfg.xml
          - /my/xwiki/config/path/xwiki.cfg:/usr/local/tomcat/webapps/ROOT/WEB-INF/xwiki.cfg
          - /my/xwiki/config/path/xwiki.properties:/usr/local/tomcat/webapps/ROOT/WEB-INF/xwiki.properties
        tmpfs:
          # Tomcat's own log files, work directory and generated context descriptors.
          - /usr/local/tomcat/logs
          - /usr/local/tomcat/work
          - /usr/local/tomcat/conf/Catalina
          # The temporary directory and the home directory of the container's user, which LibreOffice
          # both write to.
          - /tmp
          - /root
    [...]
    volumes:
      [...]
      xwiki-data: {}
  3. Start the containers with docker compose up -d.
  4. Check that the log of the web service reports no read-only error, with docker compose logs web | grep -i read-only.

Don't forget to replace /my/xwiki/config/path with your own directory, and the postgres part of the image tag with the database you use.

FAQ

Why does the log warn that the .first_start_completed marker cannot be created?

That marker is written in the read-only webapp directory, so the container configures XWiki again on every start. The operation is idempotent, so it has no other consequence.

Can XWiki still be deployed under a custom context path?

No, because CONTEXT_PATH makes the container create a directory inside the read-only webapps directory. Map the wanted path outside the container instead, with a Tomcat context file, a Tomcat RewriteValve, or a reverse proxy.

Is it enough to put the configuration files in the permanent directory?

No, because the container rewrites them at their WEB-INF paths before it reads the permanent directory, so they must be bind-mounted there.

Why must /tmp and the home directory of the container's user be writable?

LibreOffice, which XWiki starts for office import and export, writes to both and fails to start without them.

Does this work with Docker Run?

Yes, with the equivalent --read-only and --tmpfs flags.

Related

Get Connected