Giter Club home page Giter Club logo

docker-existdb's Introduction

Dockerfile for eXist-db 4.x.x

Minimal eXist-db 4.x.x Docker Image with XSL:FO support

Test Codacy Badge License


!! NOTICE !!

This GitHub repository is only suitable for use with eXist-db 4.x.x. If you are using eXist-db 5.x.x, or newer then you should be aware that the Docker Image build process is now part of the eXist-db build itself, see: https://github.com/eXist-db/exist/tree/develop/exist-docker. You can find all images on DockerHub.


This repository holds the source files for building a minimal docker image of the exist-db XML Native Database, automatically building from eXist's source code repo. It uses Google Cloud Platforms "Distroless" Docker Images.

Requirements

For test development only:

How to use

Pre-build images are available on DockerHub. There are two channels:

To download the image run:

docker pull existdb/existdb:latest

once the download is complete, you can run the image

docker run -it -d -p 8080:8080 -p 8443:8443 --name exist existdb/existdb:latest

What does this do?

  • -dit: Detaches the container from the terminal that started it (d). So your container won't stop when you close the terminal, allocates a TTY (t), and keeps STDIN open (i). This allows you to interact with the running Docker container via your console.
  • -p maps the Containers internal and external port assignments (we recommend sticking with matching pairs). This allows you to connect to the eXist-db Web Server running in the Docker container.
  • --name lets you provide a name (instead of using a randomly generated one)

The only required parts are docker run existdb/existdb. For a full list of available options see the official Docker documentation

After running the pull and run commands, you can access eXist-db via localhost:8080 in your browser.

To stop the container issue:

docker stop exist

or if you omitted the -d flag earlier press CTRL-C inside the terminal showing the exist logs.

Interacting with the running container

You can interact with a running container as if it were a regular Linux host (without a shell in our case). You can issue shell-like commands to the Java admin client, as we do throughout this readme, but you can't open the shell in interactive mode.

The name of the container in this readme is exist:

# Using java syntax on a running eXist-db instances
docker exec exist java -jar start.jar client --no-gui --xpath "system:get-memory-max()"

# Interacting with the JVM
docker exec exist java -version

Containers build from this image run a periodical health-check to make sure that eXist-db is operating normally. If docker ps reports unhealthy you can get a more detailed report with this command:

docker inspect --format='{{json .State.Health}}' exist

Logging

There is a slight modification to eXist's logger to ease access to the logs via:

docker logs exist

This works best when providing the -t flag when running an image.

Use as base image

A common usage of these images is as a base image for your own applications. We'll take a quick look at three scenarios of increasing complexity, to demonstrate how to achieve common tasks from inside Dockerfile.

A simple app image

The simplest and straightforward case assumes that you have a .xar app inside a build folder on the same level as the Dockerfile. To get an image of an eXist-db instance with your app installed and running, simply adopt the docker cp ... command to the appropriate Dockerfile syntax.

FROM existdb/existdb:4.5.0

COPY build/*.xar /exist/autodeploy

You should see something like this:

Sending build context to Docker daemon  4.337MB
Step 1/2 : FROM existdb/existdb:release
 ---> 3f4dbbce9afa
Step 2/2 : COPY build/*.xar /exist/autodeploy
 ---> ace38b0809de

The result is a new image of your app installed into eXist-db. Since you didn't provide further instructions it will simply reuse the EXPOSE, CMD, HEALTHCHECK, etc instructions defined by the base image. You can now publish this image to a docker registry and share it with others.

A slightly more complex single stage image

The following example will install your app, but also modify the underlying eXist-db instance in which your app is running. Instead of a local build directory, we'll download the .xar from the web, and copy a modified conf.xml from a src/ directory along side your Dockerfile. To execute any of the docker exec … style commands from this readme, we need to use RUN.

FROM existdb/existdb

# NOTE: this is for syntax demo purposes only
RUN ["java", "-jar", "start.jar", "client", "--no-gui", "-l", "-u", "admin", "-P", "", "-x", "sm:passwd('admin','123')"]

# use a modified conf.xml
COPY src/conf.xml /exist

ADD https://github.com/eXist-db/documentation/releases/download/4.0.4/exist-documentation-4.0.4.xar /exist/autodeploy

The above is intended to demonstrate the kind of operations available to you in a single stage build. For security reasons more elaborate techniques for not sharing your password in the clear are highly recommended, such as the use of secure variables inside your CI environment. However, the above shows you how to execute the Java Admin Client from inside a Dockerfile, which in turn allows you to run any XQuery code you want when modifying the eXist-db instance that will ship with your images. You can also chain multiple RUN commands.

As for the sequence of the commands, those with the most frequent changes should come last to avoid cache busting. Chances are, you wouldn't change the admin password very often, but the .xar might change more frequently.

Multi-stage builds

Lastly, you can eliminate external dependencies even further by using a multi-stage build. To ensure compatibility between different Java engines we recommend sticking with debian based images for the builder stage.

The following 2-stage build will download and install ant and nodeJS into a builder stage which then downloads frontend dependencies before building the .xar file. The second stage (each FROM begins a stage) is just the simple example from above. Such a setup ensures that non of your collaborators has to have java or nodeJS installed, and is great for fully automated builds and deployment.

# START STAGE 1
FROM openjdk:8-jdk-slim as builder

USER root

ENV ANT_VERSION 1.10.5
ENV ANT_HOME /etc/ant-${ANT_VERSION}

WORKDIR /tmp

RUN wget http://www-us.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz \
    && mkdir ant-${ANT_VERSION} \
    && tar -zxvf apache-ant-${ANT_VERSION}-bin.tar.gz \
    && mv apache-ant-${ANT_VERSION} ${ANT_HOME} \
    && rm apache-ant-${ANT_VERSION}-bin.tar.gz \
    && rm -rf ant-${ANT_VERSION} \
    && rm -rf ${ANT_HOME}/manual \
    && unset ANT_VERSION

ENV PATH ${PATH}:${ANT_HOME}/bin

WORKDIR /home/my-app
COPY . .
RUN apk add --no-cache --virtual .build-deps \
 nodejs \
 nodejs-npm \
 git \
 && npm i npm@latest -g \
 && ant


# START STAGE 2
FROM existdb/existdb:release

COPY --from=builder /home/my-app/build/*.xar /exist/autodeploy

EXPOSE 8080 8443

CMD [ "java", "-jar", "start.jar", "jetty" ]

The basic idea of the multi-staging is that everything you need for building your software should be managed by docker, so that all collaborators can rely on one stable environment. In the end, and after how ever many stages you need, only the files necessary to run your app should go into the final stage. The possibilities are virtually endless, but with this example and the Dockerfile in this repo you should get a pretty good idea of how you might apply this idea to your own projects.

Development use via docker-compose

This repo provides a docker-compose.yml for use with docker-compose. We highly recommend docker-compose for local development or integration into multi-container environments. For options on how to configure your own compose file, follow the link at the beginning of this paragraph.

To start exist using the compose file, type:

# starting eXist-db
docker-compose up -d
# stop eXist-db
docker-compose down

The compose file provided by this repo, declares two named volumes:

  • exist-data so that any database changes persist through reboots.
  • exist-config so you can configure eXist startup options.

Both are declared as mount volumes. If you wish to modify an eXist-db configuration file, use e.g.:

# - use docker `cp` to copy file from the eXist container
docker cp exist:exist/config/conf.xml ./src/conf.xml

# - alter the configuration item in the file
# - use docker `cp` to copy file back into the exist container

docker cp ./src/conf.xml exist:exist/config

# - stop and restart container to see your config change take effect
docker-compose down && docker-compose up -d

You can configure additional volumes e.g. for backups, or additional services such as an nginx reverse proxy by modifying the docker-compose.yml, to suite your needs.

To update the exist-docker image from a newer version

docker-compose pull

Caveat

As with normal installations, the password for the default dba user admin is empty. Change it via the usermanager or set the password to e.g. 123 from docker CLI:

docker exec exist java -jar start.jar client -q -u admin -P '' -x 'sm:passwd("admin", "123")'

For production uses you can find further security related recommendations for working with docker at this cheatsheet. We strongly encourage users to consult exist-db's official recommendations for production systems as well.

Building the Image

To build the docker image run:

docker build .

or, to build the debug docker image run:

docker build -f Dockerfile-DEBUG .

To build a specific version of eXist-db Docker image, you can do something like:

docker build --build-arg BRANCH=develop-4.x.x --tag existdb/existdb:4.x.x-SNAPSHOT .

or to build a specific version of the debug eXist-db Docker image, you can do something like:

docker build --build-arg BRANCH=develop-4.x.x --tag existdb/existdb:4.x.x-SNAPSHOT-DEBUG -f Dockerfile-DEBUG .

This will build an eXist-db image with sensible defaults as specified in the Dockerfile. The image uses a multi-stage building approach, so you can customize the compilation of eXist-db, or the final image.

To interact with the compilation of eXist-db you should build the first stage, make your changes and commit them, i.e.:

docker build --target builder .
# Do your thing…
docker commit…

Available Arguments and Defaults

eXist-db's cache size and maximum brokers can be configured at build time using the following syntax.

docker build --build-arg MAX_CACHE=312 MAX_BROKER=15 .

NOTE: Due to the fact that the final images does not provide a shell, setting ENV variables for eXist-db has no effect.

# !This has no effect!
docker run -it -d -p8080:8080 -e MAX_BROKER=10 ae4d6d653d30

If you wish to permanently adopt a customized cache or broker configuration, you can simply make a local copy of the Dockerfile and edit the default values there.

ARG MAX_BROKER=10

There are two ways to modify eXist-db's configuration files:

  • The recommended method is to use xmlstarlet in the first build stage, as in the example below, which changes the default logging configuration to a more suitable setting for use with docker. By using this method you can be sure to always be up-to-date with changes to the officially released configuration files.
# Config files are modified here
RUN echo 'modifying conf files'\
&& cd $EXIST_MIN/config \
&& xmlstarlet ed  -L -s '/Configuration/Loggers/Root' -t elem -n 'AppenderRefTMP' -v '' \
 -i //AppenderRefTMP -t attr -n 'ref' -v 'STDOUT'\
 -r //AppenderRefTMP -v AppenderRef \
 log4j2.xml
  • As a convenience, we have added the main configuration files to the /src folder of this repo. To use them, make your changes and uncomment the following lines in the Dockerfile. To edit additional files, e.g. conf.xml, simple add another COPY line. While it is easier to keep track of these files during development, there is a risk that the local file is no longer in-sync with those released by eXist-db. It is up to users to ensure their modifications are applied to the correct version of the files, or if you cloned this repo, that they are not overwritten by upstream changes.
# Optionally add customised configuration files
#  COPY ./src/log4j2.xml $EXIST_MIN/config

These files only serve as a template. While upstream updates from eXist-db to them are rare, such upstream changes will be immediately mirrored here. Users are responsible to ensure that local changes in their forks / clones persist when syncing with this repo, e.g. by rebasing their own changes after pulling from upstream.

JVM configuration

This image uses an advanced JVM configuration, via the JAVA_TOOL_OPTIONS env variable inside the Dockerfile. You should avoid the traditional way of setting the heap size via -Xmx arguments, this can lead to frequent crashes since Java and Docker are (literally) not on the same page concerning available memory.

Instead, use the -XX:MaxRAMFraction=1 argument to modify the memory available to the JVM inside the container. For production use we recommend to increase the value to 2 or even 4. This value expresses a ratio, so setting it to 2 means half the container's memory will be available to the JVM, '4' means ¼, etc.

To allocate e.g. 600mb to the container around the JVM use:

docker run -m 600m …

Lastly, this image uses a new garbage collection mechanism garbage first (G1) -XX:+UseG1GC and string deduplication -XX:+UseStringDeduplication to improve performance.

To disable or further tweak these features edit the relevant parts of the Dockerfile, or when running the image. As always when using the latest and greatest, YMMV. Feedback about real world experiences with this features in connection with eXist-db is very much welcome.

docker-existdb's People

Contributors

adamretter avatar dizzzz avatar duncdrum avatar grantmacken avatar sincopy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-existdb's Issues

build.sh redundant code

Took a quick look at build.sh
I think this could do with a bit of a clean up.
It is now used inside docker, so stuff like

# Either get or update from GitHub eXist-db

is redundant.
Most likely, build.sh could be removed all together,
with everything going into the build target.

docker-compose create named network

Small adjustment to docker compose

networks:
  www:
    name: www
    driver: bridge

Naming network allows multiple eXist instances to be attached to same network.
i.e. new IP address is assign, so you don't have to stop your existing eXistdb running container.
Found this handy when developing newBase60 lib,
which uses a totally ephemeral container (no volume binds) for developing the lib

example of attaching to existing network ( note port number )

version: '3.4'
services:
  exDev-newBase60:
    image: $DOCKER_IMAGE:$DOCKER_TAG
    container_name: eXdev
    ports:
      - 8282:8080

docker-compose override
To be used locally (not on travis)

version: '3.4'
networks:
  default:
    external:
      name: www

running tests locally

#30 @adamretter

Also, perhaps it is better to extract the shell scripts from .travis.yml into a separate shell script. With a separate shell script, we can then also run the tests locally, and we can easily check and validate any syntax errors.

As it stands now, the script blocks run sequentially,.
Each travis script block should either succeed or fail,
When the script block fails, the travis build will fail
What I think I could do is

  • extract each script block as a test-fixture (a stand alone bash script)
  • create tests dir t , write tap tests, that check the output of the scripts err code and data

This way we could test locally (and in travis ), by calling prove and getting a nice tap report.
A setup and tear down stage could be done via simple Makefile

test:
   docker-compose up d
   prove
   docker-compose down

duplicate code in build.sh and hooks

there is some (harmless) code duplication between what the hooks do, and what happens in build.sh.
I actually don't care where we do this, but we should cleanup afterwards.

Dockerfile-minimal

Dockerfile-minimal , this won't build, I think it depended on build.sh.
My suggestion remove.
If we want targeted minimal build, add a phased target in the multi staged Dockerfile

docker build --target='min' --tag ${DOCKER_IMAGE}:min-v3.2.1

how to go about backup and restore

I see a number of ways we might go about baking backup and restore into the images. As this is pretty much the last big feature I'd like to add, I'm curious to hear opinions on which way to go.

Current situation:
User is on :release which is exist-db 4.x, once 5.x (a binary incompatible) major upgrade is out, just running:
docker pull existdb/existdb:release will create a broken instance.

Ideally, I would like it to trigger a backup and restore

we could:

  • tweak conf.xml's backup job
 <job type="system" name="check1" 
            class="org.exist.storage.ConsistencyCheckTask"
            cron-trigger="0 0 * * * ?">
  <parameter name="output" value="export"/>
  <parameter name="backup" value="yes"/>
  <parameter name="incremental" value="no"/>
  <parameter name="incremental-check" value="no"/>
  <parameter name="max" value="2"/>
</job>

to kick the db into recovery mode, assuming we also made sure that automatic backups were created in the first place, e.g. by using ONBUILD

  • include a call to an external script in docker-compose.yml so backup restore becomes the default when performing
docker-compose pull

this would go along with setting a restart_policy, rollback_config, and update_config and updating the docker-compose file version to 3.7.

  • (least favourite option) passing responsibility on to the user, with some instructions in the readme , something along the lines of:
docker exec exist java -jar start.jar -u admin -p admin-pass -b /db -d /exist-backup -ouri=xmldb:exist://192.168.1.2:80/xmlrpc'

(that last parameter will need some tweaking to work within the container network)

In either scenario, backups should happen to their own volume, so that one is a given in my mind.

:release and :latest have different EXIST_HOME env

release has exist
latest has eXist

no clue how this happened, but we should harmonize. As it stands the same docker commands should work on both channels, they do not. Furthermore, once 5.0.0 is the new stable the paths would change anyways. So better to make the jump now for :latest imv, which would keep :release stable.

Still I cannot guarantee that this will have 0 fallout for users, so apologies in advance.

smoke tests for travis

We can do simple smoke tests,
by making each script line fail or succeed via exit codes

e.g. At the moment the script line only shows

  • docker logs exist

revised smoke test - eXist should start

  • docker logs exist | grep 'Server has started'

upload xquery to an image

I want to upload my xquery to a new image without using volumes.
There is an easy way to do it? the best idea is to autoupload an .xar file.

Runtime args

At the moment the Java runtime args are set in the dockerfile as the build env. I think it would be best to leave these out as they depend on the host environment. Instead use docker-compose to set these.

SHELL command and Java Admin Client

So while doing the readme updates i played some more with the SHELL directive for docker files. The good news first:

FROM existdb/existdb

SHELL ["java"]

RUN -version

This works, and produces:

Step 1/4 : FROM existdb/existdb
 ---> 85d5983d5020
Step 2/4 : SHELL ["java"]
 ---> Running in c14c825171eb
Removing intermediate container c14c825171eb
 ---> 8c3ef1e84064
Step 3/4 : RUN -version
 ---> Running in e7ad6accb70e
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8   -Djava.awt.headless=true   -Dorg.exist.db-connection.cacheSize
=256M   -Dorg.exist.db-connection.pool.max=20   -XX:+UnlockExperimentalVMOptions   -XX:+UseCGroupMemoryLimitForHea
p   -XX:+UseG1GC   -XX:+UseStringDeduplication   -XX:MaxRAMFraction=1
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)

all good. By the same token this works as expected as well:

FROM existdb/existdb

SHELL ["java", "-jar","start.jar", "client", "--no-gui"]

RUN -l 

So, i would expect the following to also work:

FROM existdb/existdb

SHELL ["java", "-jar","start.jar", "client", "--no-gui"]

RUN -l -u admin -P "" -x sm:passwd("admin","123")

Yet, it produces (shortened for readability):

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM existdb/existdb
 ---> 85d5983d5020

Step 2/4 : SHELL ["java", "-jar","start.jar", "client", "--no-gui"]
 ---> Running in 6e12f0d98548
Removing intermediate container 6e12f0d98548
 ---> be4e190e4800
Step 3/4 : RUN -l -u admin -P "" -x "sm:passwd('admin','123')"
 ---> Running in 29e6d9451921
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8   -Djava.awt.headless=true   -Dorg.exist.db-connection.cacheSize
=256M   -Dorg.exist.db-connection.pool.max=20   -XX:+UnlockExperimentalVMOptions   -XX:+UseCGroupMemoryLimitForHea
p   -XX:+UseG1GC   -XX:+UseStringDeduplication   -XX:MaxRAMFraction=1
…

so far so good, however:

…
Unexpected argument: -l -u admin -P "" -x "sm:passwd('admin','123')", previous argument: --no-gui
Usage: Main [Arguments]

Arguments:
-c, --collection <string>                  set target collection.
                                           <string>: any string
                                           Default:
-C, --config <path>                        specify alternate configuration
                                           file. Implies -l.
                                           <path>: a file path
                                           Default: /exist/.
-d, --recurse-dirs                         recurse into subdirectories during
                                           index?
                                           Default: disabled
[…]
The command 'java -jar start.jar client --no-gui -l -u admin -P "" -x sm:passwd("admin","123")' returned a non-zero code: 3

So the client is responding just not how I expect it to. I have tried different iterations of json escaping the RUN command and reshuffle the split between SHELL and RUN, e.g. only go up to -jar in SHELL and execute the rest from RUN but no joy.

I guess one could address exist.jar directly and use the -Dorg.exist.db… syntax here as well, but imv the above example should work, or am i missing something. Given that the JAC "dumb shell" is coming up and executing -l there should be away to, e.g. also do mkcol hamlet or what not.

It possible that this is a string escaping problem with docker, but its also possible that our JAC shell is still not 100% any input welcome, i m kind of stuck why the last example doesn't work but the others do.

The workaround is to simply not use SHELL and stick to long json escaped RUN commands, ie.:

FROM existdb/existdb

RUN ["java", "-jar", "start.jar", "client", "--no-gui", "-l", "-u", "admin", "-P", "", "-x", "sm:passwd('admin','123')"]

Dockerfile build-args outline

Here is a proposal of what build-args should be provided in the Dockerfile

@arg VERSION - can be stable or RC e.g. '4.3.1'
- this a requirement of hooks/build, see notes below
@arg BRANCH - branch can be a
- branch name e.g release,develop, name-of-branch
- tagged commit e.g. eXist-4.3.1
- any commit hash ( short or long )
e.g 3b19579, 3b195797a2c2f35913891412859b06d94f189229
@arg BUILD_DATE
@arg VCS_REF
@arg CACHE_MEM
@arg MAX_BROKER

NOTES:
VERSION, BUILD_DATE, VCS_REF build-args are created via a dockerhub build hook in hooks/build
CACHE_MEM, MAX_BROKER build args are available, if you want to override the defaults

Build process - build-args provided via docker build are optional.

  1. if build-arg VERSION is empty, then version is ignored
  2. if build-arg BRANCH is empty then defaults to develop

core os and xmlrpc

i m getting xmldb.jar not found when trying to connect oxygen to :release container running on stable coreOS, not yet sure whats going on.

The container reports unhealthy with more xmlrpc related errors (bit hard to copy the logs)
screenshot 2018-12-20 at 16 30 47

Further configuration tweaks to conf.xml

The following line is giving me pause:

<watchdog output-size-limit="1000000" query-timeout="-1"/>
  • query-timeout while convenient, it means that orchestrators will probably keep a dead node around potentially indefinitely. I think in a container context this should have high positive value.

Similarly,

<recovery enabled="yes"  group-commit="no"   journal-dir="webapp/WEB-INF/data"
                  size="100M" sync-on-commit="no"  force-restart="no"  consistency-check="yes"/>
  • sync-on-commit My intuition (need to do some testing on this) is that sync-on-commit might actually speed up things in containerland, but I'm not sure how it would play out in different orchestration scenarios, what if a worker node never reaches the threshold?

  • Enabling force-restart on the other hand might make sense, since new instances are created and killed much more frequently compared to traditional server contexts.

create a working 4.X branch

we might need to revert some of the 5.0.0 changes to get release images for the 4.x branch to work properly again.

Given how exist's main repo is doing things, keeping two separate branches here that mirror develop and master, seems the easiest solution. The alternative would be to create subfolders in the root here with individual docker files, build.sh, … which need to be synced at the right time… not my preferred choice.

java-admin-client acting weird

docker exec exist java -jar start.jar client --no-gui
results in an endless stream of exist:/db> to be put into the calling shell.

Am i doing it wrong, or whats going on?

cleanup LABELs

we have the same label-schema.org labels in a number of places, lets not repeat ourselves.
Most should go into hooks, imv, but some like description should stay in the dockerfile.

new ram syntax

just a reminder for JDK#8187125 XX:MaxRAMFraction is deprecated. if the gcr base image is updated we'll have to -XX:MaxRAMPercentage

500 error loading dashboard

Hi.

Trying latest tag. Copied all xml files from the config folder, created a docker-compose up, and I am getting these errors.

Any help is welcome.

HTTP ERROR 500

Problem accessing /exist/apps/dashboard/. Reason:

    Server Error

Caused by:

javax.servlet.ServletException: javax.servlet.ServletException: An error occurred while processing request to /exist/apps/dashboard/: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:753)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:502)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
	at java.lang.Thread.run(Thread.java:748)
Caused by: javax.servlet.ServletException: An error occurred while processing request to /exist/apps/dashboard/: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:371)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:859)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
	... 16 more
Caused by: org.exist.xquery.XPathException: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.exist.xquery.FunctionFactory.getInternalModuleFunction(FunctionFactory.java:294)
	at org.exist.xquery.FunctionFactory.functionCall(FunctionFactory.java:261)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:94)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:55)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:51)
	at org.exist.xquery.parser.XQueryTreeParser.functionCall(XQueryTreeParser.java:11190)
	at org.exist.xquery.parser.XQueryTreeParser.primaryExpr(XQueryTreeParser.java:7776)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3561)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3082)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:420)
	at org.exist.xquery.parser.XQueryTreeParser.functionDecl(XQueryTreeParser.java:6201)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5333)
	at org.exist.xquery.parser.XQueryTreeParser.libraryModule(XQueryTreeParser.java:4030)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3861)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQueryContext.compileModule(XQueryContext.java:2484)
	at org.exist.xquery.XQueryContext.compileOrBorrowModule(XQueryContext.java:2425)
	at org.exist.xquery.XQueryContext.importModule(XQueryContext.java:2378)
	at org.exist.xquery.parser.XQueryTreeParser.importDecl(XQueryTreeParser.java:6312)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5340)
	at org.exist.xquery.parser.XQueryTreeParser.mainModule(XQueryTreeParser.java:4042)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3987)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQuery.compile(XQuery.java:128)
	at org.exist.xquery.XQuery.compile(XQuery.java:79)
	at org.exist.xquery.XQuery.compile(XQuery.java:71)
	at org.exist.http.urlrewrite.XQueryURLRewrite.runQuery(XQueryURLRewrite.java:669)
	at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:243)
	... 34 more

Caused by:

javax.servlet.ServletException: An error occurred while processing request to /exist/apps/dashboard/: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:371)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:859)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:753)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:502)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.exist.xquery.XPathException: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.exist.xquery.FunctionFactory.getInternalModuleFunction(FunctionFactory.java:294)
	at org.exist.xquery.FunctionFactory.functionCall(FunctionFactory.java:261)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:94)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:55)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:51)
	at org.exist.xquery.parser.XQueryTreeParser.functionCall(XQueryTreeParser.java:11190)
	at org.exist.xquery.parser.XQueryTreeParser.primaryExpr(XQueryTreeParser.java:7776)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3561)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3082)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:420)
	at org.exist.xquery.parser.XQueryTreeParser.functionDecl(XQueryTreeParser.java:6201)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5333)
	at org.exist.xquery.parser.XQueryTreeParser.libraryModule(XQueryTreeParser.java:4030)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3861)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQueryContext.compileModule(XQueryContext.java:2484)
	at org.exist.xquery.XQueryContext.compileOrBorrowModule(XQueryContext.java:2425)
	at org.exist.xquery.XQueryContext.importModule(XQueryContext.java:2378)
	at org.exist.xquery.parser.XQueryTreeParser.importDecl(XQueryTreeParser.java:6312)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5340)
	at org.exist.xquery.parser.XQueryTreeParser.mainModule(XQueryTreeParser.java:4042)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3987)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQuery.compile(XQuery.java:128)
	at org.exist.xquery.XQuery.compile(XQuery.java:79)
	at org.exist.xquery.XQuery.compile(XQuery.java:71)
	at org.exist.http.urlrewrite.XQueryURLRewrite.runQuery(XQueryURLRewrite.java:669)
	at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:243)
	... 34 more

Caused by:

org.exist.xquery.XPathException: err:XPST0017 error found while loading module login: Error while loading module resource:org/exist/xquery/modules/persistentlogin/login.xql: Function xmldb:is-admin-user()  is not defined in module namespace: http://exist-db.org/xquery/xmldb [at line 78, column 24]
	at org.exist.xquery.FunctionFactory.getInternalModuleFunction(FunctionFactory.java:294)
	at org.exist.xquery.FunctionFactory.functionCall(FunctionFactory.java:261)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:94)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:55)
	at org.exist.xquery.FunctionFactory.createFunction(FunctionFactory.java:51)
	at org.exist.xquery.parser.XQueryTreeParser.functionCall(XQueryTreeParser.java:11190)
	at org.exist.xquery.parser.XQueryTreeParser.primaryExpr(XQueryTreeParser.java:7776)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3561)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:3082)
	at org.exist.xquery.parser.XQueryTreeParser.expr(XQueryTreeParser.java:420)
	at org.exist.xquery.parser.XQueryTreeParser.functionDecl(XQueryTreeParser.java:6201)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5333)
	at org.exist.xquery.parser.XQueryTreeParser.libraryModule(XQueryTreeParser.java:4030)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3861)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQueryContext.compileModule(XQueryContext.java:2484)
	at org.exist.xquery.XQueryContext.compileOrBorrowModule(XQueryContext.java:2425)
	at org.exist.xquery.XQueryContext.importModule(XQueryContext.java:2378)
	at org.exist.xquery.parser.XQueryTreeParser.importDecl(XQueryTreeParser.java:6312)
	at org.exist.xquery.parser.XQueryTreeParser.prolog(XQueryTreeParser.java:5340)
	at org.exist.xquery.parser.XQueryTreeParser.mainModule(XQueryTreeParser.java:4042)
	at org.exist.xquery.parser.XQueryTreeParser.module(XQueryTreeParser.java:3987)
	at org.exist.xquery.parser.XQueryTreeParser.xpath(XQueryTreeParser.java:3642)
	at org.exist.xquery.XQuery.compile(XQuery.java:128)
	at org.exist.xquery.XQuery.compile(XQuery.java:79)
	at org.exist.xquery.XQuery.compile(XQuery.java:71)
	at org.exist.http.urlrewrite.XQueryURLRewrite.runQuery(XQueryURLRewrite.java:669)
	at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:243)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:859)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:753)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:502)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
	at java.lang.Thread.run(Thread.java:748)

Powered by Jetty:// 9.4.14.v20181114 

Newbie impressions

Following the instructions in the README, I hit a roadblock on the line:

docker stop exist

When I ran this after starting the image via the supplied command, I got an error:

$ docker run -it -d -p 8080:8080 -p 8443:8443 existdb/existdb:release
9b875fa2e58ea558ad55fd13bb08bf31baaa3864b5e8ff70974ab5524dbb36d6
$ docker stop exist
Error response from daemon: No such container: exist

Upon further research, I see that when starting docker without a --name flag, docker assigns a random name to the container:

$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                            PORTS                                            NAMES
9b875fa2e58e        existdb/existdb:release   "java -jar start.jar…"   6 seconds ago       Up 5 seconds (health: starting)   0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->8443/tcp   inspiring_euclid

Here, inspiring_euclid is the container's randomly-generated name. To stop this container you'd need to use this name or the container ID (9b875fa2e58e):

$ docker stop inspiring_euclid
inspiring_euclid

Given this, I think the instructions would generally work if modified to include a --name exist parameter to docker run:

$ docker run -it -d -p 8080:8080 -p 8443:8443 --name exist existdb/existdb:release
a01a78c15fc17804d961052310c41e31e3ac6b14f0b6c732da05b63a37086d22
$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                            PORTS                                            NAMES
a01a78c15fc1        existdb/existdb:release   "java -jar start.jar…"   2 seconds ago       Up 2 seconds (health: starting)   0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->8443/tcp   exist
$ docker stop exist
exist
$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                        PORTS               NAMES
438fb56ed789        existdb/existdb:release   "java -jar start.jar…"   8 seconds ago       Exited (143) 1 second ago                         exist
$ docker rm exist
exist
$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                        PORTS               NAMES

Next, following the directions in the README under "Development use via docker-compose", I think new users will hit the same thing I did:

$ docker-compose up -d
ERROR: 
        Can't find a suitable configuration file in this directory or any
        parent. Are you in the right directory?

        Supported filenames: docker-compose.yml, docker-compose.yaml

Is the idea that in order to use docker-compose you should first clone the docker-existdb repo, cd into it, and then run this command? If not, what are the assumed setup steps before docker-compose can be run?

Next, the README states that the compose file declares 2 named volumes (exist-data and exist-config), but the docker cp commands refer to exist:eXist. How do the docker cp commands know which volume(s) exist:eXist corresponds to?

Lastly, I'd be grateful for any opinionated links to tutorials for becoming proficient with docker and getting the most out of this image.

Dockerfile redundant build stage

I think we can reduce Dockerfile to a 2 stage build.

FROM openjdk:8-jdk-alpine as builder
...
FROM openjdk:8-jdk-slim as jdk
...
FROM gcr.io/distroless/java:latest

to

FROM openjdk:8-jdk-slim as jdk
RUN apt-get ...
...
FROM gcr.io/distroless/java:latest

Besides, when using the alpine to build, the Alpine JDK is using Musl,
but with gcr.io/distroless/java:latest and openjdk:8-jdk-slim, Glibc is used.
Whether this makes any difference, is beyond me, however if we start from
openjdk:8-jdk-slim , we wont have to worry.

Created branch
Dockerfile adjustment tasks

  • Start with openjdk-slim
  • Remove Dynamic Labels - they can be defined at build time
  • Version ARG as tag name is only arg required at build time
  • Version ARG can be a stable or RC release tag
  • its quicker to build if we don't use git but grab the release tar
  • use apt to get stuff for FOP
  • turn build.sh shell cmds process logic into a single RUN
  • move config files into config dir then symlink to origin
  • leave data dir in default position - it's a separate volume anyway
  • for customized config files use COPY not ADD

docker-compose.yml adjustment tasks

  • add config volume

Can't autodeploy application xar application with ft-client dep

Hi,
Please find attached an application that is not properly-deployed using next line:

docker run -p 8080:8080 -v $PWD/build/test-ft-client-autodeploy-0.1.xar:/exist/autodeploy/test-ft-client-autodeploy-0.1.xar existdb/existdb:4.5.0

If you comment the ft-client dependency line in the expath-pkg.xml, the deployement works. Then you need to install on the existdb instance the ft-client (using package manager or xquery cmd)

Hey ! Github does not yet know xar extension ;) I then replace the file name extension from .xar to .zip
test-ft-client-autodeploy-0.1.zip

Hope you can make that more flexible than what it already is ;)

Big thanks in advance,

Guillaume

maven directory changes

New maven based layout for exist-db,
will require an update of the copy operations
and perhaps the sym linking of the config files,
in the Dockerfile.

I have opened this issue to check list and discuss what is required

What to do with configuration files

eXist has various config files in different locations. I don't think we should expect the user to clone this repo, adjust the configs then do a build.

My suggestion is we bundle the configs into a single directory in the image and symlink to original eXist locations.

The config directory could then be a mount volume, so the changes made to a config file would persist beyond stopping and starting the container.

Release strategy and release tagging

Just to clarify.
Each eXist release should have a corresponding docker tagged release version.
The only arg needed for the docker build is the eXist release version
The version tagged latest should be the should be the stable version not the RC version?

use travis for tagging

while the webhooks that trigger builds on docker hub are coming from the main repo and include the git tag names there, we don't have the same over here. There doesn't seem to be a sane way of telling docker hub to use repo A to build repo B using tag A.

To avoid having to manually push git tags here with the appropriate version strings, we can probably leverage travis for this here. Dockerhub then reads our git tag names, and create the matching image tags.

alternatively, we could let commits in the main repo trigger travis here and move the docker tagging logic into the deploy step. In either case, some travis fiddling is in order.

docker-compose persistence problem

I am not able to persist any data over container restarts.
Demonstration:

docker-compose.yaml:

version: '3'

services:

  xmldb:
    image: existdb/existdb:latest
    container_name: xmldb
    volumes:
      - ./res:/eoa/res
      - ./runtime_data/exist_data:/exist-data
    # just for debugging:
    ports:
      - 8443:8443
      - 8080:8080
  ...

Now when i issue these commands ...

$ docker-compose up -d xmldb
Creating network "eoa2-xmldb_default" with the default driver
Creating xmldb ... done
$ docker-compose exec xmldb java -jar start.jar client --no-gui
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8   -Djava.awt.headless=true   -Dorg.exist.db-connection.cacheSize=256M   -Dorg.exist.db-connection.pool.max=20   -XX:+UnlockExperimentalVMOptions   -XX:+UseCGroupMemoryLimitForHeap   -XX:+UseG1GC   -XX:+UseStringDeduplication   -XX:MaxRAMFraction=1
eXist version 5.0.0-SNAPSHOT (1648d512c), Copyright (C) 2001-2019 The eXist-db Project
eXist-db comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; for details read the license file.

Connecting to database...
Connected :-)

type help or ? for help.
exist:/db> mkcol testcreated collection.
exist:/db> ls
crwxr-xr-x      SYSTEM  dba     Thu Jan 31 13:52:10 GMT 2019    system
crwxr-xr-x      SYSTEM  dba     Thu Jan 31 13:52:12 GMT 2019    apps
crwxr-xr-x      admin   dba     Thu Jan 31 13:59:16 GMT 2019    test
exist:/db> quit
quit.
31 Jan 2019 13:59:43,259 [global.BrokerPools.ShutdownHook] INFO  (BrokerPools.java [lambda$static$0]:68) - Executing shutdown thread

no data is saved in my volume:

$  ls -Al  runtime_data/exist_data/
insgesamt 0

also, when restarting the container, all settings are lost ( my collection test doesn't exist) !:

$ docker-compose down
Stopping xmldb ... done
Removing xmldb ... done
Removing network eoa2-xmldb_default
$ docker-compose up -d xmldb
Creating network "eoa2-xmldb_default" with the default driver
Creating xmldb ... done
$ docker-compose exec xmldb java -jar start.jar client --no-gui
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8   -Djava.awt.headless=true   -Dorg.exist.db-connection.cacheSize=256M   -Dorg.exist.db-connection.pool.max=20   -XX:+UnlockExperimentalVMOptions   -XX:+UseCGroupMemoryLimitForHeap   -XX:+UseG1GC   -XX:+UseStringDeduplication   -XX:MaxRAMFraction=1
eXist version 5.0.0-SNAPSHOT (1648d512c), Copyright (C) 2001-2019 The eXist-db Project
eXist-db comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; for details read the license file.

Connecting to database...
Connected :-)

type help or ? for help.
exist:/db> ls
crwxr-xr-x      SYSTEM  dba     Thu Jan 31 14:03:27 GMT 2019    system
crwxr-xr-x      SYSTEM  dba     Thu Jan 31 14:03:28 GMT 2019    apps
exist:/db>

What am I missing here?

functional tests for travis

The functional tests would be on a running container.
The tests would aim to show if the changes we have made to a normal eXist install,
( to suite docker) are working properly.

changes to config files

  • copy a config file to host
    => diff check that file in host is same as in container volume
  • copy different config file(s) into container
    => diff check that file in container volume is same as copied file
    => stop and start container then check if changed startup option has been applied

changes to logging
execute commands in with start.jar client

  • util:log() | grep => check stdout

more ..

Docker build for 5.0.0RC3 does not work

@zopyx commented on Aug 17, 2018, 8:41 AM UTC:

I tried to build the Docker image for the latest 5.0.0 RC release using

https://hub.docker.com/r/existdb/existdb/~/dockerfile/

and this fails:

Step 15/28 : COPY --from=builder /usr/lib/x86_64-linux-gnu/liblcms2.so.2.0.8 /usr/lib/x86_64-linux-gnu/liblcms2.so.2
---> 52ac0864623d
Step 16/28 : COPY --from=builder /usr/lib/x86_64-linux-gnu/libpng16.so.16.28.0 /usr/lib/x86_64-linux-gnu/libpng16.so.16
---> 03d41aae47bc
Step 17/28 : COPY --from=builder /etc/fonts /etc/fonts
---> d60068e64cc0
Step 18/28 : COPY --from=builder /lib/x86_64-linux-gnu/libexpat.so.1 /lib/x86_64-linux-gnu/libexpat.so.1
---> 8f9b65004e6d
Step 19/28 : COPY --from=builder /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.8.0 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
---> 7884dad8b9ad
Step 20/28 : COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig
---> 50e2f1af8b6e
Step 21/28 : COPY --from=builder /usr/share/fonts/truetype/dejavu /usr/share/fonts/truetype/dejavu
---> 3472725277a4
Step 22/28 : COPY ./src/log4j2.xml $EXIST_HOME/config
COPY failed: stat /var/lib/docker/tmp/docker-builder241324146/src/log4j2.xml: no such file or directory
Makefile:2: recipe for target 'build' failed
make: *** [build] Error 1

This issue was moved by duncdrum from eXist-db/exist#2122.

Problem with ws-commons-util-1.0.2.01.jar

Hello, there is an error with the namespaces, the jar ws-commons-util-1.0.2.01.jar corrects this error.
But this is a Distroless, in Dockerfile something like this does not work

FROM existdb/existdb:4.5.0
RUN rm $EXIST_HOME/lib/ws-commons-util-1.0.2.01.jar
COPY ws-commons-util-1.0.2.01.jar $EXIST_HOME/lib

How do i remove the jar?

xqm files not compiling and registering

When I upload a xqm file to this image it doesn't appear to register/compile. Can you advise? I am sorry I also can't understand how to access the logs inside this container and send on this as it doesn't have a shell I am familiar with. To repeat the error I put the xqm file in the db similar to this:

PUT .../exist/rest/db/forgot.xqm
content-type:application/xquery

The contents of forgot.xqm 'simplified' look like this

xquery version "3.0";
module namespace host = "http://host/service";
import module namespace rest = "http://exquery.org/ns/restxq";
declare
    %rest:POST
	%rest:path("/forgot")
    %rest:query-param("email", "{$email}")
	%rest:consumes("application/x-www-form-urlencoded")
	%rest:produces("text/html")
function host:function1($email) {
        let $doc := 
<Customer>
        <Metadata>
            <Created>{current-dateTime()}</Created>
        </Metadata>
        <Contact>
            <Email>{$email}</Email>
        </Contact>
    </Customer>
        return
            let $new-file-path := xmldb:store("/db/forgot", concat($email, '.xml'), $doc)
            return
                <html xmlns="http://www.w3.org/1999/xhtml">
                    <body>SUCCESS</body>
                </html>
};

And I POST this xqm along the lines:

POST http://host/forgot
email=[email protected]

But the resulting error is ERROR:
HTTP/1.1 404 Not Found

I guess it is not registering/compiling. This exact same process is working perfectly when I using many other versions of the database with appropriate permissions setup but interestingly not in the 'minimal' version of the evolved binary docker image although it also works fine with the bigger image there. This seems related to the behaviour I reported for the 'minimal' version of the evolved binary image:
evolvedbinary/docker-existdb#4

Problem connection with oxygen

I create an instance existdb/existdb:4.5.0. the port 8080 is mapped with 30088.
I tried to connect against xmldb:exist://localhost:30088/exist/xmlrpc but i have timeout connection.
I have to do some extra configuration?

repo commit tagsr re, tracking new directory layout

With 4.6 onward we are seeing files and directories moving around.

eXist-db/exist#2506

is copied to eXist-db\src\org\exist\util\mime-types.xml but should end in eXist-db\exist-core\src\main\resources (or we should git rid of the one in EXIST_HOME at all, of have it copied from the resources

Changes like this obviously effect, the way we build our docker image.
e.g In the above mentioned mime-types.xml this is symlinked from home to a special
docker specific config dir,

What I suggest we do is do a tagged commit for repo before 4.6
Then tag commit when ever we have to make changes to our Dockerfile

i.e.

  • repo tagged v0.0.1 provides Dockerfile suitable for building prior 4.6
  • repo tagged v0.0.2 provides Dockerfile suitable for building after 4.6

add cmd flag for skipping all default apps

This would come in handy when designing more minimal swarm nodes, or for our own CI setups.
Basically run a build with

use.autodeploy.feature=false

in local.properties from the docker cli.

something like this:

docker build --build-arg DEFAULT_XAR=false .

see #15

add dockerfile code listings to README

It is not clear to new users, that most of the docker … commands in our readme have a corresponding syntax for use inside a dockerfile.

Let's add these so users know how e.g. changing the admin pw looks from inside a docker file.

Building upon base layer

I want to argue the case, for keeping the base layer as simple as practicable and then layering use cases into tagged images.

Obviously, when it comes to docker images, size matters. Once you have a layer in place, it is easy to add/subtract stuff and give it a tag. You could say have a v3.4.1-teiPub tag with the eXist TEI Publisher env preinstalled.

The trick is deciding what should be in and what should be out of the base layer.
Please add suggestions, comments.

  • Out: /bin - reason: no shell
  • Out: /tests - reason: its all ready been tested

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.