{"id":17733861,"url":"https://github.com/duncdrum/distroless-exist","last_synced_at":"2025-06-16T09:03:09.081Z","repository":{"id":40432460,"uuid":"443341688","full_name":"duncdrum/distroless-exist","owner":"duncdrum","description":"Multi-arch distroless images for use with exist-db","archived":false,"fork":false,"pushed_at":"2025-05-19T16:02:17.000Z","size":239761,"stargazers_count":5,"open_issues_count":7,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-19T17:24:07.800Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duncdrum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-12-31T12:33:29.000Z","updated_at":"2025-05-07T13:46:27.000Z","dependencies_parsed_at":"2024-06-18T08:53:36.196Z","dependency_job_id":"8398b3b4-92cd-4116-8297-abd2d482b35c","html_url":"https://github.com/duncdrum/distroless-exist","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/duncdrum/distroless-exist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncdrum%2Fdistroless-exist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncdrum%2Fdistroless-exist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncdrum%2Fdistroless-exist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncdrum%2Fdistroless-exist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duncdrum","download_url":"https://codeload.github.com/duncdrum/distroless-exist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncdrum%2Fdistroless-exist/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260130704,"owners_count":22963427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-25T23:06:39.905Z","updated_at":"2025-06-16T09:03:09.060Z","avatar_url":"https://github.com/duncdrum.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eXist-db Docker Image\n\nMinimal Docker Image of eXist-db NoSQL Database Client/Server with FO support\n\n[![Java 21 :latest](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java21.yml/badge.svg)](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java21.yml)\n[![Java 11 :release](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java11.yml/badge.svg)](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java11.yml)\n[![Java 8 :release](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java8.yml/badge.svg)](https://github.com/duncdrum/distroless-exist/actions/workflows/ci-java8.yml)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/c5d7a02842dd4a3c85b1b2ad421b0d13)](https://www.codacy.com/app/eXist-db/exist?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=eXist-db/exist\u0026amp;utm_campaign=Badge_Grade)\n[![License](https://img.shields.io/badge/license-AGPL%203.1-orange.svg)](https://www.gnu.org/licenses/agpl-3.0.html)\n[![](https://images.microbadger.com/badges/image/duncdrum/existdb.svg)](https://microbadger.com/images/duncdrum/existdb \"Get your own image badge on microbadger.com\")\n[![](https://images.microbadger.com/badges/version/duncdrum/existdb.svg)](https://microbadger.com/images/duncdrum/existdb \"Get your own version badge on microbadger.com\")\n[![](https://images.microbadger.com/badges/commit/duncdrum/existdb.svg)](https://microbadger.com/images/duncdrum/existdb \"Get your own commit badge on microbadger.com\")\n\nThis module holds the source files for building a minimal docker image of the [exist-db](https://www.exist-db.org) xml \ndatabase, images are automatically updated as part of the build-test life-cycle. \nThe images are based on Google Cloud Platform's [\"Distroless\" Docker Images](https://github.com/GoogleCloudPlatform/distroless).\n\n\n## Requirements \n\n*   [Docker](https://www.docker.com): `18-stable`\n\n### Build Requirements\n\n*   [Docker](https://www.docker.com): `19.03`\n*   [bats](https://github.com/bats-core/bats-core): `^1.1.0` (for testing)\n*   [buildx](https://docs.docker.com/buildx/working-with-buildx/)\n\n## How to use\n\nMulti-arch images are currently produced for `linux/amd64` and `linux/arm64`. Pre-build images are available on [DockerHub](https://hub.docker.com/r/duncdrum/existdb/). \nThe tagging scheme is: `$EXIST_VERSION$-$DISTROLESS_FLAVOR$-$JAVA_VERSION$-$IMG_FLAVOR$`. For exist-dbs version are two moving tags:\n*   `release` for the stable releases based on the [`master` branch](https://github.com/eXist-db/exist/tree/master)\n*   `latest` (default) for the latest commit to the [`develop` branch](https://github.com/eXist-db/exist/tree/develop).\n*   next to the semantic version of each supported exist release (e.g.: `6.2.0`)\n  \nDistroless flavors:\n*   s.a. `nonroot`, `debug`, or no  tag (default)\n  \n\nJava version\n*   for exist v6: `j8` or `j11` (default)\n*   for exist v7 `j21` (no tag) (default)\n\nImage flavor\n*   `slim` has and empty `autodeploy` folder\n*   `full` (default) with stock apps in autodeploy\n\n\n\n\nTo download the image run:\n\n```bash\ndocker pull duncdrum/existdb:latest\n```\n\nOnce the download is complete, you can run the image\n\n```bash\ndocker run -dit -p 8080:8080 -p 8443:8443 --name exist duncdrum/existdb:latest\n```\n\n### What does this do?\n\n*   `-it` allocates a TTY and keeps STDIN open.  This allows you to interact with the running Docker container via your console.\n*   `-d` detaches the container from the terminal that started it. So your container won't stop when you close the terminal.\n*   `-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.\n*   `--name` lets you provide a name (instead of using a randomly generated one)\n\nThe only required parts are `docker run duncdrum/existdb`. \nFor a full list of available options see the official [Docker documentation](https://docs.docker.com/engine/reference/commandline/run/)\n\nAfter running the `pull` and `run` commands, you can access eXist-db via [localhost:8080](localhost:8080) in your browser.\n\nTo stop the container issue:\n\n```bash\ndocker stop exist\n```\n\nor if you omitted the `-d` flag earlier press `CTRL-C` inside the terminal showing the exist logs.\n\n### Interacting with the running container\n\nYou can interact with a running container as if it were a regular Linux host (without a shell in our case). \nYou 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.\n\nThe name of the container in this readme is `exist`, adjust the name in the commands to suit your needs:\n\n```bash\n# Using java syntax on a running eXist-db instances\ndocker exec exist java org.exist.start.Main client --no-gui --xpath \"system:get-version()\"\n\n# Interacting with the JVM\ndocker exec exist java -version\n```\n\nContainers build from this image run periodical healthchecks to ensure that eXist-db is operating normally. \nIf `docker ps` reports `unhealthy` you can get a more detailed report with this command:  \n\n```bash\ndocker inspect --format='{{json .State.Health}}' exist\n```\n\n### Logging\nThere is a slight modification to eXist's logger to ease access to the logs via:\n\n```bash\ndocker logs exist\n```\n\nThis works best when providing the `-t` flag when running an image.\n\n## Use as base image\n\nA common usage of these images is as a base image for your own applications. \nWe'll take a quick look at three scenarios of increasing complexity, to demonstrate how to achieve common tasks from inside `Dockerfile`.\n\n### A simple app image\n\nThe simplest and straightforward case assumes that you have a `.xar` app inside a `build` folder on the same level as the `Dockerfile`. \nTo 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.\n```docker\nFROM duncdrum/existdb:6.0.1\n\nCOPY build/*.xar /exist/autodeploy\n```\n\nYou should see something like this:\n\n```bash\nSending build context to Docker daemon  4.337MB\nStep 1/2 : FROM duncdrum/existdb:6.0.1\n ---\u003e 3f4dbbce9afa\nStep 2/2 : COPY build/*.xar /exist/autodeploy\n ---\u003e ace38b0809de\n```\n\nThe result is a new image of your app installed into eXist-db. \nSince you didn't provide further instructions it will simply reuse the `EXPOSE`, `CMD`, `HEALTHCHECK`, etc instructions defined by the base image. \nYou can now publish this image to a docker registry and share it with others.\n\n### A slightly more complex single stage image\n\nThe following example will install your app, but also modify the underlying eXist-db instance in which your app is running. \nInstead 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`. \nTo execute any of the `docker exec …` style commands from this readme, we need to use `RUN`.\n\n```docker\nFROM duncdrum/existdb\n\n# NOTE: this is for syntax demo purposes only\nRUN [ \"java\", \"org.exist.start.Main\", \"client\", \"--no-gui\",  \"-l\", \"-u\", \"admin\", \"-P\", \"\", \"-x\", \"sm:passwd('admin','123')\" ]\n\n# use a modified conf.xml\nCOPY src/conf.xml /exist/etc\n\nADD https://github.com/eXist-db/documentation/releases/download/4.0.4/exist-documentation-4.0.4.xar /exist/autodeploy\n```\n\nThe above is intended to demonstrate the kind of operations available to you in a single stage build. \nFor security reasons [more elaborate techniques](https://docs.docker.com/engine/swarm/secrets/) for not sharing your password in the clear are highly recommended, \nsuch as the use of secure variables inside your CI environment. \nHowever, the above shows you how to execute the [Java Admin Client](http://www.exist-db.org/exist/apps/doc/java-admin-client.xml) from inside a `Dockerfile`, \nwhich 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.\n\nAs for the sequence of the commands, those with the most frequent changes should come last to avoid cache busting. \nChances are, you wouldn't change the admin password very often, but the `.xar` might change more frequently.\n\n### Multi-stage build with ant\n\nLastly, you can eliminate external dependencies even further by using a multi-stage build. \nTo ensure compatibility between different Java engines we recommend sticking with debian based images for the builder stage.\n\nThe 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.\nThe second stage (each `FROM` begins a stage) is just the simple example from above. \nSuch a setup ensures that non of your collaborators has to have `java` or `nodeJS` installed, and is great for fully automated builds and deployment.\n\n```docker\n# START STAGE 1\nFROM openjdk:8-jdk-slim as builder\n\nUSER root\n\nENV ANT_VERSION 1.10.5\nENV ANT_HOME /etc/ant-${ANT_VERSION}\n\nWORKDIR /tmp\n\nRUN wget http://www-us.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz \\\n    \u0026\u0026 mkdir ant-${ANT_VERSION} \\\n    \u0026\u0026 tar -zxvf apache-ant-${ANT_VERSION}-bin.tar.gz \\\n    \u0026\u0026 mv apache-ant-${ANT_VERSION} ${ANT_HOME} \\\n    \u0026\u0026 rm apache-ant-${ANT_VERSION}-bin.tar.gz \\\n    \u0026\u0026 rm -rf ant-${ANT_VERSION} \\\n    \u0026\u0026 rm -rf ${ANT_HOME}/manual \\\n    \u0026\u0026 unset ANT_VERSION\n\nENV PATH ${PATH}:${ANT_HOME}/bin\n\nWORKDIR /home/my-app\nCOPY . .\nRUN apk add --no-cache --virtual .build-deps \\\n nodejs \\\n nodejs-npm \\\n git \\\n \u0026\u0026 npm i npm@latest -g \\\n \u0026\u0026 ant\n\n\n# START STAGE 2\nFROM duncdrum/existdb:release\n\nCOPY --from=builder /home/my-app/build/*.xar /exist/autodeploy\n\nEXPOSE 8080 8443\n\nCMD [ \"java\", \"org.exist.start.Main\", \"jetty\" ]\n```\n\nThe basic idea of the multi-staging is that everything you need for building your software should be managed by docker, \nso that all collaborators can rely on one stable environment. In the end, and after how ever many stages you need, \nonly the files necessary to run your app should go into the final stage. The possibilities are virtually endless, \nbut 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.\n\n## Development use via `docker-compose`\n\nWe highly recommend use of a `docker-compose.yml` for use with [docker-compose](https://docs.docker.com/compose/). \ndocker-compose for local development or integration into multi-container environments. \nFor options on how to configure your own compose file, follow the link at the beginning of this paragraph.\n\nTo start exist using a compose file, type:\n\n```bash\n# starting eXist-db\ndocker-compose up -d\n# stop eXist-db\ndocker-compose down\n```\n\n[Volumes](https://docs.docker.com/storage/volumes/) let you ensure data persistence between reboots, \nin particular:\n\n*   `exist/data` so that any database changes persist through reboots and updates.\n*   `exist/etc` so you can configure eXist startup options.\n\ncan be declared as mount volumes. \n\nYou can configure additional volumes e.g. for backups, \nor additional services such as an nginx reverse proxy via a `docker-compose.yml`, to suite your needs.\n\nTo update the exist-docker image from a newer version\n\n```bash\ndocker-compose pull\n```\n\n### Caveat\n\nAs with normal installations, the password for the default dba user `admin` is empty. \nChange it via the [usermanager](http://localhost:8080/exist/apps/usermanager/index.html) or from CLI \\(s.a.\\).\n\n## Building the Image\n\nThe images rely on modern build features and the `buildx` build tooling. The most important arguments for building are `BRANCH` for determining the exist-db version (this also takes git tags as a value); and `FLAVOR` which supports `full` for images with a populated `exist/autodeply` folder and `slim` for an empty autodeploy folder, which can be useful inside Dockerfiles using these images as a base.\n\nThis build command uses a Java 8 (`-f`) base image, with no autodeploy EXPAth packages (`--build-arg FLAVOR=slim`) from the git tag `eXist-6.4.0` (`--build-arg BRANCH=…`) for `amd` and `arm` (`--platform`) architectures:\n\n```shell\ndocker buildx build -t duncdrum/existdb:6.4.0-j8-slim --build-arg FLAVOR=slim --build-arg BRANCH=eXist-6.4.0 --platform linux/amd64,linux/arm64 -f Dockerfile_j8 .\n```\n\n### Testing\n\nThere are unit tests for our images that run on CI using the [bats](https://github.com/bats-core/bats-core) framework. The test are located in `exist-docker/src/test/bats`.\n\nTo execute them run:\n\n```bash\nbats exist-docker/src/test/bats/*.bats \n```\n\nThe tests use fixtures and are creating a modified image call `ex-mod`. By default they expect a name container `exist-ci` to be up and running. When running test locally you must ensure that no previous image `ex-mod` exists, and that `exist-ci` is running before starting the testsuite. \n\n### Available Arguments and Defaults\n\neXist-db's cache size and maximum brokers can be configured at build time using the following syntax.\n\u003c!-- TODO(DP) --\u003e\n```bash\nmvn -DskipTests clean package docker:build --build-arg MAX_CACHE=312 MAX_BROKER=15 .\n```\n\nNOTE: Due to the fact that the final images does not provide a shell, setting ENV variables via docker does not work.\n\n```bash\n# !This has no effect!\ndocker run -dit -p8080:8080 -e MAX_BROKER=10 ae4d6d653d30\n```\n\nIf you wish to permanently adopt a customized cache or broker configuration, \nyou can either make a local copy of the `Dockerfile` and edit the default values there.\n\n```bash\nARG MAX_BROKER=10\n```\n\u003c!-- TODO(DP) --\u003e\nOr modify eXist-db's configuration files via xslt scripts located at `exist-docker/src/main/xslt/`.\nFor multi-stage builds e.g. [xmlstarlet](http://xmlstar.sourceforge.net) let's you modify the default config files from within the builder stage, \ne.g.:\n```docker\n# Config files are modified here\nRUN echo 'modifying conf files'\\\n\u0026\u0026 cd $EXIST_HOME/etc \\\n\u0026\u0026 xmlstarlet ed  -L -s '/Configuration/Loggers/Root' -t elem -n 'AppenderRefTMP' -v '' \\\n -i //AppenderRefTMP -t attr -n 'ref' -v 'STDOUT'\\\n -r //AppenderRefTMP -v AppenderRef \\\n log4j2.xml\n```\n\n#### JVM configuration\n\nThis image uses an advanced JVM configuration, via the  `JAVA_TOOL_OPTIONS` env variable inside the Dockerfile. \nYou should avoid the traditional way of setting the heap size via `-Xmx` arguments, \nthis can lead to frequent crashes since Java8 and Docker are (literally) not on the same page concerning available memory.\n\nInstead, use the `-XX:MaxRAMPercentage` argument to modify the memory available to the JVM *inside* the container. \nThe default of `75%` should be save for production use. \nTo allocate e.g. 600mb to the container *around* the JVM use, however, you can tweak this at buildtime via the `JVM_MAX_RAM_PERCENTAGE` argument. Note that percentages should include a decimal point `80.0` = `80%`.\n\nTo allocate e.g. 600mb to the container around the JVM use:\n\n```bash\ndocker run -m 600m …\n```\n\nLastly, this image uses a new garbage collection mechanism \n[garbage first (G1)](https://docs.oracle.com/javase/9/gctuning/garbage-first-garbage-collector.htm#JSGCT-GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573) `-XX:+UseG1GC` \nand [string deduplication](http://openjdk.java.net/jeps/192) `-XX:+UseStringDeduplication` to improve performance.\n\nCustomizing individual arguments is not possible at run time. To adjust individual parameters the the whole `JAVA_TOOL_OPTIONS` environment variable must be passed to `docker run …`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduncdrum%2Fdistroless-exist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduncdrum%2Fdistroless-exist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduncdrum%2Fdistroless-exist/lists"}