├── .asf.yaml ├── .github └── workflows │ └── pr-for-official-repo.yml ├── .gitignore ├── 8.11-slim ├── Dockerfile └── scripts │ ├── docker-entrypoint.sh │ ├── init-var-solr │ ├── oom_solr.sh │ ├── precreate-core │ ├── run-initdb │ ├── solr-create │ ├── solr-demo │ ├── solr-fg │ ├── solr-foreground │ ├── solr-precreate │ ├── start-local-solr │ ├── stop-local-solr │ ├── wait-for-solr.sh │ └── wait-for-zookeeper.sh ├── 8.11 ├── Dockerfile └── scripts │ ├── docker-entrypoint.sh │ ├── init-var-solr │ ├── oom_solr.sh │ ├── precreate-core │ ├── run-initdb │ ├── solr-create │ ├── solr-demo │ ├── solr-fg │ ├── solr-foreground │ ├── solr-precreate │ ├── start-local-solr │ ├── stop-local-solr │ ├── wait-for-solr.sh │ └── wait-for-zookeeper.sh ├── 9.7-slim └── Dockerfile ├── 9.7 └── Dockerfile ├── 9.8-slim └── Dockerfile ├── 9.8 └── Dockerfile ├── LICENSE ├── NOTICE ├── README-short.txt ├── README.md ├── dev-docs └── README.md ├── generate-stackbrew-library.sh └── tools └── init_macos.sh /.asf.yaml: -------------------------------------------------------------------------------- 1 | # https://cwiki.apache.org/confluence/display/INFRA/.asf.yaml+features+for+git+repositories 2 | 3 | github: 4 | description: "Official Dockerfile for Apache Solr" 5 | homepage: https://solr.apache.org/ 6 | labels: 7 | - solr 8 | - search 9 | - docker 10 | 11 | enabled_merge_buttons: 12 | squash: true 13 | merge: false 14 | rebase: false 15 | 16 | notifications: 17 | commits: commits@solr.apache.org 18 | issues: issues@solr.apache.org 19 | pullrequests: issues@solr.apache.org 20 | jira_options: link label worklog 21 | -------------------------------------------------------------------------------- /.github/workflows/pr-for-official-repo.yml: -------------------------------------------------------------------------------- 1 | name: Create PR for Official Images Repo 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | paths: 8 | - 'generate-stackbrew-library.sh' 9 | - '[0-9]+.[0-9]+*/**' 10 | 11 | jobs: 12 | test: 13 | # Only run this job for the apache repo, not on any forks 14 | if: github.repository_owner == 'apache' 15 | 16 | name: Create PR 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | # Setup 22 | - uses: actions/checkout@v4 23 | with: 24 | # This is required for stackbrew to know which commit a dockerfile belongs to 25 | fetch-depth: 0 26 | - name: Checkout official-images fork 27 | uses: actions/checkout@v4 28 | with: 29 | repository: docker-library/official-images 30 | path: official-images 31 | - name: check headcommit message 32 | id: commit 33 | run: | 34 | message="$(jq '.head_commit.message' $GITHUB_EVENT_PATH | sed -E 's/^#/ #/g' | sed -E 's/(#[0-9]+)$/\1 /g' | sed -E 's/([^a-zA-Z])(#[0-9]+[^0-9])/\1apache\/solr-docker\2/g' | tr -d \")" # get the message, substituting the github links 35 | echo ::set-output name=title::${message%%\\n*} # get the title 36 | - name: Install BashBrew 37 | run: | 38 | mkdir -p "${HOME}/.local/bin" 39 | wget -nv --output-document="${HOME}/.local/bin/bashbrew" https://github.com/docker-library/bashbrew/releases/download/v0.1.12/bashbrew-amd64 40 | chmod a+x "${HOME}/.local/bin/bashbrew" 41 | echo "${HOME}/.local/bin" >> $GITHUB_PATH 42 | - name: Generate new Solr manifest 43 | run: ./generate-stackbrew-library.sh > official-images/library/solr 44 | - name: Create Pull Request 45 | uses: peter-evans/create-pull-request@v4 46 | with: 47 | path: official-images 48 | push-to-fork: docker-solr/official-images 49 | add-paths: library/solr 50 | branch: apache-solr-automated-pr 51 | commit-message: | 52 | Apache Solr - ${{ steps.commit.outputs.title}} 53 | title: "Apache Solr - ${{ steps.commit.outputs.title}}" 54 | body: | 55 | Apache Solr: 56 | 57 | ${{ steps.commit.outputs.title }} 58 | 59 | See apache/solr-docker@${{ github.sha }} for the triggering commit. 60 | 61 | Relevant Maintainers: @HoustonPutman @janhoy @dsmiley @madrob 62 | 63 | This is an automated PR based on a change made in the https://github.com/apache/solr-docker repository's `main` branch. 64 | delete-branch: true 65 | token: ${{ secrets.DOCKER_SOLR_BUILD_PAT }} 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | downloads 2 | .gnupg 3 | ownertrust.txt 4 | upstream-versions 5 | .idea 6 | -------------------------------------------------------------------------------- /8.11-slim/Dockerfile: -------------------------------------------------------------------------------- 1 | # Patched 2022-10-20 to change from openjdk:11-jre-slim to eclipse-temurin:11-jre 2 | # Patched 2022-10-21 to use eclipse-temurin:11-jre-focal which used Ubuntu 20.04, compatible with Docker client < 20.10.16 3 | # Patched 2023-04-01 to upgrade jattach to v2.0 4 | FROM eclipse-temurin:11-jre-focal 5 | 6 | LABEL maintainer="The Apache Lucene/Solr Project" 7 | LABEL repository="https://github.com/docker-solr/docker-solr" 8 | 9 | ARG SOLR_VERSION="8.11.4" 10 | ARG SOLR_SHA512="828a7c3c06f3ccca852f2c3f91d72bf032cf102646283f4e603bbc3c3f3753978ce8b5c014c4263fb66c251b6726105956ad726baee63af6568637eba0416612" 11 | ARG SOLR_KEYS="50E3EE1C91C7E0CB4DFB007B369424FC98F3F6EC" 12 | # If specified, this will override SOLR_DOWNLOAD_SERVER and all ASF mirrors. Typically used downstream for custom builds 13 | ARG SOLR_DOWNLOAD_URL 14 | 15 | # Override the solr download location with e.g.: 16 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=http://www-eu.apache.org/dist/lucene/solr . 17 | ARG SOLR_DOWNLOAD_SERVER 18 | 19 | RUN set -ex; \ 20 | apt-get update; \ 21 | apt-get -y install acl dirmngr gpg lsof procps wget netcat gosu tini; \ 22 | rm -rf /var/lib/apt/lists/*; \ 23 | cd /usr/local/bin; wget -nv https://github.com/apangin/jattach/releases/download/v2.0/jattach; chmod 755 jattach; \ 24 | echo >jattach.sha512 "a19e774600d6aa844bceb2189285848127a70130a69fb1840c10367f3360972c733b3f09e60e9672d387e2d48c750ab56acfe8f80f7c6af76f5d1123e5ad7222 jattach"; \ 25 | sha512sum -c jattach.sha512; rm jattach.sha512 26 | 27 | ENV SOLR_USER="solr" \ 28 | SOLR_UID="8983" \ 29 | SOLR_GROUP="solr" \ 30 | SOLR_GID="8983" \ 31 | SOLR_CLOSER_URL="https://www.apache.org/dyn/closer.lua/lucene/solr/${SOLR_VERSION}/solr-${SOLR_VERSION}.tgz?action=download" \ 32 | SOLR_DIST_URL="https://downloads.apache.org/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \ 33 | SOLR_ARCHIVE_URL="https://archive.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \ 34 | PATH="/opt/solr/bin:/opt/docker-solr/scripts:$PATH" \ 35 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 36 | SOLR_HOME=/var/solr/data \ 37 | SOLR_PID_DIR=/var/solr \ 38 | SOLR_LOGS_DIR=/var/solr/logs \ 39 | LOG4J_PROPS=/var/solr/log4j2.xml 40 | 41 | RUN set -ex; \ 42 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 43 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 44 | 45 | RUN set -ex; \ 46 | export GNUPGHOME="/tmp/gnupg_home"; \ 47 | mkdir -p "$GNUPGHOME"; \ 48 | chmod 700 "$GNUPGHOME"; \ 49 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 50 | for key in $SOLR_KEYS; do \ 51 | found=''; \ 52 | for server in \ 53 | ha.pool.sks-keyservers.net \ 54 | hkp://keyserver.ubuntu.com:80 \ 55 | hkp://p80.pool.sks-keyservers.net:80 \ 56 | pgp.mit.edu \ 57 | ; do \ 58 | echo " trying $server for $key"; \ 59 | gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \ 60 | gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \ 61 | done; \ 62 | test -z "$found" && echo >&2 "error: failed to fetch $key from several disparate servers -- network issues?" && exit 1; \ 63 | done; \ 64 | exit 0 65 | 66 | RUN set -ex; \ 67 | export GNUPGHOME="/tmp/gnupg_home"; \ 68 | MAX_REDIRECTS=1; \ 69 | if [ -n "$SOLR_DOWNLOAD_URL" ]; then \ 70 | # If a custom URL is defined, we download from non-ASF mirror URL and allow more redirects and skip GPG step 71 | # This takes effect only if the SOLR_DOWNLOAD_URL build-arg is specified, typically in downstream Dockerfiles 72 | MAX_REDIRECTS=4; \ 73 | SKIP_GPG_CHECK=true; \ 74 | elif [ -n "$SOLR_DOWNLOAD_SERVER" ]; then \ 75 | SOLR_DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"; \ 76 | fi; \ 77 | for url in $SOLR_DOWNLOAD_URL $SOLR_CLOSER_URL $SOLR_DIST_URL $SOLR_ARCHIVE_URL; do \ 78 | if [ -f "/opt/solr-$SOLR_VERSION.tgz" ]; then break; fi; \ 79 | echo "downloading $url"; \ 80 | if wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$url" -O "/opt/solr-$SOLR_VERSION.tgz"; then break; else rm -f "/opt/solr-$SOLR_VERSION.tgz"; fi; \ 81 | done; \ 82 | if [ ! -f "/opt/solr-$SOLR_VERSION.tgz" ]; then echo "failed all download attempts for solr-$SOLR_VERSION.tgz"; exit 1; fi; \ 83 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 84 | echo "downloading $SOLR_ARCHIVE_URL.asc"; \ 85 | wget -nv "$SOLR_ARCHIVE_URL.asc" -O "/opt/solr-$SOLR_VERSION.tgz.asc"; \ 86 | echo "$SOLR_SHA512 */opt/solr-$SOLR_VERSION.tgz" | sha512sum -c -; \ 87 | (>&2 ls -l "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz.asc"); \ 88 | gpg --batch --verify "/opt/solr-$SOLR_VERSION.tgz.asc" "/opt/solr-$SOLR_VERSION.tgz"; \ 89 | else \ 90 | echo "Skipping GPG validation due to non-Apache build"; \ 91 | fi; \ 92 | tar -C /opt --extract --file "/opt/solr-$SOLR_VERSION.tgz"; \ 93 | (cd /opt; ln -s "solr-$SOLR_VERSION" solr); \ 94 | rm "/opt/solr-$SOLR_VERSION.tgz"*; \ 95 | rm -Rf /opt/solr/docs/ /opt/solr/dist/{solr-core-$SOLR_VERSION.jar,solr-solrj-$SOLR_VERSION.jar,solrj-lib,solr-test-framework-$SOLR_VERSION.jar,test-framework}; \ 96 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d /opt/docker-solr; \ 97 | chown -R 0:0 "/opt/solr-$SOLR_VERSION"; \ 98 | find "/opt/solr-$SOLR_VERSION" -type d -print0 | xargs -0 chmod 0755; \ 99 | find "/opt/solr-$SOLR_VERSION" -type f -print0 | xargs -0 chmod 0644; \ 100 | chmod -R 0755 "/opt/solr-$SOLR_VERSION/bin" "/opt/solr-$SOLR_VERSION/contrib/prometheus-exporter/bin/solr-exporter" /opt/solr-$SOLR_VERSION/server/scripts/cloud-scripts; \ 101 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 102 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 103 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 104 | chown root:0 /etc/default/solr.in.sh; \ 105 | chmod 0664 /etc/default/solr.in.sh; \ 106 | mkdir -p /var/solr/data /var/solr/logs; \ 107 | (cd /opt/solr/server/solr; cp solr.xml zoo.cfg /var/solr/data/); \ 108 | cp /opt/solr/server/resources/log4j2.xml /var/solr/log4j2.xml; \ 109 | find /var/solr -type d -print0 | xargs -0 chmod 0770; \ 110 | find /var/solr -type f -print0 | xargs -0 chmod 0660; \ 111 | sed -i -e "s/\"\$(whoami)\" == \"root\"/\$(id -u) == 0/" /opt/solr/bin/solr; \ 112 | sed -i -e 's/lsof -PniTCP:/lsof -t -PniTCP:/' /opt/solr/bin/solr; \ 113 | chown -R "0:0" /opt/solr-$SOLR_VERSION /docker-entrypoint-initdb.d /opt/docker-solr; \ 114 | chown -R "$SOLR_USER:0" /var/solr; \ 115 | { command -v gpgconf; gpgconf --kill all || :; }; \ 116 | rm -r "$GNUPGHOME" 117 | 118 | COPY --chown=0:0 scripts /opt/docker-solr/scripts 119 | 120 | VOLUME /var/solr 121 | EXPOSE 8983 122 | WORKDIR /opt/solr 123 | USER $SOLR_UID 124 | 125 | ENTRYPOINT ["docker-entrypoint.sh"] 126 | CMD ["solr-foreground"] 127 | -------------------------------------------------------------------------------- /8.11-slim/scripts/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # docker-entrypoint for docker-solr 4 | 5 | set -e 6 | 7 | # Clear some variables that we don't want runtime 8 | unset SOLR_USER SOLR_UID SOLR_GROUP SOLR_GID \ 9 | SOLR_CLOSER_URL SOLR_DIST_URL SOLR_ARCHIVE_URL SOLR_DOWNLOAD_URL SOLR_DOWNLOAD_SERVER SOLR_KEYS SOLR_SHA512 10 | 11 | if [[ "$VERBOSE" == "yes" ]]; then 12 | set -x 13 | fi 14 | 15 | if [[ -v SOLR_PORT ]] && ! grep -E -q '^[0-9]+$' <<<"${SOLR_PORT:-}"; then 16 | SOLR_PORT=8983 17 | export SOLR_PORT 18 | fi 19 | 20 | # when invoked with e.g.: docker run solr -help 21 | if [ "${1:0:1}" == '-' ]; then 22 | set -- solr-foreground "$@" 23 | fi 24 | 25 | # execute command passed in as arguments. 26 | # The Dockerfile has specified the PATH to include 27 | # /opt/solr/bin (for Solr) and /opt/docker-solr/scripts (for our scripts 28 | # like solr-foreground, solr-create, solr-precreate, solr-demo). 29 | # Note: if you specify "solr", you'll typically want to add -f to run it in 30 | # the foreground. 31 | exec "$@" 32 | -------------------------------------------------------------------------------- /8.11-slim/scripts/init-var-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to initialise an empty $DIR 4 | # If you use volumes then Docker will copy the $DIR content from the container to the volume. 5 | # If you use bind mounts, that does not happen, so we do it here. 6 | 7 | set -e 8 | 9 | if [[ "$VERBOSE" == "yes" ]]; then 10 | set -x 11 | fi 12 | 13 | if [[ -n "${NO_INIT_VAR_SOLR:-}" ]]; then 14 | exit 0 15 | fi 16 | 17 | DIR=${1:-/var/solr} 18 | 19 | if [ ! -d "$DIR" ]; then 20 | echo "Missing $DIR" 21 | exit 1 22 | fi 23 | 24 | function check_dir_writability { 25 | local dir="$1" 26 | if [ ! -w "$dir" ]; then 27 | echo "Cannot write to $dir as $(id -u):$(id -g)" 28 | ls -ld "$dir" 29 | exit 1 30 | fi 31 | } 32 | 33 | if [ ! -d "$DIR/data" ]; then 34 | echo "Creating $DIR/data" 35 | check_dir_writability "$DIR" 36 | mkdir "$DIR/data" 37 | chmod 0770 "$DIR/data" 38 | fi 39 | 40 | if [ ! -d "$DIR/logs" ]; then 41 | echo "Creating $DIR/logs" 42 | check_dir_writability "$DIR" 43 | mkdir "$DIR/logs" 44 | chmod 0770 "$DIR/logs" 45 | fi 46 | 47 | if [ ! -f "$DIR/data/solr.xml" ]; then 48 | echo "Copying solr.xml" 49 | cp -a /opt/solr/server/solr/solr.xml "$DIR/data/solr.xml" 50 | fi 51 | 52 | if [ ! -f "$DIR/data/zoo.cfg" ]; then 53 | echo "Copying zoo.cfg" 54 | cp -a /opt/solr/server/solr/zoo.cfg "$DIR/data/zoo.cfg" 55 | fi 56 | 57 | if [ ! -f "$DIR/log4j2.xml" ]; then 58 | echo "Copying log4j2.xml" 59 | cp -a /opt/solr/server/resources/log4j2.xml "$DIR/log4j2.xml" 60 | fi 61 | 62 | -------------------------------------------------------------------------------- /8.11-slim/scripts/oom_solr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Custom oom handler loosely based on 4 | # https://github.com/apache/lucene-solr/blob/master/solr/bin/oom_solr.sh 5 | # See solr-forgeground for how to configure OOM behaviour 6 | 7 | if [[ -z "${SOLR_LOGS_DIR:-}" ]]; then 8 | if [ -d /var/solr/logs ]; then 9 | SOLR_LOGS_DIR=/var/solr/logs 10 | elif [ -d /opt/solr/server/logs ]; then 11 | SOLR_LOGS_DIR=/opt/solr/server/logs 12 | else 13 | echo "Cannot determine SOLR_LOGS_DIR!" 14 | exit 1 15 | fi 16 | fi 17 | SOLR_PID=$(pgrep -f start.jar) 18 | if [[ -z "$SOLR_PID" ]]; then 19 | echo "Couldn't find Solr process running!" 20 | exit 21 | fi 22 | 23 | NOW=$(date +"%F_%H_%M_%S") 24 | ( 25 | echo "Running OOM killer script for Solr process $SOLR_PID" 26 | if [[ "$SOLR_PID" == 1 ]]; then 27 | # under Docker, when running as pid 1, a SIGKILL is ignored, 28 | # so use the default SIGTERM 29 | kill "$SOLR_PID" 30 | sleep 2 31 | # if that hasn't worked, send SIGKILL 32 | kill -SIGILL "$SOLR_PID" 33 | else 34 | # if we're running with `--init` or under tini or similar, 35 | # follow the upstream behaviour 36 | kill -9 "$SOLR_PID" 37 | fi 38 | ) | tee "$SOLR_LOGS_DIR/solr_oom_killer-$SOLR_PORT-$NOW.log" 39 | -------------------------------------------------------------------------------- /8.11-slim/scripts/precreate-core: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Create a core on disk 4 | # arguments are: corename configdir 5 | 6 | set -e 7 | 8 | echo "Executing $0" "$@" 9 | 10 | if [[ "${VERBOSE:-}" == "yes" ]]; then 11 | set -x 12 | fi 13 | 14 | CORE=${1:-gettingstarted} 15 | CONFIG_SOURCE="${2:-}" 16 | if [[ -z "$CONFIG_SOURCE" ]]; then 17 | DEFAULT_CONFIGS=(_default data_driven_schema_configs) 18 | for config_dir in "${DEFAULT_CONFIGS[@]}"; do 19 | config_dir="/opt/solr/server/solr/configsets/$config_dir" 20 | if [ -d "$config_dir" ]; then 21 | CONFIG_SOURCE="$config_dir" 22 | break 23 | fi 24 | done 25 | if [[ -z $CONFIG_SOURCE ]]; then 26 | echo "Cannot find default config" 27 | exit 1 28 | fi 29 | fi 30 | 31 | coresdir=/var/solr/data 32 | 33 | coredir="$coresdir/$CORE" 34 | if [[ ! -d $coredir ]]; then 35 | cp -r "$CONFIG_SOURCE/" "$coredir" 36 | touch "$coredir/core.properties" 37 | echo "Created $CORE" 38 | else 39 | echo "Core $CORE already exists" 40 | fi 41 | -------------------------------------------------------------------------------- /8.11-slim/scripts/run-initdb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run the init-solr-home script and source any '.sh' scripts in 4 | # /docker-entrypoint-initdb.d. 5 | # This script is sourced by some of the solr-* commands, so that 6 | # you can run eg: 7 | # 8 | # mkdir initdb; echo "echo hi" > initdb/hi.sh 9 | # docker run -v $PWD/initdb:/docker-entrypoint-initdb.d solr 10 | # 11 | # and have your script execute before Solr starts. 12 | # 13 | # Note: scripts can modify the environment, which will affect 14 | # subsequent scripts and ultimately Solr. That allows you to set 15 | # environment variables from your scripts (though you usually just 16 | # use "docker run -e"). If this is undesirable in your use-case, 17 | # have your scripts execute a sub-shell. 18 | 19 | set -e 20 | 21 | # execute files in /docker-entrypoint-initdb.d before starting solr 22 | while read -r f; do 23 | case "$f" in 24 | *.sh) echo "$0: running $f"; . "$f" ;; 25 | *) echo "$0: ignoring $f" ;; 26 | esac 27 | echo 28 | done < <(find /docker-entrypoint-initdb.d/ -mindepth 1 -type f | sort -n) 29 | -------------------------------------------------------------------------------- /8.11-slim/scripts/solr-create: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This script starts Solr on localhost, creates a core with "solr create", 4 | # stops Solr, and then starts Solr as normal. 5 | # Any arguments are passed to the "solr create". 6 | # To simply create a core: 7 | # docker run -P -d solr solr-create -c mycore 8 | # To create a core from mounted config: 9 | # docker run -P -d -v $PWD/myconfig:/myconfig solr solr-create -c mycore -d /myconfig 10 | 11 | set -euo pipefail 12 | echo "Executing $0" "$@" 13 | 14 | if [[ "${VERBOSE:-}" == "yes" ]]; then 15 | set -x 16 | fi 17 | 18 | # init script for handling an empty /var/solr 19 | /opt/docker-solr/scripts/init-var-solr 20 | 21 | . /opt/docker-solr/scripts/run-initdb 22 | 23 | # solr uses "-c corename". Parse the arguments to determine the core name. 24 | CORE_NAME="$( 25 | while (( $# > 0 )); do 26 | if [[ "$1" == '-c' ]]; then 27 | shift 28 | echo "$1" 29 | fi 30 | shift 31 | done 32 | )" 33 | if [[ -z "${CORE_NAME:-}" ]]; then 34 | echo "Could not determine core name" 35 | exit 1 36 | fi 37 | 38 | coresdir=/var/solr/data 39 | CORE_DIR="$coresdir/$CORE_NAME" 40 | 41 | if [[ -d $CORE_DIR ]]; then 42 | echo "Directory $CORE_DIR exists; skipping core creation" 43 | else 44 | start-local-solr 45 | 46 | echo "Creating core with:" "${@:1}" 47 | /opt/solr/bin/solr create "${@:1}" 48 | 49 | # See https://github.com/docker-solr/docker-solr/issues/27 50 | echo "Checking core" 51 | if ! wget -O - "http://localhost:${SOLR_PORT:-8983}/solr/admin/cores?action=STATUS" | grep instanceDir >/dev/null; then 52 | echo "Could not find any cores" 53 | exit 1 54 | fi 55 | 56 | echo "Created core with:" "${@:1}" 57 | stop-local-solr 58 | 59 | # check the core_dir exists; otherwise the detecting above will fail after stop/start 60 | if [ ! -d "$CORE_DIR" ]; then 61 | echo "Missing $CORE_DIR" 62 | exit 1 63 | fi 64 | fi 65 | 66 | exec solr-fg 67 | -------------------------------------------------------------------------------- /8.11-slim/scripts/solr-demo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Configure a Solr demo and then run solr in the foreground 4 | 5 | set -euo pipefail 6 | 7 | if [[ "${VERBOSE:-}" == "yes" ]]; then 8 | set -x 9 | fi 10 | 11 | . /opt/docker-solr/scripts/run-initdb 12 | 13 | CORE=demo 14 | 15 | coresdir=/var/solr/data 16 | CORE_DIR="$coresdir/demo" 17 | if [ -d "$CORE_DIR" ]; then 18 | echo "$CORE_DIR exists; skipping demo creation" 19 | else 20 | start-local-solr 21 | echo "Creating $CORE" 22 | /opt/solr/bin/solr create -c "$CORE" 23 | echo "Created $CORE" 24 | echo "Loading example data" 25 | post_args=() 26 | if [[ -n "${SOLR_PORT:-}" ]]; then 27 | post_args+=(-p "$SOLR_PORT") 28 | fi 29 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/*.xml 30 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/books.json 31 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit yes example/exampledocs/books.csv 32 | echo "Loaded example data" 33 | stop-local-solr 34 | 35 | # check the core_dir exists; otherwise the detecting above will fail after stop/start 36 | if [ ! -d "$CORE_DIR" ]; then 37 | echo "Missing $CORE_DIR" 38 | exit 1 39 | fi 40 | fi 41 | 42 | exec solr-fg 43 | -------------------------------------------------------------------------------- /8.11-slim/scripts/solr-fg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # start solr in the foreground 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | EXTRA_ARGS=() 11 | EXTRA_ARGS+=('-Dlog4j2.formatMsgNoLookups=true') 12 | 13 | # Allow easy setting of the OOM behaviour 14 | # Test with: docker run -p 8983:8983 -it -e OOM=script -e SOLR_JAVA_MEM="-Xms25m -Xmx25m" solr 15 | if [[ -z "${OOM:-}" ]]; then 16 | OOM='none' 17 | fi 18 | case "$OOM" in 19 | 'script') 20 | EXTRA_ARGS+=(-a '-XX:OnOutOfMemoryError=/opt/docker-solr/scripts/oom_solr.sh') 21 | ;; 22 | 'exit') 23 | # recommended 24 | EXTRA_ARGS+=(-a '-XX:+ExitOnOutOfMemoryError') 25 | ;; 26 | 'crash') 27 | EXTRA_ARGS+=(-a '-XX:+CrashOnOutOfMemoryError') 28 | ;; 29 | 'none'|'') 30 | ;; 31 | *) 32 | echo "Unsupported value in OOM=$OOM" 33 | exit 1 34 | esac 35 | 36 | echo "Starting Solr $SOLR_VERSION" 37 | # determine TINI default. If it is already set, assume the user knows what they want 38 | if [[ -z "${TINI:-}" ]]; then 39 | if [[ "$$" == 1 ]]; then 40 | # Default to running tini, so we can run with an OOM script and have 'kill -9' work 41 | TINI=yes 42 | else 43 | # Presumably we're already running under tini through 'docker --init', in which case we 44 | # don't need to run it twice. 45 | # It's also possible that we're run from a wrapper script without exec, 46 | # in which case running tini would not be ideal either. 47 | TINI=no 48 | fi 49 | fi 50 | if [[ "$TINI" == yes ]]; then 51 | exec /usr/bin/tini -- solr -f "$@" "${EXTRA_ARGS[@]}" 52 | elif [[ "$TINI" == no ]]; then 53 | exec solr -f "$@" "${EXTRA_ARGS[@]}" 54 | else 55 | echo "invalid value TINI=$TINI" 56 | exit 1 57 | fi 58 | -------------------------------------------------------------------------------- /8.11-slim/scripts/solr-foreground: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run the initdb, then start solr in the foreground 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | # init script for handling an empty /var/solr 11 | /opt/docker-solr/scripts/init-var-solr 12 | 13 | . /opt/docker-solr/scripts/run-initdb 14 | 15 | exec solr-fg "$@" 16 | -------------------------------------------------------------------------------- /8.11-slim/scripts/solr-precreate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Create a core on disk and then run solr in the foreground 4 | # arguments are: corename configdir 5 | # To simply create a core: 6 | # docker run -P -d solr solr-precreate mycore 7 | # To create a core from mounted config: 8 | # docker run -P -d -v $PWD/myconfig:/myconfig solr solr-precreate mycore /myconfig 9 | # To create a core in a mounted directory: 10 | # mkdir myvarsolr; chown 8983:8983 myvarsolr 11 | # docker run -it --rm -P -v $PWD/myvarsolr://var/solr solr solr-precreate mycore 12 | set -e 13 | 14 | echo "Executing $0" "$@" 15 | 16 | if [[ "${VERBOSE:-}" == "yes" ]]; then 17 | set -x 18 | fi 19 | 20 | # init script for handling an empty /var/solr 21 | /opt/docker-solr/scripts/init-var-solr 22 | 23 | . /opt/docker-solr/scripts/run-initdb 24 | 25 | /opt/docker-solr/scripts/precreate-core "$@" 26 | 27 | exec solr-fg 28 | -------------------------------------------------------------------------------- /8.11-slim/scripts/start-local-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # configure Solr to run on the local interface, and start it running in the background 3 | 4 | set -euo pipefail 5 | 6 | if [[ "${VERBOSE:-}" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | echo "Running solr in the background. Logs are in /var/solr/logs" 11 | SOLR_OPTS="-Djetty.host=${SOLR_LOCAL_HOST:-localhost} -Dlog4j2.formatMsgNoLookups=true" solr start 12 | max_try=${MAX_TRY:-12} 13 | wait_seconds=${WAIT_SECONDS:-5} 14 | if ! /opt/docker-solr/scripts/wait-for-solr.sh --max-attempts "$max_try" --wait-seconds "$wait_seconds"; then 15 | echo "Could not start Solr." 16 | if [ -f "/var/solr/logs/solr.log" ]; then 17 | echo "Here is the log:" 18 | cat "/var/solr/logs/solr.log" 19 | fi 20 | exit 1 21 | fi 22 | -------------------------------------------------------------------------------- /8.11-slim/scripts/stop-local-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # stop the background Solr, and restore the normal configuration 3 | 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | echo "Shutting down the background Solr" 11 | solr stop 12 | -------------------------------------------------------------------------------- /8.11-slim/scripts/wait-for-solr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to wait for solr 4 | # 5 | # Usage: wait-for-solr.sh [--max-attempts count] [--wait-seconds seconds] [--solr-url url] 6 | # Deprecated usage: wait-for-solr.sh [ max_attempts [ wait_seconds ] ] 7 | 8 | set -euo pipefail 9 | 10 | SCRIPT="$0" 11 | 12 | if [[ "${VERBOSE:-}" == "yes" ]]; then 13 | set -x 14 | fi 15 | 16 | function usage { 17 | echo "$1" 18 | echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] [--solr-url url]" 19 | exit 1 20 | } 21 | 22 | max_attempts=12 23 | wait_seconds=5 24 | 25 | if [[ -v SOLR_PORT ]] && ! grep -E -q '^[0-9]+$' <<<"$SOLR_PORT"; then 26 | echo "Invalid SOLR_PORT=$SOLR_PORT environment variable specified" 27 | exit 1 28 | fi 29 | 30 | solr_url="http://localhost:${SOLR_PORT:-8983}" 31 | 32 | while (( $# > 0 )); do 33 | case "$1" in 34 | --help) 35 | cat <0" 75 | exit 1 76 | fi 77 | grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number" 78 | grep -q -E '^https?://' <<<"$solr_url" || usage "--solr-url $solr_url: not a URL" 79 | 80 | ((attempts_left=max_attempts)) 81 | while (( attempts_left > 0 )); do 82 | if wget -q -O - "$solr_url" | grep -i solr >/dev/null; then 83 | break 84 | fi 85 | (( attempts_left-- )) 86 | if (( attempts_left == 0 )); then 87 | echo "Solr is still not running; giving up" 88 | exit 1 89 | fi 90 | if (( attempts_left == 1 )); then 91 | attempts=attempt 92 | else 93 | attempts=attempts 94 | fi 95 | echo "Solr is not running yet on $solr_url. $attempts_left $attempts left" 96 | sleep "$wait_seconds" 97 | done 98 | echo "Solr is running on $solr_url" 99 | -------------------------------------------------------------------------------- /8.11-slim/scripts/wait-for-zookeeper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to wait for ZooKeeper 4 | # 5 | # This script waits for a ZooKeeper master to appear. 6 | # It repeatedly looks up the name passed as argument 7 | # in the DNS using getent, and then connects to the 8 | # ZooKeeper admin port and uses the 'srvr' command to 9 | # obtain the server's status. 10 | # You can use this in a Kubernetes init container to 11 | # delay Solr pods starting until the ZooKeeper service 12 | # has settled down. Or you could explicitly run this in 13 | # the Solr container before exec'ing Solr. 14 | # 15 | # Inspired by https://github.com/helm/charts/blob/9eba7b1c80990233a68dce48f4a8fe0baf9b7fa5/incubator/solr/templates/statefulset.yaml#L60 16 | # 17 | # Usage: wait-for-zookeeper.sh [--max-attempts count] [--wait-seconds seconds] zookeeper-service-name 18 | # 19 | # If no argument is provided, but a Solr-style ZK_HOST is set, 20 | # that will be used. If neither is provided, the default 21 | # name is 'solr-zookeeper-headless', to match the helm chart. 22 | 23 | set -euo pipefail 24 | 25 | SCRIPT="$0" 26 | 27 | if [[ "${VERBOSE:-}" == "yes" ]]; then 28 | set -x 29 | fi 30 | 31 | function usage { 32 | echo "$1" 33 | echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] zookeeper-service-name" 34 | exit 1 35 | } 36 | 37 | TMP_HOSTS="/tmp/hosts.$$" 38 | TMP_STATUS="/tmp/status.$$" 39 | 40 | function cleanup { 41 | rm -f $TMP_HOSTS $TMP_STATUS 42 | } 43 | 44 | trap cleanup EXIT 45 | 46 | function check_zookeeper { 47 | local host=$1 48 | local port="${2:-2181}" 49 | if ! echo srvr | nc "$host" "$port" > $TMP_STATUS; then 50 | echo "Failed to get status from $host" 51 | return 52 | fi 53 | if [ ! -s $TMP_STATUS ]; then 54 | echo "No data from $ip" 55 | return 56 | fi 57 | if grep -q 'not currently serving requests' $TMP_STATUS; then 58 | echo "Node $ip is not currently serving requests" 59 | return 60 | fi 61 | mode=$(grep "Mode: " $TMP_STATUS | sed 's/Mode: //'); 62 | if [ -z "$mode" ]; then 63 | echo "Cannot determine mode from:" 64 | cat $TMP_STATUS 65 | return 66 | fi 67 | echo "Node $ip is a $mode" 68 | if [ "$mode" = "leader" ] || [ "$mode" = "standalone" ]; then 69 | echo "Done" 70 | exit 0 71 | fi 72 | } 73 | 74 | max_attempts=120 75 | wait_seconds=2 76 | while (( $# > 0 )); do 77 | case "$1" in 78 | --help) 79 | cat <0" 114 | exit 1 115 | fi 116 | grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number" 117 | 118 | if [ -z "${lookup_arg:-}" ]; then 119 | if [ -n "$ZK_HOST" ]; then 120 | lookup_arg="$ZK_HOST" 121 | else 122 | lookup_arg=solr-zookeeper-headless 123 | fi 124 | fi 125 | 126 | echo "Looking up '$lookup_arg'" 127 | # split on commas, for when a ZK_HOST string like zoo1:2181,zoo2:2181 is used 128 | IFS=',' read -ra lookups <<< "$lookup_arg" 129 | ((attempts_left=max_attempts)) 130 | while (( attempts_left > 0 )); do 131 | for lookup in "${lookups[@]}"; do 132 | if grep -q -E "^\[[0-9].*\]" <<<"$lookup"; then 133 | # looks like an IPv6 address, eg [2001:DB8::1] or [2001:DB8::1]:2181 134 | # getent does not support the bracket notation, but does support IPv6 addresses 135 | host=$(sed -E 's/\[(.*)\].*/\1/' <<<"$lookup") 136 | port=$(sed -E 's/^\[(.*)\]:?//' <<<"$lookup") 137 | else 138 | # IPv4, just split on : 139 | IFS=: read -ra split <<<"$lookup" 140 | host="${split[0]}" 141 | port="${split[1]:-}" 142 | fi 143 | if [[ "${VERBOSE:-}" == "yes" ]]; then 144 | echo "Parsed host=$host port=${port:-}" 145 | fi 146 | if getent hosts "$host" > $TMP_HOSTS; then 147 | while read -r ip hostname ; do 148 | echo "${hostname:-}">/dev/null # consume for shellcheck 149 | check_zookeeper "$ip" "$port" 150 | done <$TMP_HOSTS 151 | else 152 | echo "Cannot find $lookup yet" 153 | fi 154 | done 155 | (( attempts_left-- )) 156 | if (( attempts_left == 0 )); then echo "Still no master found; giving up" 157 | exit 1 158 | fi 159 | sleep "$wait_seconds" 160 | done 161 | 162 | # To test the parsing: 163 | # bash scripts/wait-for-zookeeper.sh foo 164 | # bash scripts/wait-for-zookeeper.sh 'ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2' 165 | # ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2 bash scripts/wait-for-zookeeper.sh 166 | -------------------------------------------------------------------------------- /8.11/Dockerfile: -------------------------------------------------------------------------------- 1 | # Patched 2022-10-20 to change from openjdk:11-jre to eclipse-temurin:11-jre 2 | # Patched 2022-10-21 to use eclipse-temurin:11-jre-focal which used Ubuntu 20.04, compatible with Docker client < 20.10.16 3 | # Patched 2023-04-01 to upgrade jattach to v2.0 4 | FROM eclipse-temurin:11-jre-focal 5 | 6 | LABEL maintainer="The Apache Lucene/Solr Project" 7 | LABEL repository="https://github.com/docker-solr/docker-solr" 8 | 9 | ARG SOLR_VERSION="8.11.4" 10 | ARG SOLR_SHA512="828a7c3c06f3ccca852f2c3f91d72bf032cf102646283f4e603bbc3c3f3753978ce8b5c014c4263fb66c251b6726105956ad726baee63af6568637eba0416612" 11 | ARG SOLR_KEYS="50E3EE1C91C7E0CB4DFB007B369424FC98F3F6EC" 12 | # If specified, this will override SOLR_DOWNLOAD_SERVER and all ASF mirrors. Typically used downstream for custom builds 13 | ARG SOLR_DOWNLOAD_URL 14 | 15 | # Override the solr download location with e.g.: 16 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=http://www-eu.apache.org/dist/lucene/solr . 17 | ARG SOLR_DOWNLOAD_SERVER 18 | 19 | RUN set -ex; \ 20 | apt-get update; \ 21 | apt-get -y install acl dirmngr gpg lsof procps wget netcat gosu tini; \ 22 | rm -rf /var/lib/apt/lists/*; \ 23 | cd /usr/local/bin; wget -nv https://github.com/apangin/jattach/releases/download/v2.0/jattach; chmod 755 jattach; \ 24 | echo >jattach.sha512 "a19e774600d6aa844bceb2189285848127a70130a69fb1840c10367f3360972c733b3f09e60e9672d387e2d48c750ab56acfe8f80f7c6af76f5d1123e5ad7222 jattach"; \ 25 | sha512sum -c jattach.sha512; rm jattach.sha512 26 | 27 | ENV SOLR_USER="solr" \ 28 | SOLR_UID="8983" \ 29 | SOLR_GROUP="solr" \ 30 | SOLR_GID="8983" \ 31 | SOLR_CLOSER_URL="https://www.apache.org/dyn/closer.lua/lucene/solr/${SOLR_VERSION}/solr-${SOLR_VERSION}.tgz?action=download" \ 32 | SOLR_DIST_URL="https://downloads.apache.org/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \ 33 | SOLR_ARCHIVE_URL="https://archive.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \ 34 | PATH="/opt/solr/bin:/opt/docker-solr/scripts:$PATH" \ 35 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 36 | SOLR_HOME=/var/solr/data \ 37 | SOLR_PID_DIR=/var/solr \ 38 | SOLR_LOGS_DIR=/var/solr/logs \ 39 | LOG4J_PROPS=/var/solr/log4j2.xml 40 | 41 | RUN set -ex; \ 42 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 43 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 44 | 45 | RUN set -ex; \ 46 | export GNUPGHOME="/tmp/gnupg_home"; \ 47 | mkdir -p "$GNUPGHOME"; \ 48 | chmod 700 "$GNUPGHOME"; \ 49 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 50 | for key in $SOLR_KEYS; do \ 51 | found=''; \ 52 | for server in \ 53 | ha.pool.sks-keyservers.net \ 54 | hkp://keyserver.ubuntu.com:80 \ 55 | hkp://p80.pool.sks-keyservers.net:80 \ 56 | pgp.mit.edu \ 57 | ; do \ 58 | echo " trying $server for $key"; \ 59 | gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \ 60 | gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \ 61 | done; \ 62 | test -z "$found" && echo >&2 "error: failed to fetch $key from several disparate servers -- network issues?" && exit 1; \ 63 | done; \ 64 | exit 0 65 | 66 | RUN set -ex; \ 67 | export GNUPGHOME="/tmp/gnupg_home"; \ 68 | MAX_REDIRECTS=1; \ 69 | if [ -n "$SOLR_DOWNLOAD_URL" ]; then \ 70 | # If a custom URL is defined, we download from non-ASF mirror URL and allow more redirects and skip GPG step 71 | # This takes effect only if the SOLR_DOWNLOAD_URL build-arg is specified, typically in downstream Dockerfiles 72 | MAX_REDIRECTS=4; \ 73 | SKIP_GPG_CHECK=true; \ 74 | elif [ -n "$SOLR_DOWNLOAD_SERVER" ]; then \ 75 | SOLR_DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"; \ 76 | fi; \ 77 | for url in $SOLR_DOWNLOAD_URL $SOLR_CLOSER_URL $SOLR_DIST_URL $SOLR_ARCHIVE_URL; do \ 78 | if [ -f "/opt/solr-$SOLR_VERSION.tgz" ]; then break; fi; \ 79 | echo "downloading $url"; \ 80 | if wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$url" -O "/opt/solr-$SOLR_VERSION.tgz"; then break; else rm -f "/opt/solr-$SOLR_VERSION.tgz"; fi; \ 81 | done; \ 82 | if [ ! -f "/opt/solr-$SOLR_VERSION.tgz" ]; then echo "failed all download attempts for solr-$SOLR_VERSION.tgz"; exit 1; fi; \ 83 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 84 | echo "downloading $SOLR_ARCHIVE_URL.asc"; \ 85 | wget -nv "$SOLR_ARCHIVE_URL.asc" -O "/opt/solr-$SOLR_VERSION.tgz.asc"; \ 86 | echo "$SOLR_SHA512 */opt/solr-$SOLR_VERSION.tgz" | sha512sum -c -; \ 87 | (>&2 ls -l "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz.asc"); \ 88 | gpg --batch --verify "/opt/solr-$SOLR_VERSION.tgz.asc" "/opt/solr-$SOLR_VERSION.tgz"; \ 89 | else \ 90 | echo "Skipping GPG validation due to non-Apache build"; \ 91 | fi; \ 92 | tar -C /opt --extract --file "/opt/solr-$SOLR_VERSION.tgz"; \ 93 | (cd /opt; ln -s "solr-$SOLR_VERSION" solr); \ 94 | rm "/opt/solr-$SOLR_VERSION.tgz"*; \ 95 | rm -Rf /opt/solr/docs/ /opt/solr/dist/{solr-core-$SOLR_VERSION.jar,solr-solrj-$SOLR_VERSION.jar,solrj-lib,solr-test-framework-$SOLR_VERSION.jar,test-framework}; \ 96 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d /opt/docker-solr; \ 97 | chown -R 0:0 "/opt/solr-$SOLR_VERSION"; \ 98 | find "/opt/solr-$SOLR_VERSION" -type d -print0 | xargs -0 chmod 0755; \ 99 | find "/opt/solr-$SOLR_VERSION" -type f -print0 | xargs -0 chmod 0644; \ 100 | chmod -R 0755 "/opt/solr-$SOLR_VERSION/bin" "/opt/solr-$SOLR_VERSION/contrib/prometheus-exporter/bin/solr-exporter" /opt/solr-$SOLR_VERSION/server/scripts/cloud-scripts; \ 101 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 102 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 103 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 104 | chown root:0 /etc/default/solr.in.sh; \ 105 | chmod 0664 /etc/default/solr.in.sh; \ 106 | mkdir -p /var/solr/data /var/solr/logs; \ 107 | (cd /opt/solr/server/solr; cp solr.xml zoo.cfg /var/solr/data/); \ 108 | cp /opt/solr/server/resources/log4j2.xml /var/solr/log4j2.xml; \ 109 | find /var/solr -type d -print0 | xargs -0 chmod 0770; \ 110 | find /var/solr -type f -print0 | xargs -0 chmod 0660; \ 111 | sed -i -e "s/\"\$(whoami)\" == \"root\"/\$(id -u) == 0/" /opt/solr/bin/solr; \ 112 | sed -i -e 's/lsof -PniTCP:/lsof -t -PniTCP:/' /opt/solr/bin/solr; \ 113 | chown -R "0:0" /opt/solr-$SOLR_VERSION /docker-entrypoint-initdb.d /opt/docker-solr; \ 114 | chown -R "$SOLR_USER:0" /var/solr; \ 115 | { command -v gpgconf; gpgconf --kill all || :; }; \ 116 | rm -r "$GNUPGHOME" 117 | 118 | COPY --chown=0:0 scripts /opt/docker-solr/scripts 119 | 120 | VOLUME /var/solr 121 | EXPOSE 8983 122 | WORKDIR /opt/solr 123 | USER $SOLR_UID 124 | 125 | ENTRYPOINT ["docker-entrypoint.sh"] 126 | CMD ["solr-foreground"] 127 | -------------------------------------------------------------------------------- /8.11/scripts/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # docker-entrypoint for docker-solr 4 | 5 | set -e 6 | 7 | # Clear some variables that we don't want runtime 8 | unset SOLR_USER SOLR_UID SOLR_GROUP SOLR_GID \ 9 | SOLR_CLOSER_URL SOLR_DIST_URL SOLR_ARCHIVE_URL SOLR_DOWNLOAD_URL SOLR_DOWNLOAD_SERVER SOLR_KEYS SOLR_SHA512 10 | 11 | if [[ "$VERBOSE" == "yes" ]]; then 12 | set -x 13 | fi 14 | 15 | if [[ -v SOLR_PORT ]] && ! grep -E -q '^[0-9]+$' <<<"${SOLR_PORT:-}"; then 16 | SOLR_PORT=8983 17 | export SOLR_PORT 18 | fi 19 | 20 | # when invoked with e.g.: docker run solr -help 21 | if [ "${1:0:1}" == '-' ]; then 22 | set -- solr-foreground "$@" 23 | fi 24 | 25 | # execute command passed in as arguments. 26 | # The Dockerfile has specified the PATH to include 27 | # /opt/solr/bin (for Solr) and /opt/docker-solr/scripts (for our scripts 28 | # like solr-foreground, solr-create, solr-precreate, solr-demo). 29 | # Note: if you specify "solr", you'll typically want to add -f to run it in 30 | # the foreground. 31 | exec "$@" 32 | -------------------------------------------------------------------------------- /8.11/scripts/init-var-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to initialise an empty $DIR 4 | # If you use volumes then Docker will copy the $DIR content from the container to the volume. 5 | # If you use bind mounts, that does not happen, so we do it here. 6 | 7 | set -e 8 | 9 | if [[ "$VERBOSE" == "yes" ]]; then 10 | set -x 11 | fi 12 | 13 | if [[ -n "${NO_INIT_VAR_SOLR:-}" ]]; then 14 | exit 0 15 | fi 16 | 17 | DIR=${1:-/var/solr} 18 | 19 | if [ ! -d "$DIR" ]; then 20 | echo "Missing $DIR" 21 | exit 1 22 | fi 23 | 24 | function check_dir_writability { 25 | local dir="$1" 26 | if [ ! -w "$dir" ]; then 27 | echo "Cannot write to $dir as $(id -u):$(id -g)" 28 | ls -ld "$dir" 29 | exit 1 30 | fi 31 | } 32 | 33 | if [ ! -d "$DIR/data" ]; then 34 | echo "Creating $DIR/data" 35 | check_dir_writability "$DIR" 36 | mkdir "$DIR/data" 37 | chmod 0770 "$DIR/data" 38 | fi 39 | 40 | if [ ! -d "$DIR/logs" ]; then 41 | echo "Creating $DIR/logs" 42 | check_dir_writability "$DIR" 43 | mkdir "$DIR/logs" 44 | chmod 0770 "$DIR/logs" 45 | fi 46 | 47 | if [ ! -f "$DIR/data/solr.xml" ]; then 48 | echo "Copying solr.xml" 49 | cp -a /opt/solr/server/solr/solr.xml "$DIR/data/solr.xml" 50 | fi 51 | 52 | if [ ! -f "$DIR/data/zoo.cfg" ]; then 53 | echo "Copying zoo.cfg" 54 | cp -a /opt/solr/server/solr/zoo.cfg "$DIR/data/zoo.cfg" 55 | fi 56 | 57 | if [ ! -f "$DIR/log4j2.xml" ]; then 58 | echo "Copying log4j2.xml" 59 | cp -a /opt/solr/server/resources/log4j2.xml "$DIR/log4j2.xml" 60 | fi 61 | 62 | -------------------------------------------------------------------------------- /8.11/scripts/oom_solr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Custom oom handler loosely based on 4 | # https://github.com/apache/lucene-solr/blob/master/solr/bin/oom_solr.sh 5 | # See solr-forgeground for how to configure OOM behaviour 6 | 7 | if [[ -z "${SOLR_LOGS_DIR:-}" ]]; then 8 | if [ -d /var/solr/logs ]; then 9 | SOLR_LOGS_DIR=/var/solr/logs 10 | elif [ -d /opt/solr/server/logs ]; then 11 | SOLR_LOGS_DIR=/opt/solr/server/logs 12 | else 13 | echo "Cannot determine SOLR_LOGS_DIR!" 14 | exit 1 15 | fi 16 | fi 17 | SOLR_PID=$(pgrep -f start.jar) 18 | if [[ -z "$SOLR_PID" ]]; then 19 | echo "Couldn't find Solr process running!" 20 | exit 21 | fi 22 | 23 | NOW=$(date +"%F_%H_%M_%S") 24 | ( 25 | echo "Running OOM killer script for Solr process $SOLR_PID" 26 | if [[ "$SOLR_PID" == 1 ]]; then 27 | # under Docker, when running as pid 1, a SIGKILL is ignored, 28 | # so use the default SIGTERM 29 | kill "$SOLR_PID" 30 | sleep 2 31 | # if that hasn't worked, send SIGKILL 32 | kill -SIGILL "$SOLR_PID" 33 | else 34 | # if we're running with `--init` or under tini or similar, 35 | # follow the upstream behaviour 36 | kill -9 "$SOLR_PID" 37 | fi 38 | ) | tee "$SOLR_LOGS_DIR/solr_oom_killer-$SOLR_PORT-$NOW.log" 39 | -------------------------------------------------------------------------------- /8.11/scripts/precreate-core: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Create a core on disk 4 | # arguments are: corename configdir 5 | 6 | set -e 7 | 8 | echo "Executing $0" "$@" 9 | 10 | if [[ "${VERBOSE:-}" == "yes" ]]; then 11 | set -x 12 | fi 13 | 14 | CORE=${1:-gettingstarted} 15 | CONFIG_SOURCE="${2:-}" 16 | if [[ -z "$CONFIG_SOURCE" ]]; then 17 | DEFAULT_CONFIGS=(_default data_driven_schema_configs) 18 | for config_dir in "${DEFAULT_CONFIGS[@]}"; do 19 | config_dir="/opt/solr/server/solr/configsets/$config_dir" 20 | if [ -d "$config_dir" ]; then 21 | CONFIG_SOURCE="$config_dir" 22 | break 23 | fi 24 | done 25 | if [[ -z $CONFIG_SOURCE ]]; then 26 | echo "Cannot find default config" 27 | exit 1 28 | fi 29 | fi 30 | 31 | coresdir=/var/solr/data 32 | 33 | coredir="$coresdir/$CORE" 34 | if [[ ! -d $coredir ]]; then 35 | cp -r "$CONFIG_SOURCE/" "$coredir" 36 | touch "$coredir/core.properties" 37 | echo "Created $CORE" 38 | else 39 | echo "Core $CORE already exists" 40 | fi 41 | -------------------------------------------------------------------------------- /8.11/scripts/run-initdb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run the init-solr-home script and source any '.sh' scripts in 4 | # /docker-entrypoint-initdb.d. 5 | # This script is sourced by some of the solr-* commands, so that 6 | # you can run eg: 7 | # 8 | # mkdir initdb; echo "echo hi" > initdb/hi.sh 9 | # docker run -v $PWD/initdb:/docker-entrypoint-initdb.d solr 10 | # 11 | # and have your script execute before Solr starts. 12 | # 13 | # Note: scripts can modify the environment, which will affect 14 | # subsequent scripts and ultimately Solr. That allows you to set 15 | # environment variables from your scripts (though you usually just 16 | # use "docker run -e"). If this is undesirable in your use-case, 17 | # have your scripts execute a sub-shell. 18 | 19 | set -e 20 | 21 | # execute files in /docker-entrypoint-initdb.d before starting solr 22 | while read -r f; do 23 | case "$f" in 24 | *.sh) echo "$0: running $f"; . "$f" ;; 25 | *) echo "$0: ignoring $f" ;; 26 | esac 27 | echo 28 | done < <(find /docker-entrypoint-initdb.d/ -mindepth 1 -type f | sort -n) 29 | -------------------------------------------------------------------------------- /8.11/scripts/solr-create: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This script starts Solr on localhost, creates a core with "solr create", 4 | # stops Solr, and then starts Solr as normal. 5 | # Any arguments are passed to the "solr create". 6 | # To simply create a core: 7 | # docker run -P -d solr solr-create -c mycore 8 | # To create a core from mounted config: 9 | # docker run -P -d -v $PWD/myconfig:/myconfig solr solr-create -c mycore -d /myconfig 10 | 11 | set -euo pipefail 12 | echo "Executing $0" "$@" 13 | 14 | if [[ "${VERBOSE:-}" == "yes" ]]; then 15 | set -x 16 | fi 17 | 18 | # init script for handling an empty /var/solr 19 | /opt/docker-solr/scripts/init-var-solr 20 | 21 | . /opt/docker-solr/scripts/run-initdb 22 | 23 | # solr uses "-c corename". Parse the arguments to determine the core name. 24 | CORE_NAME="$( 25 | while (( $# > 0 )); do 26 | if [[ "$1" == '-c' ]]; then 27 | shift 28 | echo "$1" 29 | fi 30 | shift 31 | done 32 | )" 33 | if [[ -z "${CORE_NAME:-}" ]]; then 34 | echo "Could not determine core name" 35 | exit 1 36 | fi 37 | 38 | coresdir=/var/solr/data 39 | CORE_DIR="$coresdir/$CORE_NAME" 40 | 41 | if [[ -d $CORE_DIR ]]; then 42 | echo "Directory $CORE_DIR exists; skipping core creation" 43 | else 44 | start-local-solr 45 | 46 | echo "Creating core with:" "${@:1}" 47 | /opt/solr/bin/solr create "${@:1}" 48 | 49 | # See https://github.com/docker-solr/docker-solr/issues/27 50 | echo "Checking core" 51 | if ! wget -O - "http://localhost:${SOLR_PORT:-8983}/solr/admin/cores?action=STATUS" | grep instanceDir >/dev/null; then 52 | echo "Could not find any cores" 53 | exit 1 54 | fi 55 | 56 | echo "Created core with:" "${@:1}" 57 | stop-local-solr 58 | 59 | # check the core_dir exists; otherwise the detecting above will fail after stop/start 60 | if [ ! -d "$CORE_DIR" ]; then 61 | echo "Missing $CORE_DIR" 62 | exit 1 63 | fi 64 | fi 65 | 66 | exec solr-fg 67 | -------------------------------------------------------------------------------- /8.11/scripts/solr-demo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Configure a Solr demo and then run solr in the foreground 4 | 5 | set -euo pipefail 6 | 7 | if [[ "${VERBOSE:-}" == "yes" ]]; then 8 | set -x 9 | fi 10 | 11 | . /opt/docker-solr/scripts/run-initdb 12 | 13 | CORE=demo 14 | 15 | coresdir=/var/solr/data 16 | CORE_DIR="$coresdir/demo" 17 | if [ -d "$CORE_DIR" ]; then 18 | echo "$CORE_DIR exists; skipping demo creation" 19 | else 20 | start-local-solr 21 | echo "Creating $CORE" 22 | /opt/solr/bin/solr create -c "$CORE" 23 | echo "Created $CORE" 24 | echo "Loading example data" 25 | post_args=() 26 | if [[ -n "${SOLR_PORT:-}" ]]; then 27 | post_args+=(-p "$SOLR_PORT") 28 | fi 29 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/*.xml 30 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/books.json 31 | /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit yes example/exampledocs/books.csv 32 | echo "Loaded example data" 33 | stop-local-solr 34 | 35 | # check the core_dir exists; otherwise the detecting above will fail after stop/start 36 | if [ ! -d "$CORE_DIR" ]; then 37 | echo "Missing $CORE_DIR" 38 | exit 1 39 | fi 40 | fi 41 | 42 | exec solr-fg 43 | -------------------------------------------------------------------------------- /8.11/scripts/solr-fg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # start solr in the foreground 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | EXTRA_ARGS=() 11 | EXTRA_ARGS+=('-Dlog4j2.formatMsgNoLookups=true') 12 | 13 | # Allow easy setting of the OOM behaviour 14 | # Test with: docker run -p 8983:8983 -it -e OOM=script -e SOLR_JAVA_MEM="-Xms25m -Xmx25m" solr 15 | if [[ -z "${OOM:-}" ]]; then 16 | OOM='none' 17 | fi 18 | case "$OOM" in 19 | 'script') 20 | EXTRA_ARGS+=(-a '-XX:OnOutOfMemoryError=/opt/docker-solr/scripts/oom_solr.sh') 21 | ;; 22 | 'exit') 23 | # recommended 24 | EXTRA_ARGS+=(-a '-XX:+ExitOnOutOfMemoryError') 25 | ;; 26 | 'crash') 27 | EXTRA_ARGS+=(-a '-XX:+CrashOnOutOfMemoryError') 28 | ;; 29 | 'none'|'') 30 | ;; 31 | *) 32 | echo "Unsupported value in OOM=$OOM" 33 | exit 1 34 | esac 35 | 36 | echo "Starting Solr $SOLR_VERSION" 37 | # determine TINI default. If it is already set, assume the user knows what they want 38 | if [[ -z "${TINI:-}" ]]; then 39 | if [[ "$$" == 1 ]]; then 40 | # Default to running tini, so we can run with an OOM script and have 'kill -9' work 41 | TINI=yes 42 | else 43 | # Presumably we're already running under tini through 'docker --init', in which case we 44 | # don't need to run it twice. 45 | # It's also possible that we're run from a wrapper script without exec, 46 | # in which case running tini would not be ideal either. 47 | TINI=no 48 | fi 49 | fi 50 | if [[ "$TINI" == yes ]]; then 51 | exec /usr/bin/tini -- solr -f "$@" "${EXTRA_ARGS[@]}" 52 | elif [[ "$TINI" == no ]]; then 53 | exec solr -f "$@" "${EXTRA_ARGS[@]}" 54 | else 55 | echo "invalid value TINI=$TINI" 56 | exit 1 57 | fi 58 | -------------------------------------------------------------------------------- /8.11/scripts/solr-foreground: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run the initdb, then start solr in the foreground 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | # init script for handling an empty /var/solr 11 | /opt/docker-solr/scripts/init-var-solr 12 | 13 | . /opt/docker-solr/scripts/run-initdb 14 | 15 | exec solr-fg "$@" 16 | -------------------------------------------------------------------------------- /8.11/scripts/solr-precreate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Create a core on disk and then run solr in the foreground 4 | # arguments are: corename configdir 5 | # To simply create a core: 6 | # docker run -P -d solr solr-precreate mycore 7 | # To create a core from mounted config: 8 | # docker run -P -d -v $PWD/myconfig:/myconfig solr solr-precreate mycore /myconfig 9 | # To create a core in a mounted directory: 10 | # mkdir myvarsolr; chown 8983:8983 myvarsolr 11 | # docker run -it --rm -P -v $PWD/myvarsolr://var/solr solr solr-precreate mycore 12 | set -e 13 | 14 | echo "Executing $0" "$@" 15 | 16 | if [[ "${VERBOSE:-}" == "yes" ]]; then 17 | set -x 18 | fi 19 | 20 | # init script for handling an empty /var/solr 21 | /opt/docker-solr/scripts/init-var-solr 22 | 23 | . /opt/docker-solr/scripts/run-initdb 24 | 25 | /opt/docker-solr/scripts/precreate-core "$@" 26 | 27 | exec solr-fg 28 | -------------------------------------------------------------------------------- /8.11/scripts/start-local-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # configure Solr to run on the local interface, and start it running in the background 3 | 4 | set -euo pipefail 5 | 6 | if [[ "${VERBOSE:-}" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | echo "Running solr in the background. Logs are in /var/solr/logs" 11 | SOLR_OPTS="-Djetty.host=${SOLR_LOCAL_HOST:-localhost} -Dlog4j2.formatMsgNoLookups=true" solr start 12 | max_try=${MAX_TRY:-12} 13 | wait_seconds=${WAIT_SECONDS:-5} 14 | if ! /opt/docker-solr/scripts/wait-for-solr.sh --max-attempts "$max_try" --wait-seconds "$wait_seconds"; then 15 | echo "Could not start Solr." 16 | if [ -f "/var/solr/logs/solr.log" ]; then 17 | echo "Here is the log:" 18 | cat "/var/solr/logs/solr.log" 19 | fi 20 | exit 1 21 | fi 22 | -------------------------------------------------------------------------------- /8.11/scripts/stop-local-solr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # stop the background Solr, and restore the normal configuration 3 | 4 | set -e 5 | 6 | if [[ "$VERBOSE" == "yes" ]]; then 7 | set -x 8 | fi 9 | 10 | echo "Shutting down the background Solr" 11 | solr stop 12 | -------------------------------------------------------------------------------- /8.11/scripts/wait-for-solr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to wait for solr 4 | # 5 | # Usage: wait-for-solr.sh [--max-attempts count] [--wait-seconds seconds] [--solr-url url] 6 | # Deprecated usage: wait-for-solr.sh [ max_attempts [ wait_seconds ] ] 7 | 8 | set -euo pipefail 9 | 10 | SCRIPT="$0" 11 | 12 | if [[ "${VERBOSE:-}" == "yes" ]]; then 13 | set -x 14 | fi 15 | 16 | function usage { 17 | echo "$1" 18 | echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] [--solr-url url]" 19 | exit 1 20 | } 21 | 22 | max_attempts=12 23 | wait_seconds=5 24 | 25 | if [[ -v SOLR_PORT ]] && ! grep -E -q '^[0-9]+$' <<<"$SOLR_PORT"; then 26 | echo "Invalid SOLR_PORT=$SOLR_PORT environment variable specified" 27 | exit 1 28 | fi 29 | 30 | solr_url="http://localhost:${SOLR_PORT:-8983}" 31 | 32 | while (( $# > 0 )); do 33 | case "$1" in 34 | --help) 35 | cat <0" 75 | exit 1 76 | fi 77 | grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number" 78 | grep -q -E '^https?://' <<<"$solr_url" || usage "--solr-url $solr_url: not a URL" 79 | 80 | ((attempts_left=max_attempts)) 81 | while (( attempts_left > 0 )); do 82 | if wget -q -O - "$solr_url" | grep -i solr >/dev/null; then 83 | break 84 | fi 85 | (( attempts_left-- )) 86 | if (( attempts_left == 0 )); then 87 | echo "Solr is still not running; giving up" 88 | exit 1 89 | fi 90 | if (( attempts_left == 1 )); then 91 | attempts=attempt 92 | else 93 | attempts=attempts 94 | fi 95 | echo "Solr is not running yet on $solr_url. $attempts_left $attempts left" 96 | sleep "$wait_seconds" 97 | done 98 | echo "Solr is running on $solr_url" 99 | -------------------------------------------------------------------------------- /8.11/scripts/wait-for-zookeeper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A helper script to wait for ZooKeeper 4 | # 5 | # This script waits for a ZooKeeper master to appear. 6 | # It repeatedly looks up the name passed as argument 7 | # in the DNS using getent, and then connects to the 8 | # ZooKeeper admin port and uses the 'srvr' command to 9 | # obtain the server's status. 10 | # You can use this in a Kubernetes init container to 11 | # delay Solr pods starting until the ZooKeeper service 12 | # has settled down. Or you could explicitly run this in 13 | # the Solr container before exec'ing Solr. 14 | # 15 | # Inspired by https://github.com/helm/charts/blob/9eba7b1c80990233a68dce48f4a8fe0baf9b7fa5/incubator/solr/templates/statefulset.yaml#L60 16 | # 17 | # Usage: wait-for-zookeeper.sh [--max-attempts count] [--wait-seconds seconds] zookeeper-service-name 18 | # 19 | # If no argument is provided, but a Solr-style ZK_HOST is set, 20 | # that will be used. If neither is provided, the default 21 | # name is 'solr-zookeeper-headless', to match the helm chart. 22 | 23 | set -euo pipefail 24 | 25 | SCRIPT="$0" 26 | 27 | if [[ "${VERBOSE:-}" == "yes" ]]; then 28 | set -x 29 | fi 30 | 31 | function usage { 32 | echo "$1" 33 | echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] zookeeper-service-name" 34 | exit 1 35 | } 36 | 37 | TMP_HOSTS="/tmp/hosts.$$" 38 | TMP_STATUS="/tmp/status.$$" 39 | 40 | function cleanup { 41 | rm -f $TMP_HOSTS $TMP_STATUS 42 | } 43 | 44 | trap cleanup EXIT 45 | 46 | function check_zookeeper { 47 | local host=$1 48 | local port="${2:-2181}" 49 | if ! echo srvr | nc "$host" "$port" > $TMP_STATUS; then 50 | echo "Failed to get status from $host" 51 | return 52 | fi 53 | if [ ! -s $TMP_STATUS ]; then 54 | echo "No data from $ip" 55 | return 56 | fi 57 | if grep -q 'not currently serving requests' $TMP_STATUS; then 58 | echo "Node $ip is not currently serving requests" 59 | return 60 | fi 61 | mode=$(grep "Mode: " $TMP_STATUS | sed 's/Mode: //'); 62 | if [ -z "$mode" ]; then 63 | echo "Cannot determine mode from:" 64 | cat $TMP_STATUS 65 | return 66 | fi 67 | echo "Node $ip is a $mode" 68 | if [ "$mode" = "leader" ] || [ "$mode" = "standalone" ]; then 69 | echo "Done" 70 | exit 0 71 | fi 72 | } 73 | 74 | max_attempts=120 75 | wait_seconds=2 76 | while (( $# > 0 )); do 77 | case "$1" in 78 | --help) 79 | cat <0" 114 | exit 1 115 | fi 116 | grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number" 117 | 118 | if [ -z "${lookup_arg:-}" ]; then 119 | if [ -n "$ZK_HOST" ]; then 120 | lookup_arg="$ZK_HOST" 121 | else 122 | lookup_arg=solr-zookeeper-headless 123 | fi 124 | fi 125 | 126 | echo "Looking up '$lookup_arg'" 127 | # split on commas, for when a ZK_HOST string like zoo1:2181,zoo2:2181 is used 128 | IFS=',' read -ra lookups <<< "$lookup_arg" 129 | ((attempts_left=max_attempts)) 130 | while (( attempts_left > 0 )); do 131 | for lookup in "${lookups[@]}"; do 132 | if grep -q -E "^\[[0-9].*\]" <<<"$lookup"; then 133 | # looks like an IPv6 address, eg [2001:DB8::1] or [2001:DB8::1]:2181 134 | # getent does not support the bracket notation, but does support IPv6 addresses 135 | host=$(sed -E 's/\[(.*)\].*/\1/' <<<"$lookup") 136 | port=$(sed -E 's/^\[(.*)\]:?//' <<<"$lookup") 137 | else 138 | # IPv4, just split on : 139 | IFS=: read -ra split <<<"$lookup" 140 | host="${split[0]}" 141 | port="${split[1]:-}" 142 | fi 143 | if [[ "${VERBOSE:-}" == "yes" ]]; then 144 | echo "Parsed host=$host port=${port:-}" 145 | fi 146 | if getent hosts "$host" > $TMP_HOSTS; then 147 | while read -r ip hostname ; do 148 | echo "${hostname:-}">/dev/null # consume for shellcheck 149 | check_zookeeper "$ip" "$port" 150 | done <$TMP_HOSTS 151 | else 152 | echo "Cannot find $lookup yet" 153 | fi 154 | done 155 | (( attempts_left-- )) 156 | if (( attempts_left == 0 )); then echo "Still no master found; giving up" 157 | exit 1 158 | fi 159 | sleep "$wait_seconds" 160 | done 161 | 162 | # To test the parsing: 163 | # bash scripts/wait-for-zookeeper.sh foo 164 | # bash scripts/wait-for-zookeeper.sh 'ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2' 165 | # ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2 bash scripts/wait-for-zookeeper.sh 166 | -------------------------------------------------------------------------------- /9.7-slim/Dockerfile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | FROM eclipse-temurin:17-jre-jammy 18 | 19 | ARG SOLR_VERSION="9.7.0" 20 | # empty for the full distribution, "-slim" for the slim distribution 21 | ARG SOLR_DIST="-slim" 22 | ARG SOLR_SHA512="f270ebd94deb9a002fb4e57c5cc2c11c7acc583dfa8e65a814028aa22dd8d0fa7c8a18f92024d8c0f5b07853801d25dcb2e26b3b3d4c8b2d906485f8dc0224c9" 23 | ARG SOLR_KEYS="EDF961FF03E647F9CA8A9C2C758051CCA3A13A7F" 24 | 25 | # Override the default solr download location with a preferred mirror, e.g.: 26 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=https://downloads.apache.org/solr/solr . 27 | # This server must support downloading at: ${SOLR_DOWNLOAD_SERVER}/${SOLR_VERSION}/solr-${SOLR_VERSION}(-slim).tgz(.asc) 28 | ARG SOLR_DOWNLOAD_SERVER="https://www.apache.org/dyn/closer.lua?action=download&filename=/solr/solr" 29 | 30 | RUN set -ex; \ 31 | apt-get update; \ 32 | apt-get -y --no-install-recommends install wget gpg gnupg dirmngr; \ 33 | rm -rf /var/lib/apt/lists/*; \ 34 | export SOLR_BINARY="solr-$SOLR_VERSION$SOLR_DIST.tgz"; \ 35 | MAX_REDIRECTS=3; \ 36 | case "${SOLR_DOWNLOAD_SERVER}" in \ 37 | (*"apache.org"*);; \ 38 | (*) \ 39 | # If a non-ASF URL is provided, allow more redirects and skip GPG step. 40 | MAX_REDIRECTS=4 && \ 41 | SKIP_GPG_CHECK=true;; \ 42 | esac; \ 43 | export DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/$SOLR_BINARY"; \ 44 | echo "downloading $DOWNLOAD_URL"; \ 45 | if ! wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$DOWNLOAD_URL" -O "/opt/$SOLR_BINARY"; then rm -f "/opt/$SOLR_BINARY"; fi; \ 46 | if [ ! -f "/opt/$SOLR_BINARY" ]; then echo "failed download attempt for $SOLR_BINARY"; exit 1; fi; \ 47 | echo "$SOLR_SHA512 */opt/$SOLR_BINARY" | sha512sum -c -; \ 48 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 49 | # Setup GPG \ 50 | export GNUPGHOME="/tmp/gnupg_home"; \ 51 | mkdir -p "$GNUPGHOME"; \ 52 | chmod 700 "$GNUPGHOME"; \ 53 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 54 | if [ -n "$SOLR_KEYS" ]; then \ 55 | # Install all Solr GPG Keys to start 56 | wget -nv "https://downloads.apache.org/solr/KEYS" -O- | \ 57 | gpg --batch --import --key-origin 'url,https://downloads.apache.org/solr/KEYS'; \ 58 | # Save just the release key 59 | release_keys="$(gpg --batch --export -a ${SOLR_KEYS})"; \ 60 | rm -rf "$GNUPGHOME"/*; \ 61 | echo "${release_keys}" | gpg --batch --import; \ 62 | fi; \ 63 | # Do GPG Checks 64 | echo "downloading $DOWNLOAD_URL.asc"; \ 65 | wget -nv "$DOWNLOAD_URL.asc" -O "/opt/$SOLR_BINARY.asc"; \ 66 | (>&2 ls -l "/opt/$SOLR_BINARY" "/opt/$SOLR_BINARY.asc"); \ 67 | gpg --batch --verify "/opt/$SOLR_BINARY.asc" "/opt/$SOLR_BINARY"; \ 68 | # Cleanup GPG 69 | { command -v gpgconf; gpgconf --kill all || :; }; \ 70 | rm -r "$GNUPGHOME"; \ 71 | else \ 72 | echo "Skipping GPG validation due to non-Apache build"; \ 73 | fi; \ 74 | tar -C /opt --extract --preserve-permissions --file "/opt/$SOLR_BINARY"; \ 75 | rm "/opt/$SOLR_BINARY"*; \ 76 | apt-get -y remove gpg dirmngr && apt-get -y autoremove; 77 | 78 | 79 | 80 | LABEL org.opencontainers.image.title="Apache Solr" 81 | LABEL org.opencontainers.image.description="Apache Solr is the popular, blazing-fast, open source search platform built on Apache Lucene." 82 | LABEL org.opencontainers.image.authors="The Apache Solr Project" 83 | LABEL org.opencontainers.image.url="https://solr.apache.org" 84 | LABEL org.opencontainers.image.source="https://github.com/apache/solr" 85 | LABEL org.opencontainers.image.documentation="https://solr.apache.org/guide/" 86 | LABEL org.opencontainers.image.version="${SOLR_VERSION}" 87 | LABEL org.opencontainers.image.licenses="Apache-2.0" 88 | 89 | ENV SOLR_USER="solr" \ 90 | SOLR_UID="8983" \ 91 | SOLR_GROUP="solr" \ 92 | SOLR_GID="8983" \ 93 | PATH="/opt/solr/bin:/opt/solr/docker/scripts:/opt/solr/prometheus-exporter/bin:$PATH" \ 94 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 95 | SOLR_HOME=/var/solr/data \ 96 | SOLR_PID_DIR=/var/solr \ 97 | SOLR_LOGS_DIR=/var/solr/logs \ 98 | LOG4J_PROPS=/var/solr/log4j2.xml \ 99 | SOLR_JETTY_HOST="0.0.0.0" \ 100 | SOLR_ZK_EMBEDDED_HOST="0.0.0.0" 101 | 102 | RUN set -ex; \ 103 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 104 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 105 | 106 | # add symlink to /opt/solr, remove what we don't want. 107 | # Remove the Dockerfile because it might not represent the dockerfile that was used to generate the image. 108 | RUN set -ex; \ 109 | (cd /opt; ln -s solr-*/ solr); \ 110 | rm -Rf /opt/solr/docs /opt/solr/docker/Dockerfile; 111 | 112 | RUN set -ex; \ 113 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d; \ 114 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 115 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 116 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 117 | chmod 0664 /etc/default/solr.in.sh; \ 118 | mkdir -p -m0770 /var/solr; \ 119 | chown -R "$SOLR_USER:0" /var/solr; \ 120 | test ! -e /opt/solr/modules || ln -s /opt/solr/modules /opt/solr/contrib; \ 121 | test ! -e /opt/solr/prometheus-exporter || ln -s /opt/solr/prometheus-exporter /opt/solr/modules/prometheus-exporter; 122 | 123 | RUN set -ex; \ 124 | apt-get update; \ 125 | apt-get -y --no-install-recommends install acl lsof procps wget netcat gosu tini jattach; \ 126 | rm -rf /var/lib/apt/lists/*; 127 | 128 | VOLUME /var/solr 129 | EXPOSE 8983 130 | WORKDIR /opt/solr 131 | USER $SOLR_UID 132 | 133 | ENTRYPOINT ["docker-entrypoint.sh"] 134 | CMD ["solr-foreground"] 135 | -------------------------------------------------------------------------------- /9.7/Dockerfile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | FROM eclipse-temurin:17-jre-jammy 18 | 19 | ARG SOLR_VERSION="9.7.0" 20 | # empty for the full distribution, "-slim" for the slim distribution 21 | ARG SOLR_DIST="" 22 | ARG SOLR_SHA512="a80417a79c8371d2049868573927c587b4a5b7b37e938ca6e64e8a8842449f49eddc987968ddad5d6b6b1f4395990c1edc4576a884b3a62c4fbcd97091a659d9" 23 | ARG SOLR_KEYS="EDF961FF03E647F9CA8A9C2C758051CCA3A13A7F" 24 | 25 | # Override the default solr download location with a preferred mirror, e.g.: 26 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=https://downloads.apache.org/solr/solr . 27 | # This server must support downloading at: ${SOLR_DOWNLOAD_SERVER}/${SOLR_VERSION}/solr-${SOLR_VERSION}(-slim).tgz(.asc) 28 | ARG SOLR_DOWNLOAD_SERVER="https://www.apache.org/dyn/closer.lua?action=download&filename=/solr/solr" 29 | 30 | RUN set -ex; \ 31 | apt-get update; \ 32 | apt-get -y --no-install-recommends install wget gpg gnupg dirmngr; \ 33 | rm -rf /var/lib/apt/lists/*; \ 34 | export SOLR_BINARY="solr-$SOLR_VERSION$SOLR_DIST.tgz"; \ 35 | MAX_REDIRECTS=3; \ 36 | case "${SOLR_DOWNLOAD_SERVER}" in \ 37 | (*"apache.org"*);; \ 38 | (*) \ 39 | # If a non-ASF URL is provided, allow more redirects and skip GPG step. 40 | MAX_REDIRECTS=4 && \ 41 | SKIP_GPG_CHECK=true;; \ 42 | esac; \ 43 | export DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/$SOLR_BINARY"; \ 44 | echo "downloading $DOWNLOAD_URL"; \ 45 | if ! wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$DOWNLOAD_URL" -O "/opt/$SOLR_BINARY"; then rm -f "/opt/$SOLR_BINARY"; fi; \ 46 | if [ ! -f "/opt/$SOLR_BINARY" ]; then echo "failed download attempt for $SOLR_BINARY"; exit 1; fi; \ 47 | echo "$SOLR_SHA512 */opt/$SOLR_BINARY" | sha512sum -c -; \ 48 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 49 | # Setup GPG \ 50 | export GNUPGHOME="/tmp/gnupg_home"; \ 51 | mkdir -p "$GNUPGHOME"; \ 52 | chmod 700 "$GNUPGHOME"; \ 53 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 54 | if [ -n "$SOLR_KEYS" ]; then \ 55 | # Install all Solr GPG Keys to start 56 | wget -nv "https://downloads.apache.org/solr/KEYS" -O- | \ 57 | gpg --batch --import --key-origin 'url,https://downloads.apache.org/solr/KEYS'; \ 58 | # Save just the release key 59 | release_keys="$(gpg --batch --export -a ${SOLR_KEYS})"; \ 60 | rm -rf "$GNUPGHOME"/*; \ 61 | echo "${release_keys}" | gpg --batch --import; \ 62 | fi; \ 63 | # Do GPG Checks 64 | echo "downloading $DOWNLOAD_URL.asc"; \ 65 | wget -nv "$DOWNLOAD_URL.asc" -O "/opt/$SOLR_BINARY.asc"; \ 66 | (>&2 ls -l "/opt/$SOLR_BINARY" "/opt/$SOLR_BINARY.asc"); \ 67 | gpg --batch --verify "/opt/$SOLR_BINARY.asc" "/opt/$SOLR_BINARY"; \ 68 | # Cleanup GPG 69 | { command -v gpgconf; gpgconf --kill all || :; }; \ 70 | rm -r "$GNUPGHOME"; \ 71 | else \ 72 | echo "Skipping GPG validation due to non-Apache build"; \ 73 | fi; \ 74 | tar -C /opt --extract --preserve-permissions --file "/opt/$SOLR_BINARY"; \ 75 | rm "/opt/$SOLR_BINARY"*; \ 76 | apt-get -y remove gpg dirmngr && apt-get -y autoremove; 77 | 78 | 79 | 80 | LABEL org.opencontainers.image.title="Apache Solr" 81 | LABEL org.opencontainers.image.description="Apache Solr is the popular, blazing-fast, open source search platform built on Apache Lucene." 82 | LABEL org.opencontainers.image.authors="The Apache Solr Project" 83 | LABEL org.opencontainers.image.url="https://solr.apache.org" 84 | LABEL org.opencontainers.image.source="https://github.com/apache/solr" 85 | LABEL org.opencontainers.image.documentation="https://solr.apache.org/guide/" 86 | LABEL org.opencontainers.image.version="${SOLR_VERSION}" 87 | LABEL org.opencontainers.image.licenses="Apache-2.0" 88 | 89 | ENV SOLR_USER="solr" \ 90 | SOLR_UID="8983" \ 91 | SOLR_GROUP="solr" \ 92 | SOLR_GID="8983" \ 93 | PATH="/opt/solr/bin:/opt/solr/docker/scripts:/opt/solr/prometheus-exporter/bin:$PATH" \ 94 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 95 | SOLR_HOME=/var/solr/data \ 96 | SOLR_PID_DIR=/var/solr \ 97 | SOLR_LOGS_DIR=/var/solr/logs \ 98 | LOG4J_PROPS=/var/solr/log4j2.xml \ 99 | SOLR_JETTY_HOST="0.0.0.0" \ 100 | SOLR_ZK_EMBEDDED_HOST="0.0.0.0" 101 | 102 | RUN set -ex; \ 103 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 104 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 105 | 106 | # add symlink to /opt/solr, remove what we don't want. 107 | # Remove the Dockerfile because it might not represent the dockerfile that was used to generate the image. 108 | RUN set -ex; \ 109 | (cd /opt; ln -s solr-*/ solr); \ 110 | rm -Rf /opt/solr/docs /opt/solr/docker/Dockerfile; 111 | 112 | RUN set -ex; \ 113 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d; \ 114 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 115 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 116 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 117 | chmod 0664 /etc/default/solr.in.sh; \ 118 | mkdir -p -m0770 /var/solr; \ 119 | chown -R "$SOLR_USER:0" /var/solr; \ 120 | test ! -e /opt/solr/modules || ln -s /opt/solr/modules /opt/solr/contrib; \ 121 | test ! -e /opt/solr/prometheus-exporter || ln -s /opt/solr/prometheus-exporter /opt/solr/modules/prometheus-exporter; 122 | 123 | RUN set -ex; \ 124 | apt-get update; \ 125 | apt-get -y --no-install-recommends install acl lsof procps wget netcat gosu tini jattach; \ 126 | rm -rf /var/lib/apt/lists/*; 127 | 128 | VOLUME /var/solr 129 | EXPOSE 8983 130 | WORKDIR /opt/solr 131 | USER $SOLR_UID 132 | 133 | ENTRYPOINT ["docker-entrypoint.sh"] 134 | CMD ["solr-foreground"] 135 | -------------------------------------------------------------------------------- /9.8-slim/Dockerfile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | FROM eclipse-temurin:17-jre-jammy 18 | 19 | ARG SOLR_VERSION="9.8.1" 20 | # empty for the full distribution, "-slim" for the slim distribution 21 | ARG SOLR_DIST="-slim" 22 | ARG SOLR_SHA512="e760696cad89ba5c1858eeb3d7e8a873206dadcb961580ae3c79375de819d164d71ac896e90810ead19953b6b0589d31dfe8a765c8e197114956ad1b4de7559a" 23 | ARG SOLR_KEYS="50E3EE1C91C7E0CB4DFB007B369424FC98F3F6EC" 24 | 25 | # Override the default solr download location with a preferred mirror, e.g.: 26 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=https://downloads.apache.org/solr/solr . 27 | # This server must support downloading at: ${SOLR_DOWNLOAD_SERVER}/${SOLR_VERSION}/solr-${SOLR_VERSION}(-slim).tgz(.asc) 28 | ARG SOLR_DOWNLOAD_SERVER="https://www.apache.org/dyn/closer.lua?action=download&filename=/solr/solr" 29 | 30 | RUN set -ex; \ 31 | apt-get update; \ 32 | apt-get -y --no-install-recommends install wget gpg gnupg dirmngr; \ 33 | rm -rf /var/lib/apt/lists/*; \ 34 | export SOLR_BINARY="solr-$SOLR_VERSION$SOLR_DIST.tgz"; \ 35 | MAX_REDIRECTS=3; \ 36 | case "${SOLR_DOWNLOAD_SERVER}" in \ 37 | (*"apache.org"*);; \ 38 | (*) \ 39 | # If a non-ASF URL is provided, allow more redirects and skip GPG step. 40 | MAX_REDIRECTS=4 && \ 41 | SKIP_GPG_CHECK=true;; \ 42 | esac; \ 43 | export DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/$SOLR_BINARY"; \ 44 | echo "downloading $DOWNLOAD_URL"; \ 45 | if ! wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$DOWNLOAD_URL" -O "/opt/$SOLR_BINARY"; then rm -f "/opt/$SOLR_BINARY"; fi; \ 46 | if [ ! -f "/opt/$SOLR_BINARY" ]; then echo "failed download attempt for $SOLR_BINARY"; exit 1; fi; \ 47 | echo "$SOLR_SHA512 */opt/$SOLR_BINARY" | sha512sum -c -; \ 48 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 49 | # Setup GPG \ 50 | export GNUPGHOME="/tmp/gnupg_home"; \ 51 | mkdir -p "$GNUPGHOME"; \ 52 | chmod 700 "$GNUPGHOME"; \ 53 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 54 | if [ -n "$SOLR_KEYS" ]; then \ 55 | # Install all Solr GPG Keys to start 56 | wget -nv "https://downloads.apache.org/solr/KEYS" -O- | \ 57 | gpg --batch --import --key-origin 'url,https://downloads.apache.org/solr/KEYS'; \ 58 | # Save just the release key 59 | release_keys="$(gpg --batch --export -a ${SOLR_KEYS})"; \ 60 | rm -rf "$GNUPGHOME"/*; \ 61 | echo "${release_keys}" | gpg --batch --import; \ 62 | fi; \ 63 | # Do GPG Checks 64 | echo "downloading $DOWNLOAD_URL.asc"; \ 65 | wget -nv "$DOWNLOAD_URL.asc" -O "/opt/$SOLR_BINARY.asc"; \ 66 | (>&2 ls -l "/opt/$SOLR_BINARY" "/opt/$SOLR_BINARY.asc"); \ 67 | gpg --batch --verify "/opt/$SOLR_BINARY.asc" "/opt/$SOLR_BINARY"; \ 68 | # Cleanup GPG 69 | { command -v gpgconf; gpgconf --kill all || :; }; \ 70 | rm -r "$GNUPGHOME"; \ 71 | else \ 72 | echo "Skipping GPG validation due to non-Apache build"; \ 73 | fi; \ 74 | tar -C /opt --extract --preserve-permissions --file "/opt/$SOLR_BINARY"; \ 75 | rm "/opt/$SOLR_BINARY"*; \ 76 | apt-get -y remove gpg dirmngr && apt-get -y autoremove; 77 | 78 | 79 | 80 | LABEL org.opencontainers.image.title="Apache Solr" 81 | LABEL org.opencontainers.image.description="Solr is the blazing-fast, open source, multi-modal search platform built on Apache Lucene. It powers full-text, vector, and geospatial search at many of the world's largest organizations." 82 | LABEL org.opencontainers.image.authors="The Apache Solr Project" 83 | LABEL org.opencontainers.image.url="https://solr.apache.org" 84 | LABEL org.opencontainers.image.source="https://github.com/apache/solr" 85 | LABEL org.opencontainers.image.documentation="https://solr.apache.org/guide/" 86 | LABEL org.opencontainers.image.version="${SOLR_VERSION}" 87 | LABEL org.opencontainers.image.licenses="Apache-2.0" 88 | 89 | ENV SOLR_USER="solr" \ 90 | SOLR_UID="8983" \ 91 | SOLR_GROUP="solr" \ 92 | SOLR_GID="8983" \ 93 | PATH="/opt/solr/bin:/opt/solr/docker/scripts:/opt/solr/prometheus-exporter/bin:/opt/solr/cross-dc-manager/bin:$PATH" \ 94 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 95 | SOLR_HOME=/var/solr/data \ 96 | SOLR_PID_DIR=/var/solr \ 97 | SOLR_LOGS_DIR=/var/solr/logs \ 98 | LOG4J_PROPS=/var/solr/log4j2.xml \ 99 | SOLR_JETTY_HOST="0.0.0.0" \ 100 | SOLR_ZK_EMBEDDED_HOST="0.0.0.0" 101 | 102 | RUN set -ex; \ 103 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 104 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 105 | 106 | # add symlink to /opt/solr, remove what we don't want. 107 | # Remove the Dockerfile because it might not represent the dockerfile that was used to generate the image. 108 | RUN set -ex; \ 109 | (cd /opt; ln -s solr-*/ solr); \ 110 | rm -Rf /opt/solr/docs /opt/solr/docker/Dockerfile; 111 | 112 | RUN set -ex; \ 113 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d; \ 114 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 115 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 116 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 117 | chmod 0664 /etc/default/solr.in.sh; \ 118 | mkdir -p -m0770 /var/solr; \ 119 | chown -R "$SOLR_USER:0" /var/solr; \ 120 | test ! -e /opt/solr/modules || ln -s /opt/solr/modules /opt/solr/contrib; \ 121 | test ! -e /opt/solr/prometheus-exporter || ln -s /opt/solr/prometheus-exporter /opt/solr/modules/prometheus-exporter; 122 | 123 | RUN set -ex; \ 124 | apt-get update; \ 125 | apt-get -y --no-install-recommends install acl lsof procps wget netcat gosu tini jattach; \ 126 | rm -rf /var/lib/apt/lists/*; 127 | 128 | VOLUME /var/solr 129 | EXPOSE 8983 130 | WORKDIR /opt/solr 131 | USER $SOLR_UID 132 | 133 | ENTRYPOINT ["docker-entrypoint.sh"] 134 | CMD ["solr-foreground"] 135 | -------------------------------------------------------------------------------- /9.8/Dockerfile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | FROM eclipse-temurin:17-jre-jammy 18 | 19 | ARG SOLR_VERSION="9.8.1" 20 | # empty for the full distribution, "-slim" for the slim distribution 21 | ARG SOLR_DIST="" 22 | ARG SOLR_SHA512="08888ea626b9fa617438b97f9f8d552acfbd087fc9fd248e7495627716decca5e2e8d55bedf0e1f2484c838295c2abd68debb002d1ae36965eb99753320459f4" 23 | ARG SOLR_KEYS="50E3EE1C91C7E0CB4DFB007B369424FC98F3F6EC" 24 | 25 | # Override the default solr download location with a preferred mirror, e.g.: 26 | # docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=https://downloads.apache.org/solr/solr . 27 | # This server must support downloading at: ${SOLR_DOWNLOAD_SERVER}/${SOLR_VERSION}/solr-${SOLR_VERSION}(-slim).tgz(.asc) 28 | ARG SOLR_DOWNLOAD_SERVER="https://www.apache.org/dyn/closer.lua?action=download&filename=/solr/solr" 29 | 30 | RUN set -ex; \ 31 | apt-get update; \ 32 | apt-get -y --no-install-recommends install wget gpg gnupg dirmngr; \ 33 | rm -rf /var/lib/apt/lists/*; \ 34 | export SOLR_BINARY="solr-$SOLR_VERSION$SOLR_DIST.tgz"; \ 35 | MAX_REDIRECTS=3; \ 36 | case "${SOLR_DOWNLOAD_SERVER}" in \ 37 | (*"apache.org"*);; \ 38 | (*) \ 39 | # If a non-ASF URL is provided, allow more redirects and skip GPG step. 40 | MAX_REDIRECTS=4 && \ 41 | SKIP_GPG_CHECK=true;; \ 42 | esac; \ 43 | export DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/$SOLR_BINARY"; \ 44 | echo "downloading $DOWNLOAD_URL"; \ 45 | if ! wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$DOWNLOAD_URL" -O "/opt/$SOLR_BINARY"; then rm -f "/opt/$SOLR_BINARY"; fi; \ 46 | if [ ! -f "/opt/$SOLR_BINARY" ]; then echo "failed download attempt for $SOLR_BINARY"; exit 1; fi; \ 47 | echo "$SOLR_SHA512 */opt/$SOLR_BINARY" | sha512sum -c -; \ 48 | if [ -z "$SKIP_GPG_CHECK" ]; then \ 49 | # Setup GPG \ 50 | export GNUPGHOME="/tmp/gnupg_home"; \ 51 | mkdir -p "$GNUPGHOME"; \ 52 | chmod 700 "$GNUPGHOME"; \ 53 | echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \ 54 | if [ -n "$SOLR_KEYS" ]; then \ 55 | # Install all Solr GPG Keys to start 56 | wget -nv "https://downloads.apache.org/solr/KEYS" -O- | \ 57 | gpg --batch --import --key-origin 'url,https://downloads.apache.org/solr/KEYS'; \ 58 | # Save just the release key 59 | release_keys="$(gpg --batch --export -a ${SOLR_KEYS})"; \ 60 | rm -rf "$GNUPGHOME"/*; \ 61 | echo "${release_keys}" | gpg --batch --import; \ 62 | fi; \ 63 | # Do GPG Checks 64 | echo "downloading $DOWNLOAD_URL.asc"; \ 65 | wget -nv "$DOWNLOAD_URL.asc" -O "/opt/$SOLR_BINARY.asc"; \ 66 | (>&2 ls -l "/opt/$SOLR_BINARY" "/opt/$SOLR_BINARY.asc"); \ 67 | gpg --batch --verify "/opt/$SOLR_BINARY.asc" "/opt/$SOLR_BINARY"; \ 68 | # Cleanup GPG 69 | { command -v gpgconf; gpgconf --kill all || :; }; \ 70 | rm -r "$GNUPGHOME"; \ 71 | else \ 72 | echo "Skipping GPG validation due to non-Apache build"; \ 73 | fi; \ 74 | tar -C /opt --extract --preserve-permissions --file "/opt/$SOLR_BINARY"; \ 75 | rm "/opt/$SOLR_BINARY"*; \ 76 | apt-get -y remove gpg dirmngr && apt-get -y autoremove; 77 | 78 | 79 | 80 | LABEL org.opencontainers.image.title="Apache Solr" 81 | LABEL org.opencontainers.image.description="Solr is the blazing-fast, open source, multi-modal search platform built on Apache Lucene. It powers full-text, vector, and geospatial search at many of the world's largest organizations." 82 | LABEL org.opencontainers.image.authors="The Apache Solr Project" 83 | LABEL org.opencontainers.image.url="https://solr.apache.org" 84 | LABEL org.opencontainers.image.source="https://github.com/apache/solr" 85 | LABEL org.opencontainers.image.documentation="https://solr.apache.org/guide/" 86 | LABEL org.opencontainers.image.version="${SOLR_VERSION}" 87 | LABEL org.opencontainers.image.licenses="Apache-2.0" 88 | 89 | ENV SOLR_USER="solr" \ 90 | SOLR_UID="8983" \ 91 | SOLR_GROUP="solr" \ 92 | SOLR_GID="8983" \ 93 | PATH="/opt/solr/bin:/opt/solr/docker/scripts:/opt/solr/prometheus-exporter/bin:/opt/solr/cross-dc-manager/bin:$PATH" \ 94 | SOLR_INCLUDE=/etc/default/solr.in.sh \ 95 | SOLR_HOME=/var/solr/data \ 96 | SOLR_PID_DIR=/var/solr \ 97 | SOLR_LOGS_DIR=/var/solr/logs \ 98 | LOG4J_PROPS=/var/solr/log4j2.xml \ 99 | SOLR_JETTY_HOST="0.0.0.0" \ 100 | SOLR_ZK_EMBEDDED_HOST="0.0.0.0" 101 | 102 | RUN set -ex; \ 103 | groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \ 104 | useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER" 105 | 106 | # add symlink to /opt/solr, remove what we don't want. 107 | # Remove the Dockerfile because it might not represent the dockerfile that was used to generate the image. 108 | RUN set -ex; \ 109 | (cd /opt; ln -s solr-*/ solr); \ 110 | rm -Rf /opt/solr/docs /opt/solr/docker/Dockerfile; 111 | 112 | RUN set -ex; \ 113 | mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d; \ 114 | cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \ 115 | mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \ 116 | mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \ 117 | chmod 0664 /etc/default/solr.in.sh; \ 118 | mkdir -p -m0770 /var/solr; \ 119 | chown -R "$SOLR_USER:0" /var/solr; \ 120 | test ! -e /opt/solr/modules || ln -s /opt/solr/modules /opt/solr/contrib; \ 121 | test ! -e /opt/solr/prometheus-exporter || ln -s /opt/solr/prometheus-exporter /opt/solr/modules/prometheus-exporter; 122 | 123 | RUN set -ex; \ 124 | apt-get update; \ 125 | apt-get -y --no-install-recommends install acl lsof procps wget netcat gosu tini jattach; \ 126 | rm -rf /var/lib/apt/lists/*; 127 | 128 | VOLUME /var/solr 129 | EXPOSE 8983 130 | WORKDIR /opt/solr 131 | USER $SOLR_UID 132 | 133 | ENTRYPOINT ["docker-entrypoint.sh"] 134 | CMD ["solr-foreground"] 135 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | Apache Solr Docker Image 3 | Copyright 2006-2022 The Apache Software Foundation 4 | ============================================================== 5 | 6 | This product includes software developed at 7 | The Apache Software Foundation (http://www.apache.org/). 8 | 9 | Includes software from other Apache Software Foundation projects. 10 | 11 | -------------------------------------------------------------------------------- /README-short.txt: -------------------------------------------------------------------------------- 1 | Solr is the blazing-fast, open source, multi-modal search platform built on Apache Lucene. It powers full-text, vector, analytics, and geospatial search at many of the world's largest organizations. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is Apache Solr™? 2 | 3 | Solr is the blazing-fast, open source, multi-modal search platform built on Apache Lucene. 4 | It powers full-text, vector, analytics, and geospatial search at many of the world's largest organizations. 5 | Other major features include Kubernetes integration, streaming, highlighting, faceting, and spellchecking. 6 | 7 | Learn more on [Solr's homepage](https://solr.apache.org) and in the [Solr Reference Guide](https://solr.apache.org/guide/solr/). 8 | 9 | # Supported tags and respective `Dockerfile` links 10 | 11 | See [Docker Hub](https://hub.docker.com/_/solr?tab=tags) for a list of image tags available to pull. 12 | Note that the Apache Solr project does not support any releases older than the current major release series, despite whatever tags are published. 13 | 14 | The official Dockerfile is released along-side Solr. 15 | Therefore the project has decided to not support changes to Dockerfiles after release. 16 | Changes must be made to [github.com/apache/solr](https://github.com/apache/solr), which will then be included in the next targeted release. 17 | 18 | # About this repository 19 | 20 | This repository is available on [github.com/apache/solr-docker](https://github.com/apache/solr-docker), and the official build is on the [Docker Hub](https://hub.docker.com/_/solr/). 21 | 22 | The Dockerfiles are generated upon release from [github.com/apache/solr](https://github.com/apache/solr). 23 | 24 | Please refer to the [developer documentation](dev-docs/README.md) for information on how this repository is maintained & automated. 25 | **WARNING: Do not modify this repo manually unless you have read through the developer documentation first.** 26 | 27 | # License 28 | 29 | Solr is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). 30 | 31 | This repository is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). 32 | 33 | Copyright 2015-2022 The Apache Software Foundation 34 | 35 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 36 | 37 | http://www.apache.org/licenses/LICENSE-2.0 38 | 39 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 40 | 41 | # User Feedback 42 | 43 | ## Issues 44 | 45 | Please report issues with this docker image on via [Apache Solr JIRA](https://issues.apache.org/jira/projects/SOLR). But please first reach out via the users@solr mailing list linked in the community information below. 46 | 47 | For general questions about Solr, see the [Community information](http://solr.apache.org/community.html), in particular the users@solr mailing list. 48 | 49 | ## Contributing 50 | 51 | If you want to contribute to Solr, see the [How To Contribute](http://solr.apache.org/community.html#how-to-contribute). 52 | 53 | # History 54 | 55 | This project was started in 2015 by [Martijn Koster](https://github.com/makuk66). In 2019 maintainership and copyright was transferred to the Apache Solr project. Many thanks to Martijn for all your contributions over the years! 56 | 57 | -------------------------------------------------------------------------------- /dev-docs/README.md: -------------------------------------------------------------------------------- 1 | # Official Solr Dockerfile Management 2 | 3 | In general most interactions with this repository should be done via the Solr Release Wizard, not manually. 4 | 5 | ## How an Official Solr Dockerfile is released 6 | 7 | 1. In the Solr Release Wizard, an **official** Dockerfile will be created as a part of the release candidate. 8 | The official Dockerfile is tested as a part of the release candidate. 9 | 1. But importantly, the official Dockerfile is not voted on because small changes _may_ be requested by the Official Images team. 10 | We need to be able to make changes for these requests **after** a vote succeeds. 11 | 2. If the vote succeeds: 12 | 1. As a part of the artifact-uploading steps, the Release Wizard will clone this repo (`apache/solr-docker`) locally. 13 | 2. It will then add the successfully voted on `Dockerfile` to the respective folder for the released version (`.`). 14 | 3. If it is a patch release, the existing `Dockerfile` for that version will be over-written. 15 | 4. It will commit this `Dockerfile`, and push to the `main` branch of this repo. No PR or reviews required. 16 | 3. Now that this repo has the new `Dockerfile` committed to main, the [Github Actions Workflow](../.github/workflows/pr-for-official-repo.yml) will kick-off. 17 | 1. It will use [`generate-stackbrew-library.sh`](../generate-stackbrew-library.sh) to build the [Solr metadata](https://github.com/docker-library/official-images/blob/master/library/solr) for the latest `main` branch commit. 18 | 2. After generating a new version of this file, it will create a PR in [docker-library/official-images](https://github.com/docker-library/official-images) to update the official image. 19 | 3. This PR will have to be reviewed and merged by the Docker Official Images team before the release will be available. 20 | 1. If a change to the Dockerfile/metadata is required by the maintainers, make further PRs/commits to this repo. 21 | Refer to the [section on making fixes for an open PR](#make-fixes-for-an-open-automated-pr) for more information. 22 | 4. Before the PR can be approved, one of the listed Solr maintainers must comment their approval of the PR. 23 | 4. The Official Docker image should now be available 24 | 25 | ## How does the automated PR work? 26 | 27 | The [Github Actions Workflow](../.github/workflows/pr-for-official-repo.yml) is triggered on commits to the `main` branch that touch the following files: 28 | - `generate-stackbrew-library.sh` 29 | - `*.*/Dockerfile` 30 | 31 | The PR in [docker-library/official-images](https://github.com/docker-library/official-images) is generated through: 32 | - Creating a branch in the [docker-solr/official-images](https://github.com/docker-solr/official-images). 33 | - We have to use this repo, because Apache does not allow forks in their organization. 34 | - This commit is made by the [@docker-solr-builder](https://github.com/docker-solr-builder), which has credentials saved in this repo. 35 | - These credentials were added by emailing them to the Apache infra-team (`root@`) 36 | - If you need access to this account or credentials, reach out to the private mailing list. 37 | - Once the commit and branch are created, the Github Action will create a PR in the official repo. 38 | 39 | ### Make fixes for an open automated PR 40 | 41 | If the PR in [docker-library/official-images](https://github.com/docker-library/official-images) is already created & open, 42 | any commit you make to this repo will auto-update the existing PR. 43 | The commit has to change the files that the Github Actions Workflow is listening on, which are [listed above](#how-does-the-automated-pr-work). 44 | 45 | The PR name will change to reflect the most recent commit message, and the pr description will link to this commit instead. 46 | The PR contents will be updated to reflect the generated solr image metadata made from the latest commit. 47 | There is no need to close an existing PR to make further changes. 48 | 49 | **Make sure that all changes to Dockerfiles are reflected in the official source of these dockerfiles, [apache/solr](https://github.com/apache/solr). 50 | This will ensure that the official-images team does not ask for the same changes in future releases. 51 | This speeds up the release process and ensures that the Dockerfile provided in the binary-release is as similar as possible to the official Solr Dockerfile.** 52 | -------------------------------------------------------------------------------- /generate-stackbrew-library.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Produce https://github.com/docker-library/official-images/blob/master/library/solr 4 | # Based on https://github.com/docker-library/httpd/blob/master/generate-stackbrew-library.sh 5 | set -eu 6 | 7 | declare -A aliases 8 | declare -g -A parentRepoToArches 9 | 10 | self="$(basename "${BASH_SOURCE[0]}")" 11 | if [[ "$OSTYPE" == "darwin"* ]]; then 12 | source "$(dirname "${BASH_SOURCE[0]}")/tools/init_macos.sh" 13 | fi 14 | cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" 15 | 16 | 17 | declare -a versions 18 | readarray -t versions < <(find . -maxdepth 1 -regex '\./[0-9]*\.[0-9]*' -printf '%f\n' | sort -rV) 19 | latest_version="${versions[0]}" 20 | 21 | # make a map from major version to most recent minor, eg 9.6 -> 9 22 | readarray -t versions_increasing < <(printf '%s\n' "${versions[@]}" | tac ) 23 | declare -A major_to_minor 24 | for v in "${versions_increasing[@]}"; do 25 | major="$(sed -E 's/\..*//' <<<"$v")" 26 | major_to_minor[$major]=$v 27 | done 28 | # invert that to create aliases eg 9.6 -> 9 29 | for major in "${!major_to_minor[@]}"; do 30 | aliases[${major_to_minor[$major]}]="$major" 31 | done 32 | 33 | # get the most recent commit which modified any of "$@" 34 | fileCommit() { 35 | git log -1 --format='format:%H' HEAD -- "$@" 36 | } 37 | 38 | # get the most recent commit which modified "$1/Dockerfile" 39 | dirCommit() { 40 | local dir="$1"; shift 41 | ( 42 | cd "$dir" 43 | fileCommit \ 44 | "Dockerfile" 45 | ) 46 | } 47 | 48 | getArches() { 49 | local repo="$1"; shift 50 | local officialImagesUrl='https://github.com/docker-library/official-images/raw/master/library/' 51 | 52 | eval "declare -g -A parentRepoToArches=( $( 53 | find . -name 'Dockerfile' -not -path "./official-images/*" -exec awk ' 54 | toupper($1) == "FROM" && $2 !~ /^('"$repo"'|scratch|microsoft\/[^:]+)(:|$)/ { 55 | print "'"$officialImagesUrl"'" $2 56 | } 57 | ' '{}' + \ 58 | | sort -u \ 59 | | xargs bashbrew cat --format '[{{ .RepoName }}:{{ .TagName }}]="{{ join " " .TagEntry.Architectures }}"' 60 | ) )" 61 | } 62 | getArches 'solr' 63 | 64 | cat <<-EOH 65 | # this file is generated via https://github.com/apache/solr-docker/blob/$(fileCommit "$self")/$self 66 | 67 | Maintainers: The Apache Solr Project (@asfbot), 68 | Shalin Mangar (@shalinmangar), 69 | David Smiley (@dsmiley), 70 | Jan Høydahl (@janhoy), 71 | Houston Putman (@houstonputman) 72 | GitRepo: https://github.com/apache/solr-docker.git 73 | GitFetch: refs/heads/main 74 | EOH 75 | 76 | for version in "${versions[@]}"; do 77 | # We can remove the variant loop when 8.11 is no longer supported 78 | for variant in '' slim; do 79 | dir="$version${variant:+-$variant}" 80 | [ -f "$dir/Dockerfile" ] || continue 81 | 82 | commit="$(dirCommit "$dir")" 83 | 84 | # grep the full version from the Dockerfile, eg: SOLR_VERSION="6.6.1" 85 | fullVersion="$(git show "$commit:$dir/Dockerfile" | \ 86 | grep -E 'SOLR_VERSION="[^"]+"' | \ 87 | sed -E -e 's/.*SOLR_VERSION="([^"]+)".*$/\1/')" 88 | if [[ -z $fullVersion ]]; then 89 | echo "Cannot determine full version from $dir/Dockerfile" 90 | exit 1 91 | fi 92 | versionAliases=( 93 | "$fullVersion" 94 | "$version" 95 | ) 96 | 97 | if [[ -n "${aliases[$version]:-}" ]]; then 98 | versionAliases=( "${versionAliases[@]}" "${aliases[$version]:-}" ) 99 | fi 100 | if [ -z "$variant" ]; then 101 | variantAliases=( "${versionAliases[@]}" ) 102 | if [[ $version == "$latest_version" ]]; then 103 | variantAliases=( "${variantAliases[@]}" "latest" ) 104 | fi 105 | else 106 | variantAliases=( "${versionAliases[@]/%/-$variant}" ) 107 | if [[ $version == "$latest_version" ]]; then 108 | variantAliases=( "${variantAliases[@]}" "$variant" ) 109 | fi 110 | fi 111 | 112 | variantParent="$(awk 'toupper($1) == "FROM" { print $2 }' "$dir/Dockerfile")" 113 | variantArches=(${parentRepoToArches[$variantParent]}) 114 | # Do not produce 32bit images 115 | variantArches=("${variantArches[@]/*32*}") 116 | 117 | echo 118 | cat <<-EOE 119 | Tags: $(sed -E 's/ +/, /g' <<<"${variantAliases[@]}") 120 | Architectures: $(sed -E 's/ +/, /g' <<<"${variantArches[@]}") 121 | GitCommit: $commit 122 | Directory: $dir 123 | EOE 124 | done 125 | done 126 | -------------------------------------------------------------------------------- /tools/init_macos.sh: -------------------------------------------------------------------------------- 1 | # Source this file to prepare a mac for running scripts 2 | hash greadlink 2>/dev/null || { 3 | echo >&2 "Required tool greadlink is not installed, please run 'brew install coreutils'" 4 | exit 1 5 | } 6 | hash gfind 2>/dev/null || { 7 | echo >&2 "Required tool gfind is not installed, please run 'brew install findutils'" 8 | exit 1 9 | } 10 | hash gsed 2>/dev/null || { 11 | echo >&2 "Required tool gsed is not installed, please run 'brew install gnu-sed'" 12 | exit 1 13 | } 14 | 15 | TOOL_PREFIX="$(brew --prefix)/bin" 16 | 17 | if [[ ! -d /tmp/docker-solr-bin ]]; then 18 | mkdir -p /tmp/docker-solr-bin >/dev/null 2>&1 19 | ln -s $TOOL_PREFIX/greadlink /tmp/docker-solr-bin/readlink 20 | ln -s $TOOL_PREFIX/gfind /tmp/docker-solr-bin/find 21 | ln -s $TOOL_PREFIX/gsed /tmp/docker-solr-bin/sed 22 | fi 23 | 24 | if [[ ! $PATH == *"docker-solr-bin"* ]]; then 25 | export PATH=/tmp/docker-solr-bin:$PATH 26 | echo >&2 "Configuring for macOS - adding /tmp/docker-solr-bin first in path" 27 | fi 28 | --------------------------------------------------------------------------------