├── .gitignore
├── image
├── resources
│ ├── root
│ │ ├── set-timezone.sh
│ │ ├── preinit
│ │ │ ├── xml-transformations
│ │ │ │ ├── opencms-system_activate_jsonapi.params
│ │ │ │ └── opencms-system_activate_jsonapi.xslt
│ │ │ ├── 90_message.sh
│ │ │ ├── 07_jetty_setup.sh
│ │ │ ├── 50_opencms_optimize_webxml_jetty.sh
│ │ │ ├── 30_transform_opencms_configuration.sh
│ │ │ ├── 10-create-setup-properties.sh
│ │ │ ├── 50_opencms_optimize_webxml_tomcat.sh
│ │ │ ├── 07_tomcat_setup.sh
│ │ │ └── 20_check_install.sh
│ │ ├── postinit
│ │ │ ├── 10_create_timestamp.sh
│ │ │ └── 99_message.sh
│ │ ├── execute-opencms-shell.sh
│ │ ├── opencms-fetch.sh
│ │ ├── opencms-run.sh
│ │ ├── process-script-dir.sh
│ │ ├── jetty-webxml.xsl
│ │ ├── wait-for.sh
│ │ ├── opencms-restart.sh
│ │ └── common.sh
│ └── config
│ │ ├── update-core-modules.ocsh
│ │ └── server.xml
└── Dockerfile
├── .project
├── scripts
├── docker-rm-all.sh
├── docker-enter.sh
└── opencms-mount.sh
├── compose
├── postgres
│ ├── custom-setup.properties
│ └── docker-compose.yml
└── build-tomcat
│ └── docker-compose.yml
├── docker-compose.yml
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | # It never hurts to have a .gitignore file in the project :)
--------------------------------------------------------------------------------
/image/resources/root/set-timezone.sh:
--------------------------------------------------------------------------------
1 | ln -snf /usr/share/zoneinfo/$1 /etc/localtime && echo $1 > /etc/timezone
--------------------------------------------------------------------------------
/image/resources/root/preinit/xml-transformations/opencms-system_activate_jsonapi.params:
--------------------------------------------------------------------------------
1 | --stringparam jsonapi ${JSONAPI:-false}
--------------------------------------------------------------------------------
/image/resources/root/postinit/10_create_timestamp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Creating timestamp for the system start ..."
4 |
5 | date > ${OPENCMS_HOME}/WEB-INF/opencms-starttime
--------------------------------------------------------------------------------
/image/resources/root/postinit/99_message.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | WORKDIR=$(dirname $(readlink -f $0))
4 |
5 | echo "."
6 | echo "Post-init script folder ${WORKDIR} has been processed"
7 | echo "."
8 |
--------------------------------------------------------------------------------
/image/resources/root/preinit/90_message.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | WORKDIR=$(dirname $(readlink -f $0))
4 |
5 | echo "."
6 | echo "Pre-init script folder ${WORKDIR} has been processed"
7 | echo "."
8 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | opencms-docker
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/image/resources/config/update-core-modules.ocsh:
--------------------------------------------------------------------------------
1 | login Admin admin
2 | setSiteRoot "/"
3 |
4 | # Import the CORE modules
5 | replaceModule "/artifacts/org.opencms.base.zip"
6 | replaceModule "/artifacts/org.opencms.configuration.zip"
7 |
8 | exit
9 |
10 |
11 |
--------------------------------------------------------------------------------
/image/resources/root/execute-opencms-shell.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "=== START OPENCMS SHELL ==="
4 | echo "Installing modules from ${1}"
5 |
6 | # Install Modules using the OpenCms Shell
7 | java -classpath "$(shell_classpath)" \
8 | org.opencms.main.CmsShell -script=${1} -base=${OPENCMS_HOME}/WEB-INF
9 |
10 | echo "=== END OPENCMS SHELL ==="
--------------------------------------------------------------------------------
/image/resources/root/preinit/07_jetty_setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "$SERVLET_CONTAINER" != "jetty" ]; then
4 | echo "Skipping $0 because we are not using Jetty"
5 | exit
6 | fi
7 |
8 | cd $CONTAINER_BASE
9 | java -jar $JETTY_HOME/start.jar --add-modules=ee8-deploy,ee8-jsp,ee8-jstl,server,http,gzip
10 | echo "$JETTY_OPTS" > jetty-opts.txt
--------------------------------------------------------------------------------
/image/resources/root/preinit/50_opencms_optimize_webxml_jetty.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "${SERVLET_CONTAINER}" != "jetty" ] ; then
4 | echo "Skipping $0 because we are not using Jetty."
5 | exit
6 | fi
7 |
8 | WEB_XML=${OPENCMS_HOME}/WEB-INF/web.xml
9 | xsltproc --stringparam cookie_name "JSESSIONID_$HOSTNAME" -o "$WEB_XML" /root/jetty-webxml.xsl "$WEB_XML"
10 |
11 | echo ""
12 | echo "Modified web.xml configuration looks like this:"
13 | echo "================================================================================================="
14 | cat "$WEB_XML"
15 | echo ""
16 |
--------------------------------------------------------------------------------
/scripts/docker-rm-all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "=== START DOCKER CLEANUP SCRIPT ==="
4 |
5 | echo "Removing all stale containers:"
6 | STALE_CONTAINERS=$(docker ps -a | grep "Exited " | awk '{ print $1; }')
7 | COUNT=$(echo "$STALE_CONTAINERS" | wc -m)
8 |
9 | if [ $COUNT -gt 1 ]; then
10 | docker rm $STALE_CONTAINERS
11 | else
12 | echo "- No stale containers found."
13 | fi
14 |
15 | echo "Removing all stale images that have as name:"
16 |
17 | STALE_IMAGES=$(docker images | grep "^" | awk '{ print $3; }')
18 | COUNT=$(echo "$STALE_IMAGES" | wc -m)
19 |
20 | if [ $COUNT -gt 1 ]; then
21 | docker rmi $STALE_IMAGES
22 | else
23 | echo "- No stale images found."
24 | fi
25 |
26 | echo "=== END DOCKER CLEANUP SCRIPT ==="
--------------------------------------------------------------------------------
/compose/postgres/custom-setup.properties:
--------------------------------------------------------------------------------
1 | setup.webapp.path=/container/webapps/ROOT
2 | setup.default.webapp=
3 | setup.install.components=workplace,demo
4 | setup.show.progress=true
5 |
6 | db.product=postgresql
7 | db.provider=postgresql
8 | db.create.user=root
9 | db.create.pwd=root
10 | db.worker.user=opencms
11 | db.worker.pwd=opencms
12 | db.connection.url=jdbc:postgresql://postgres:5432/
13 | db.name=opencms
14 | db.create.db=true
15 | db.create.tables=true
16 | db.dropDb=true
17 | db.default.tablespace=
18 | db.index.tablespace=
19 | db.jdbc.driver=org.postgresql.Driver
20 | db.template.db=template1
21 | db.temporary.tablespace=
22 |
23 | server.url=http://localhost
24 | server.name=OpenCmsServer
25 | server.ethernet.address=
26 | server.servlet.mapping=
27 |
--------------------------------------------------------------------------------
/image/resources/root/opencms-fetch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 |
5 | # Check if a file opencms.war is not available, if so download from the web
6 | if [ ! -s ${ARTIFACTS_FOLDER}opencms.war ]
7 | then
8 |
9 | if [ ! -s ${ARTIFACTS_FOLDER}opencms.zip ]
10 | then
11 | if [ ! -d ${ARTIFACTS_FOLDER} ]; then
12 | mkdir -v -p ${ARTIFACTS_FOLDER}
13 | fi
14 | echo "Downloading OpenCms from '$OPENCMS_URL'"
15 | wget -nv $OPENCMS_URL -O ${ARTIFACTS_FOLDER}opencms.zip
16 | echo "Download complete, unpacking war"
17 | fi
18 |
19 | if [ -s ${ARTIFACTS_FOLDER}opencms.zip ]
20 | then
21 | unzip -q ${ARTIFACTS_FOLDER}opencms.zip opencms.war -d $ARTIFACTS_FOLDER
22 | echo "Unziped WAR file"
23 | rm -fv ${ARTIFACTS_FOLDER}opencms.zip
24 | ls -la ${ARTIFACTS_FOLDER}
25 | else
26 | exit 1
27 | fi
28 | else
29 | echo "Using local WAR file"
30 | fi
31 |
32 |
--------------------------------------------------------------------------------
/compose/postgres/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | postgres:
3 | image: postgres:latest
4 | container_name: postgres
5 | init: true
6 | # restart: always
7 | volumes:
8 | - ~/dockermount/opencms-docker-postgres:/var/lib/postgresql/data
9 | environment:
10 | - POSTGRES_PASSWORD=root
11 | - POSTGRES_USER=root
12 | opencms:
13 | image: alkacon/opencms-docker:latest
14 | container_name: opencms
15 | init: true
16 | # restart: always
17 | depends_on: [ "postgres" ]
18 | ports:
19 | - "80:8080"
20 | volumes:
21 | - ~/dockermount/opencms-docker-webapps:/container/webapps
22 | - ./custom-setup.properties:/custom-setup.properties
23 | command: ["/root/wait-for.sh", "postgres:5432", "-t", "30", "--", "/root/opencms-run.sh"]
24 |
--------------------------------------------------------------------------------
/image/resources/root/opencms-run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # OpenCms startup script executed when Docker loads the image
4 |
5 | # Set the timezone
6 | echo "Adjusting the timezone"
7 | bash /root/set-timezone.sh ${TIME_ZONE}
8 |
9 | ls /root/preinit/
10 |
11 | chmod -v +x /root/preinit/*.sh
12 |
13 | ls /root/postinit/
14 |
15 | chmod -v +x /root/postinit/*.sh
16 |
17 | # Execute pre-init configuration scripts
18 | bash /root/process-script-dir.sh /root/preinit runonce
19 |
20 | start_container
21 |
22 | # Write startup time to file
23 | date > ${OPENCMS_HOME}/WEB-INF/opencms-starttime
24 |
25 | function kill_container_and_exit() {
26 | kill_container
27 | exit
28 | }
29 | trap "kill_container_and_exit" SIGTERM
30 |
31 | # Execute post-init configuration scripts
32 | bash /root/process-script-dir.sh /root/postinit runonce
33 |
34 | # We need a running process for docker
35 | # We use only sleep 1 to get kill_container() executed when SIGTERM is receive
36 | while true ; do
37 | sleep 1
38 | done
39 |
--------------------------------------------------------------------------------
/compose/build-tomcat/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mariadb:
3 | image: mariadb:latest
4 | container_name: mariadb
5 | init: true
6 | restart: always
7 | volumes:
8 | - ~/dockermount/opencms-docker-mysql:/var/lib/mysql
9 | environment:
10 | - "MYSQL_ROOT_PASSWORD=secretDBpassword"
11 | opencms:
12 | image: alkacon/opencms-docker:17.0-tomcat
13 | container_name: opencms
14 | build:
15 | context: ../../image
16 | args:
17 | SERVLET_CONTAINER: tomcat
18 | BASE_IMAGE: tomcat:9.0-jdk21
19 | init: true
20 | restart: always
21 | depends_on: [ "mariadb" ]
22 | links:
23 | - "mariadb:mysql"
24 | ports:
25 | - "80:8080"
26 | volumes:
27 | - ~/dockermount/opencms-docker-webapps:/container/webapps
28 | command: ["/root/wait-for.sh", "mysql:3306", "-t", "30", "--", "/root/opencms-run.sh"]
29 | environment:
30 | - "DB_PASSWD=secretDBpassword"
31 |
--------------------------------------------------------------------------------
/image/resources/root/process-script-dir.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ -z "$1" ]; then
4 | echo "."
5 | echo "Usage: $0 {SCRIPT_DIR}"
6 | echo "."
7 | exit 1
8 | fi
9 |
10 | SCRIPT_DIR=$1
11 |
12 | echo "."
13 | echo "Executing scripts located in ${SCRIPT_DIR}."
14 |
15 | if [ -d "${SCRIPT_DIR}" ]; then
16 | for SCRIPT in ${SCRIPT_DIR}/*.sh; do
17 | echo "."
18 | echo "Executing OpenCms configuration script: ${SCRIPT}"
19 | echo "---------------------------------------------------"
20 | bash "${SCRIPT}"
21 | if [[ ${SCRIPT} = *.runonce.sh ]]; then
22 | echo "."
23 | echo "Disabling configuration script: ${SCRIPT}"
24 | mv -v "${SCRIPT}" "${SCRIPT}.executed"
25 | fi
26 | echo "---------------------------------------------------"
27 | done
28 | if [ "$2" = "runonce" ]; then
29 | echo "."
30 | echo "Disabling configuration script folder: ${SCRIPT_DIR}"
31 | mv -v "${SCRIPT_DIR}" "${SCRIPT_DIR}.executed"
32 | fi
33 | else
34 | echo "Directory ${SCRIPT_DIR} not available, ignoring!"
35 | fi
36 |
37 | echo "."
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Default build/run file for the OpenCms docker image.
2 | # The image uses Jetty and Java 21.
3 | # It connects to a MariaDB database, running as second container.
4 | # To persist data, volumes are defined. Adjust the mount points to your needs,
5 | # or remove the volumes if data should not be persisted.
6 | services:
7 | mariadb:
8 | image: mariadb:latest
9 | container_name: mariadb
10 | init: true
11 | restart: always
12 | volumes:
13 | - ~/dockermount/opencms-docker-mysql:/var/lib/mysql
14 | environment:
15 | - "MYSQL_ROOT_PASSWORD=secretDBpassword"
16 | opencms:
17 | image: alkacon/opencms-docker:20.1
18 | container_name: opencms
19 | build:
20 | context: ./image
21 | args:
22 | SERVLET_CONTAINER: jetty
23 | BASE_IMAGE: jetty:12-jdk21
24 | init: true
25 | restart: always
26 | depends_on: [ "mariadb" ]
27 | links:
28 | - "mariadb:mysql"
29 | ports:
30 | - "80:8080"
31 | volumes:
32 | - ~/dockermount/opencms-docker-webapps:/container/webapps
33 | command: ["/root/wait-for.sh", "mysql:3306", "-t", "30", "--", "/root/opencms-run.sh"]
34 | environment:
35 | - "DB_PASSWD=secretDBpassword"
36 |
--------------------------------------------------------------------------------
/image/resources/config/server.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/image/resources/root/preinit/xml-transformations/opencms-system_activate_jsonapi.xslt:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/image/resources/root/jetty-webxml.xsl:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
28 | ExpiresFilter
29 | org.opencms.main.CmsExportExpiresFilter
30 |
31 |
32 |
33 | ExpiresFilter
34 | /export/*
35 | REQUEST
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/scripts/docker-enter.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ -e $(dirname "$0")/nsenter ]; then
4 | # with boot2docker, nsenter is not in the PATH but it is in the same folder
5 | NSENTER=$(dirname "$0")/nsenter
6 | else
7 | NSENTER=nsenter
8 | fi
9 |
10 | if [ -z "$1" ]; then
11 | echo ""
12 | echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]"
13 | echo ""
14 | echo "Enters the Docker CONTAINER and executes the specified COMMAND."
15 | echo "If COMMAND is not specified, runs an interactive shell in CONTAINER."
16 | echo ""
17 | else
18 | PID=$(docker inspect --format "{{.State.Pid}}" "$1")
19 | [ -z "$PID" ] && exit 1
20 | shift
21 |
22 | if [ "$(id -u)" -ne "0" ]; then
23 | which sudo > /dev/null
24 | if [ "$?" -eq "0" ]; then
25 | LAZY_SUDO="sudo "
26 | else
27 | echo "Warning: Cannot find sudo; Invoking nsenter as the user $USER." >&2
28 | fi
29 | fi
30 |
31 | # Get environment variables from the container's root process
32 |
33 | ENV=$($LAZY_SUDO cat /proc/$PID/environ | xargs -0)
34 |
35 | # Prepare nsenter flags
36 | OPTS="--target $PID --mount --uts --ipc --net --pid --"
37 |
38 | # env is to clear all host environment variables and set then anew
39 | if [ $# -lt 1 ]; then
40 | # No arguments, default to `su` which executes the default login shell
41 | $LAZY_SUDO "$NSENTER" $OPTS env -i - $ENV su -m root
42 | else
43 | # Has command
44 | # "$@" is magic in bash, and needs to be in the invocation
45 | $LAZY_SUDO "$NSENTER" $OPTS env -i - $ENV "$@"
46 | fi
47 | fi
--------------------------------------------------------------------------------
/image/resources/root/preinit/30_transform_opencms_configuration.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CONFIG_FOLDER="${OPENCMS_HOME}/WEB-INF/config/"
4 | XSLT_DIR="/root/preinit/xml-transformations"
5 | echo "Executing XSL transformation of OpenCms config files."
6 | if [ -d "${XSLT_DIR}" ]; then
7 | for XSLT in "${XSLT_DIR}"/*.xslt; do
8 | echo "."
9 | echo "Executing XSL transformation: ${XSLT}"
10 | echo "---------------------------------------------------"
11 | XSLT_NAME=${XSLT##*/}
12 | CONFIG_NAME=$(echo "${XSLT_NAME}"| cut -d'_' -f 1)
13 | if [[ $CONFIG_NAME == "solr-schema" ]]; then
14 | # transformation of the SOLR schema
15 | XML_CONFIG_FILE="${OPENCMS_HOME}/WEB-INF/solr/configsets/default/conf/schema.xml"
16 | else
17 | XML_CONFIG_FILE="${CONFIG_FOLDER}${CONFIG_NAME}.xml"
18 | fi
19 | PARAM_FILE="${XSLT/%.xslt/.params}"
20 | if [ -f "${XML_CONFIG_FILE}" ]; then
21 | if [ -f "${PARAM_FILE}" ]; then
22 | extraparams=$(cat "${PARAM_FILE}")
23 | extraparams=$(eval echo $extraparams)
24 | cat "${XSLT}" | xsltproc --novalid --nonet $extraparams --output "${XML_CONFIG_FILE}" - "${XML_CONFIG_FILE}"
25 | else
26 | cat "${XSLT}" | xsltproc --novalid --nonet --output "${XML_CONFIG_FILE}" - "${XML_CONFIG_FILE}"
27 | fi
28 | else
29 | echo "XML config file ${XML_CONFIG_FILE} does not exist"
30 | fi
31 | echo "---------------------------------------------------"
32 | done
33 | else
34 | echo "Directory ${XSLT_DIR} not available, ignoring!"
35 | fi
--------------------------------------------------------------------------------
/image/resources/root/preinit/10-create-setup-properties.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ -f /custom-setup.properties ]; then
4 | echo "Using custom setup properties file:"
5 | echo "OpenCms Setup: Copying /custom-setup.properties to '$CONFIG_FILE'"
6 | cp /custom-setup.properties "$CONFIG_FILE"
7 | else
8 | OCSERVER=${SERVER_URL:-http://localhost}
9 | HWADDR=$(cat /sys/class/net/eth0/address)
10 |
11 | DB_USER=$DB_USER
12 | DB_PWD=$(get_secret DB_PASSWD_FILE DB_PASSWD)
13 | DB_DB=$DB_NAME
14 | DB_PRODUCT=mysql
15 | DB_URL="jdbc:mysql://${DB_HOST}:3306/"
16 | DB_DRIVER=org.gjt.mm.mysql.Driver
17 |
18 | # Create setup.properties
19 | echo "OpenCms Setup: Writing configuration to '$CONFIG_FILE'"
20 | echo "-- Components: $OPENCMS_COMPONENTS"
21 | PROPERTIES="
22 |
23 | setup.webapp.path=$OPENCMS_HOME
24 | setup.default.webapp=
25 | setup.install.components=$OPENCMS_COMPONENTS
26 | setup.show.progress=true
27 |
28 | db.product=$DB_PRODUCT
29 | db.provider=$DB_PRODUCT
30 | db.create.user=$DB_USER
31 | db.create.pwd=$DB_PWD
32 | db.worker.user=$DB_USER
33 | db.worker.pwd=$DB_PWD
34 | db.connection.url=$DB_URL
35 | db.name=$DB_DB
36 | db.create.db=true
37 | db.create.tables=true
38 | db.dropDb=true
39 | db.default.tablespace=
40 | db.index.tablespace=
41 | db.jdbc.driver=$DB_DRIVER
42 | db.template.db=
43 | db.temporary.tablespace=
44 |
45 | server.url=$OCSERVER
46 | server.name=OpenCmsServer
47 | server.ethernet.address=$HWADDR
48 | server.servlet.mapping=
49 |
50 | "
51 | echo "$PROPERTIES" > $CONFIG_FILE || { echo "Error: Couldn't write to '$CONFIG_FILE'!" ; exit 1 ; }
52 | fi
--------------------------------------------------------------------------------
/image/resources/root/wait-for.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | TIMEOUT=15
4 | QUIET=0
5 |
6 | echoerr() {
7 | if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
8 | }
9 |
10 | usage() {
11 | exitcode="$1"
12 | cat << USAGE >&2
13 | Usage:
14 | $cmdname host:port [-t timeout] [-- command args]
15 | -q | --quiet Do not output any status messages
16 | -t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
17 | -- COMMAND ARGS Execute command with args after the test finishes
18 | USAGE
19 | exit "$exitcode"
20 | }
21 |
22 | wait_for() {
23 | for i in `seq $TIMEOUT` ; do
24 | nc -z "$HOST" "$PORT" > /dev/null 2>&1
25 |
26 | result=$?
27 | if [ $result -eq 0 ] ; then
28 | if [ $# -gt 0 ] ; then
29 | exec "$@"
30 | fi
31 | exit 0
32 | fi
33 | sleep 1
34 | done
35 | echo "Operation timed out" >&2
36 | exit 1
37 | }
38 |
39 | while [ $# -gt 0 ]
40 | do
41 | case "$1" in
42 | *:* )
43 | HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
44 | PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
45 | shift 1
46 | ;;
47 | -q | --quiet)
48 | QUIET=1
49 | shift 1
50 | ;;
51 | -t)
52 | TIMEOUT="$2"
53 | if [ "$TIMEOUT" = "" ]; then break; fi
54 | shift 2
55 | ;;
56 | --timeout=*)
57 | TIMEOUT="${1#*=}"
58 | shift 1
59 | ;;
60 | --)
61 | shift
62 | break
63 | ;;
64 | --help)
65 | usage 0
66 | ;;
67 | *)
68 | echoerr "Unknown argument: $1"
69 | usage 1
70 | ;;
71 | esac
72 | done
73 |
74 | if [ "$HOST" = "" -o "$PORT" = "" ]; then
75 | echoerr "Error: you need to provide a host and port to test."
76 | usage 2
77 | fi
78 |
79 | wait_for "$@"
--------------------------------------------------------------------------------
/image/resources/root/opencms-restart.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # OpenCms server restart script
4 |
5 | # We must work around an isse here that exists with Docker and the default Tomcat startup scripts.
6 | # In short, the official "restart" script does not work in a Docker container. This is a known issue.
7 | # Full information on the issue: https://github.com/docker/docker/issues/6800
8 |
9 | WIDTH=$(stty size | cut -d" " -f2)
10 |
11 | echo "."
12 | echo "Restarting OpenCms!"
13 | echo "."
14 |
15 | CONTAINER_PID=$(ps -ef | egrep 'tomcat|jetty' | grep java | awk ' { print $2 } ')
16 |
17 | if [ -z "$CONTAINER_PID" ]; then
18 | echo "Servlet container was not running."
19 | else
20 | kill $(ps -ef | egrep 'tomcat|jetty' | grep java | awk ' { print $2 } ' )
21 | echo "Killed servlet container."
22 | echo "."
23 | echo "Waiting for a clean shut down..."
24 | echo "."
25 | while kill -0 $CONTAINER_PID > /dev/null 2>&1; do
26 | echo "Servlet container still running ... Here are the last lines of the opencms.log"
27 | tail -20 ${OPENCMS_HOME}/WEB-INF/logs/opencms.log
28 | sleep 5
29 | done
30 | echo "."
31 | echo "Servlet container is shut down ... Here are the last lines of the opencms.log"
32 | tail -20 ${OPENCMS_HOME}/WEB-INF/logs/opencms.log
33 | echo "."
34 | echo "Shut down completed."
35 | fi
36 | echo "."
37 | echo "Starting servlet container again..."
38 | echo "."
39 |
40 | start_container
41 | echo "."
42 | sleep 1
43 | echo "Showing servlet container process via 'ps -ef | grep tomcat | grep java':"
44 | ps -ef | egrep 'tomcat|jetty' | grep java
45 |
46 | echo "."
47 | echo "The ps output above should contain a ${SERVLET_CONTAINER} process."
48 | echo "This means the servlet container is running, even though a [fail] message may have been displayed earlier!"
49 | echo "."
50 |
--------------------------------------------------------------------------------
/image/resources/root/preinit/50_opencms_optimize_webxml_tomcat.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "${SERVLET_CONTAINER}" != "tomcat" ] ; then
4 | echo "Skipping $0 because we are not using Tomcat."
5 | exit
6 | fi
7 |
8 |
9 | CONFIG_WEBXML="${OPENCMS_HOME}/WEB-INF/web.xml"
10 | CONFIG_TMPFILE="/tmp/webxml.txt"
11 |
12 | # Optimize web.xml configuration
13 | if ! grep -q "ExpiresFilter" "$CONFIG_WEBXML" ; then
14 | read -r -d '' REPLACE_WEBXML << EOM
15 |
16 |
21 |
22 |
23 | ExpiresFilter
24 | org.apache.catalina.filters.ExpiresFilter
25 |
26 | ExpiresByType text/css
27 | access plus 24 hours
28 |
29 |
30 | ExpiresByType application/javascript
31 | access plus 24 hours
32 |
33 |
34 | ExpiresDefault
35 | access plus 365 days
36 |
37 |
38 |
39 |
40 | ExpiresFilter
41 | /export/*
42 | REQUEST
43 |
44 |
45 | EOM
46 |
47 | echo "${REPLACE_WEBXML}" > "${CONFIG_TMPFILE}"
48 |
49 | sed -i "/OpenCms<\/display-name>/ r ${CONFIG_TMPFILE}" "${CONFIG_WEBXML}"
50 |
51 | echo ""
52 | echo "Modified web.xml configuration looks like this:"
53 | echo "================================================================================================="
54 | cat "${CONFIG_WEBXML}"
55 | echo ""
56 | else
57 | echo "web.xml is already modified. Skipping repeated optimization."
58 | fi
--------------------------------------------------------------------------------
/image/resources/root/preinit/07_tomcat_setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "$SERVLET_CONTAINER" != "tomcat" ]; then
4 | echo "Skipping $0 because we are not using Tomcat"
5 | exit
6 | fi
7 | # Tomcat server configuration
8 | # This is ON PURPOSE done in the init / run phase NOT during image installation phase!
9 | # In case you need a special Tomact configuration in a downsteam image, just overwrite this configuration script.
10 | # Or, you can add the configuration as environment variable TOMCAT_OPTS.
11 | if [ -z "${TOMCAT_OPTS}" ]; then
12 | TOMCAT_OPTS="-Xmx2g -Xms512m -server"
13 | else
14 | TOMCAT_OPTS="${TOMCAT_OPTS}"
15 | fi
16 |
17 | if [ "${DEBUG}" == "true" ]; then
18 | TOMCAT_OPTS="${TOMCAT_OPTS} -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000 -Djava.compiler=NONE"
19 | fi
20 |
21 | # By default Tomcat will overwrite session cookies from multiple webapps on the same IP even different ports are used
22 | # With this little 'sed' magic, each running docker instance will attach the ID of the running container to the session cookie name
23 | echo "Making session cookie name unique and disabling web sockets ..."
24 | sed -i "s///" ${TOMCAT_HOME}/conf/context.xml
25 |
26 | # Increasing Tomcat webresources cache size
27 | echo "Setting webresources cache size to override defaults"
28 | sed -i "s/<\/Context>/<\/Context>/" ${TOMCAT_HOME}/conf/context.xml
29 |
30 | # Disabling session persistence
31 | # Disable JAR scanning for servlets and restrict TLD scanning to the JSTL JAR to speed up Tomcat start
32 | echo "Disabling session persistence and adding JAR scanner filter ..."
33 | sed -i "s/<\/Context>/<\/JarScanner><\/Context>/" ${TOMCAT_HOME}/conf/context.xml
34 |
35 |
36 | echo "Setting java opts for Tomcat to: ${TOMCAT_OPTS}"
37 | echo "JAVA_OPTS=\"-Djava.awt.headless=true -DDISPLAY=:0.0 ${TOMCAT_OPTS}\"" > ${TOMCAT_HOME}/bin/setenv.sh
38 |
39 | echo "Using OpenCms optimized server.xml configuration for Tomcat"
40 | mv -v /config/server.xml ${TOMCAT_HOME}/conf/server.xml
--------------------------------------------------------------------------------
/image/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG BASE_IMAGE=jetty:12-jdk21
2 | FROM $BASE_IMAGE
3 | LABEL org.opencontainers.image.authors="Alkacon Software GmbH & Co. KG"
4 | USER root
5 | ARG SERVLET_CONTAINER=jetty
6 | ENV SERVLET_CONTAINER=${SERVLET_CONTAINER}
7 |
8 | #
9 | # This Dockerfile installs a simple OpenCms demo system.
10 | # It downloads the OpenCms distro and installs it with all the standard demo modules.
11 | #
12 | # You should run it in combination with a mysql container, as specified in the docker-compose.yaml
13 | # coming with this repository.
14 | #
15 |
16 | # Variables used in the shell scripts loaded from the file system
17 | ENV DEBIAN_FRONTEND=noninteractive \
18 | TMPDIR=/tmp
19 |
20 | ENV CONTAINER_BASE=/container \
21 | TOMCAT_HOME=/usr/local/tomcat \
22 | JETTY_HOME=/usr/local/jetty \
23 | BASH_ENV=/root/common.sh
24 |
25 | ENV TOMCAT_LIB=${TOMCAT_HOME}/lib \
26 | JETTY_LIB=${JETTY_HOME}/lib \
27 | WEBAPPS_HOME=${CONTAINER_BASE}/webapps \
28 | OPENCMS_HOME=${CONTAINER_BASE}/webapps/ROOT \
29 | ARTIFACTS_FOLDER=/artifacts/ \
30 | CONFIG_FILE=/config/setup.properties \
31 | OPENCMS_URL=https://github.com/alkacon/opencms-core/releases/download/build_20_0_0/opencms-20.0-distribution.zip \
32 | OPENCMS_COMPONENTS=workplace,demo \
33 | UPDATE_CONFIG_FILES="WEB-INF/web.xml WEB-INF/opencms.tld WEB-INF/config/opencms-search.xml WEB-INF/config/opencms-system.xml WEB-INF/config/opencms-vfs.xml WEB-INF/config/opencms-workplace.xml WEB-INF/solr/configsets/default/conf/solrconfig.xml WEB-INF/solr/spellcheck/conf/solrconfig.xml"\
34 | TIME_ZONE=Europe/Berlin \
35 | JETTY_OPTS="-Xmx2g" \
36 | TOMCAT_OPTS= \
37 | ADMIN_PASSWD=admin \
38 | ADMIN_PASSWD_FILE= \
39 | DB_HOST=mysql \
40 | DB_NAME=opencms \
41 | DB_USER=root \
42 | DB_PASSWD= \
43 | DB_PASSWD_FILE= \
44 | WEBRESOURCES_CACHE_SIZE=200000 \
45 | DEBUG=false
46 |
47 | RUN \
48 | echo "Update the apt packet repos" && \
49 | apt-get update && \
50 | echo "Install utils" && \
51 | apt-get install -yq --no-install-recommends procps wget unzip xsltproc netcat-openbsd && \
52 | echo "Clean up apt" && \
53 | rm -rf /var/lib/apt/lists/* && \
54 | apt-get autoremove && \
55 | apt-get clean
56 |
57 | # Create the setup configuration file
58 | COPY resources /
59 |
60 | RUN \
61 | echo "Make scripts under /root/ executable" && \
62 | chmod +x /root/*.sh && \
63 | echo "Update .bashrc" && \
64 | echo "source /root/common.sh" >> /root/.bashrc && \
65 | bash /root/opencms-fetch.sh && \
66 | rm -rf ${WEBAPPS_HOME}/*
67 |
68 | # Expose port 8080 for Tomcat and define the startup script
69 | EXPOSE 8080
70 | WORKDIR $CONTAINER_BASE
71 | CMD ["/root/opencms-run.sh"]
72 |
--------------------------------------------------------------------------------
/image/resources/root/common.sh:
--------------------------------------------------------------------------------
1 | # common shell functions for use in other scripts
2 | # (Included via BASH_ENV for noninteractive bash shells and is sourced in .bashrc for interactive ones)
3 |
4 | function get_secret() {
5 | if [ -z "${1+x}" ] || [ -z "${2+x}" ]; then
6 | echo "Two args required."
7 | return 1
8 | fi
9 | if [[ "$1" != *_FILE ]]; then
10 | echo "Arg 1 must end with the _FILE suffix."
11 | return 1
12 | fi
13 | local sec_file="$1"
14 | local sec_env="$2"
15 | if [[ -n "${!sec_file}" ]]; then
16 | if [[ -f "${!sec_file}" ]]; then
17 | local password
18 | password=$(<"${!sec_file}")
19 | echo "${password}" | xargs
20 | else
21 | echo "File ${sec_file}=${!sec_file} not found."
22 | fi
23 | elif [[ -n "${!sec_env}" ]]; then
24 | echo "${!sec_env}"
25 | else
26 | echo "Either ${sec_file} or ${sec_env} must be set."
27 | return 1
28 | fi
29 | }
30 |
31 | function shell_classpath() {
32 | if [ "${SERVLET_CONTAINER}" == "tomcat" ]; then
33 | echo "${OPENCMS_HOME}/WEB-INF/lib/*:${OPENCMS_HOME}/WEB-INF/classes:${TOMCAT_LIB}/*"
34 | elif [ "${SERVLET_CONTAINER}" == "jetty" ]; then
35 | # Jetty libraries in OpenCms which are needed for Solr would cause a version conflict with the libraries included in Jetty,
36 | # so we have to specifically only include the servlet/JSP API libs in the CmsShell classpath.
37 | local SERVLET_API=$(find ${JETTY_LIB} -maxdepth 1 -name 'jetty-servlet-api*.jar' | head -1)
38 | echo "${OPENCMS_HOME}/WEB-INF/lib/*:${OPENCMS_HOME}/WEB-INF/classes:$SERVLET_API:${JETTY_HOME}/lib/ee8-apache-jsp/*"
39 | fi
40 | }
41 |
42 | function start_container() {
43 | if [ "${SERVLET_CONTAINER}" == "tomcat" ] ; then
44 | start_tomcat
45 | elif [ "${SERVLET_CONTAINER}" == "jetty" ] ; then
46 | start_jetty
47 | fi
48 | }
49 |
50 | function start_tomcat() {
51 | ${TOMCAT_HOME}/bin/catalina.sh run >> ${TOMCAT_HOME}/logs/catalina.out 2>&1 &
52 | }
53 |
54 | function start_jetty() {
55 | cd $CONTAINER_BASE
56 | java $(jetty_opts) -jar $JETTY_HOME/start.jar >> ${CONTAINER_BASE}/jetty.out 2>&1 &
57 | }
58 |
59 | function kill_container() {
60 | local pid=""
61 | if [ -d $TOMCAT_HOME ] ; then
62 | pid=$(pgrep -f org.apache.catalina.startup.Bootstrap)
63 | else
64 | pid=$(pgrep -f $JETTY_HOME/start.jar)
65 | fi
66 | if [[ ! -z "$pid" ]] ; then
67 | kill -TERM "$pid"
68 | wait "$pid" >/dev/null
69 | fi
70 | }
71 |
72 | function jetty_opts() {
73 | local OPTS="-server -Djava.awt.headless=true -XX:-OmitStackTraceInFastThrow -DDISPLAY=:0.0"
74 | if [ "$DEBUG" == "true" ]; then
75 | OPTS="$OPTS -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000 -Djava.compiler=NONE"
76 | fi
77 | OPTS="$OPTS $(cat $CONTAINER_BASE/jetty-opts.txt)"
78 | echo "$OPTS"
79 | }
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/scripts/opencms-mount.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Mount OpenCms with SAMBA.
4 | #
5 |
6 |
7 | ##################
8 | #
9 | # Display usage info.
10 | #
11 | showUsage() {
12 | echo ""
13 | echo "${red}Usage: `basename "${0}"` ${bold}[OPTIONS]${normal}"
14 | echo ""
15 | echo "Supported command line ${bold}[OPTION]${normal}s:"
16 | echo "${bold} -f FILENAME ${normal}Process given file for parameters, e.g. '~/docker-1'."
17 | echo "${bold} -t TARGET ${normal}Mount on the given target folder '/mnt/mymount/' (${OCMOUNT_TARGET})."
18 | echo "${bold} -s SOURCE ${normal}Mount the given remote folter, e.g. '//docker-1/OCMOUNTS' (${OCMOUNT_SOURCE})."
19 | echo "${bold} -u USER ${normal}Username to use for login, eg. 'Admin' (${OCMOUNT_USER})."
20 | echo "${bold} -p PASSWORD ${normal}Password to use for login, eg. 'admin' (${OCMOUNT_PWD})."
21 | echo "${bold} -i ID ${normal}Used as user and group name for local mounting, e.g. 'root' (${OCMOUNT_ID})."
22 | echo "${bold} -o PORT ${normal}Port to connect to, eg. '1445' (${OCMOUNT_PORT})."
23 | echo "${normal}"
24 | exit 1
25 | }
26 |
27 | ##################
28 | #
29 | # Check for empty parameter.
30 | #
31 | checkEmpty() {
32 | for i in "$@"; do
33 | eval local PARAM="\${${i}}"
34 | if [ -z "${PARAM}" ]; then
35 | showUsage
36 | fi
37 | shift
38 | done
39 | }
40 |
41 | ##################
42 | #
43 | # Set env variable for options.
44 | #
45 | setOptions() {
46 |
47 | # check if stdout is a terminal...
48 | if test -t 1; then
49 | # see if it supports colors...
50 | NCOLORS=$(tput colors)
51 | if test -n "${NCOLORS}" && test ${NCOLORS} -ge 8; then
52 | bold="$(tput bold)"
53 | underline="$(tput smul)"
54 | standout="$(tput smso)"
55 | normal="$(tput sgr0)"
56 | black="$(tput setaf 0)"
57 | red="$(tput setaf 1)"
58 | green="$(tput setaf 2)"
59 | yellow="$(tput setaf 3)"
60 | blue="$(tput setaf 4)"
61 | magenta="$(tput setaf 5)"
62 | cyan="$(tput setaf 6)"
63 | white="$(tput setaf 7)"
64 | fi
65 | fi
66 |
67 | # OCMOUNT_TARGET="${OCMOUNT_TARGET:-/mnt/opencms/vfs/}"
68 | # OCMOUNT_SOURCE="${OCMOUNT_SOURCE:-//localhost/OPENCMS}"
69 | OCMOUNT_USER="${OCMOUNT_USER:-Admin}"
70 | OCMOUNT_PWD="${OCMOUNT_PWD:-admin}"
71 | OCMOUNT_ID="${OCMOUNT_ID:-$USER}"
72 | OCMOUNT_PORT="${OCMOUNT_PORT:-445}"
73 |
74 | while true; do
75 | case "${1}" in
76 | -f | --file )
77 | OCMOUNT_PARAMFILE="${2}"
78 | source ${OCMOUNT_PARAMFILE}
79 | shift 2 ;;
80 | -t | --target )
81 | OCMOUNT_TARGET="${2}"
82 | shift 2 ;;
83 | -s | --source )
84 | OCMOUNT_SOURCE="${2}"
85 | shift 2 ;;
86 | -u | --user )
87 | OCMOUNT_USER="${2}"
88 | shift 2 ;;
89 | -p | --pwd | --password )
90 | OCMOUNT_PWD="${2}"
91 | shift 2 ;;
92 | -i | --id )
93 | OCMOUNT_ID="${2}"
94 | shift 2 ;;
95 | -o | --port )
96 | OCMOUNT_PORT="${2}"
97 | shift 2 ;;
98 | "" ) break ;;
99 | * )
100 | echo "Invalid [OPTION] \"${1}\" provided!"
101 | showUsage
102 | break ;;
103 | esac
104 | done
105 |
106 | checkEmpty "OCMOUNT_TARGET" "OCMOUNT_SOURCE" "OCMOUNT_USER" "OCMOUNT_PWD" "OCMOUNT_ID" "OCMOUNT_PORT"
107 | }
108 |
109 | setOptions "${@}"
110 |
111 | MNT_PARAM="-v -t cifs -o uid=${OCMOUNT_ID},gid=${OCMOUNT_ID},username=${OCMOUNT_USER},password=${OCMOUNT_PWD},port=${OCMOUNT_PORT} ${OCMOUNT_SOURCE} ${OCMOUNT_TARGET}"
112 |
113 | # the command to execute
114 | MNT_CMD="sudo mount ${MNT_PARAM}"
115 |
116 | echo ""
117 | echo "${green}${bold}Executing: ${cyan}"
118 | echo "sudo umount -v -l -f ${OCMOUNT_TARGET}"
119 | echo "${MNT_CMD}"
120 | echo "ls -la ${OCMOUNT_TARGET}"
121 | echo "${normal}"
122 |
123 | sudo umount -v -l -f ${OCMOUNT_TARGET}
124 | bash -c "${MNT_CMD}"
125 | ls -la ${OCMOUNT_TARGET}
126 |
--------------------------------------------------------------------------------
/image/resources/root/preinit/20_check_install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ ! -d ${ARTIFACTS_FOLDER}libs ]; then
3 | mkdir -v -p ${ARTIFACTS_FOLDER}libs
4 | fi
5 |
6 | echo "Writing properties file to contain list of JARs used by the OpenCms core, to be used in later updates."
7 | JAR_NAMES=$( zipinfo -1 ${ARTIFACTS_FOLDER}opencms.war *.jar | tr '\n' ',' )
8 | JAR_NAMES_PROPERTIES="OPENCMS_CORE_LIBS=$JAR_NAMES"
9 | JAR_NAMES_PROPERTIES_FILE=${ARTIFACTS_FOLDER}libs/core-libs.properties
10 | echo "$JAR_NAMES_PROPERTIES" > $JAR_NAMES_PROPERTIES_FILE
11 |
12 | if [ -f "${OPENCMS_HOME}/WEB-INF/lib/opencms.jar" ]
13 | then
14 | echo "OpenCms already installed, updating modules and libs"
15 |
16 | admin_passwd=$(get_secret ADMIN_PASSWD_FILE ADMIN_PASSWD)
17 | if [ ! -z "$admin_passwd" ]; then
18 | echo "Changing Admin password for update"
19 | sed -i -- "s/Admin admin/\"Admin\" \"${admin_passwd}\"/g" /config/update*
20 | fi
21 |
22 | echo "Extract modules and libs"
23 | unzip -q -d ${ARTIFACTS_FOLDER}TEMP ${ARTIFACTS_FOLDER}opencms.war
24 | mv ${ARTIFACTS_FOLDER}TEMP/WEB-INF/packages/modules/* ${ARTIFACTS_FOLDER}
25 |
26 | mv ${ARTIFACTS_FOLDER}TEMP/WEB-INF/lib/* ${ARTIFACTS_FOLDER}libs
27 | echo "Renaming modules to remove version number"
28 | for file in ${ARTIFACTS_FOLDER}*.zip
29 | do
30 | if [[ $file =~ .*-.*\.zip ]]; then
31 | mv $file ${file%-*}".zip"
32 | fi
33 | done
34 | echo "Creating backup of opencms-modules.xml at ${OPENCMS_HOME}/WEB-INF/config/backups/opencms-modules-preinst.xml"
35 | if [ ! -d ${OPENCMS_HOME}/WEB-INF/config/backups ]; then
36 | mkdir -v -p ${OPENCMS_HOME}/WEB-INF/config/backups
37 | fi
38 | cp -f -v ${OPENCMS_HOME}/WEB-INF/config/opencms-modules.xml ${OPENCMS_HOME}/WEB-INF/config/backups/opencms-modules-preinst.xml
39 |
40 | echo "Updating config files with the version from the OpenCms WAR"
41 | unzip -q -d ${OPENCMS_HOME} ${ARTIFACTS_FOLDER}opencms.war WEB-INF/packages/modules/*.zip WEB-INF/lib/*.jar
42 | IFS=',' read -r -a FILES <<< "$UPDATE_CONFIG_FILES"
43 | for FILENAME in ${FILES[@]}
44 | do
45 | if [ -f "${OPENCMS_HOME}/${FILENAME}" ]
46 | then
47 | rm -rf "${OPENCMS_HOME}/${FILENAME}"
48 | fi
49 | echo "Moving file from \"${ARTIFACTS_FOLDER}TEMP/${FILENAME}\" to \"${OPENCMS_HOME}/${FILENAME}\" ..."
50 | mv "${ARTIFACTS_FOLDER}TEMP/${FILENAME}" "${OPENCMS_HOME}/${FILENAME}"
51 | done
52 |
53 | echo "Updating OpenCms core JARs"
54 | if [ -f ${OPENCMS_HOME}/WEB-INF/lib/core-libs.properties ]; then
55 | echo "Deleting old JARs first"
56 | while IFS='=' read -r key value
57 | do
58 | key=$(echo $key | tr '.' '_')
59 | eval ${key}=\${value}
60 | done < "${OPENCMS_HOME}/WEB-INF/lib/core-libs.properties"
61 |
62 | IFS=',' read -r -a CORE_LIBS <<< "$OPENCMS_CORE_LIBS"
63 | for CORE_LIB in ${CORE_LIBS[@]}
64 | do
65 | rm -f -v ${OPENCMS_HOME}/${CORE_LIB}
66 | done
67 | fi
68 | echo "Moving new JARs"
69 | mv ${ARTIFACTS_FOLDER}libs/* ${OPENCMS_HOME}/WEB-INF/lib/
70 |
71 | echo "Update modules core"
72 | bash /root/execute-opencms-shell.sh /config/update-core-modules.ocsh
73 | else
74 | echo "OpenCms not installed yet, running setup"
75 | if [ ! -d ${WEBAPPS_HOME} ]; then
76 | mkdir -v -p ${WEBAPPS_HOME}
77 | fi
78 |
79 | if [ ! -d ${OPENCMS_HOME} ]; then
80 | mkdir -v -p ${OPENCMS_HOME}
81 | fi
82 |
83 | echo "Unzip the .war"
84 | unzip -q -d ${OPENCMS_HOME} ${ARTIFACTS_FOLDER}opencms.war
85 | mv ${ARTIFACTS_FOLDER}libs/core-libs.properties ${OPENCMS_HOME}/WEB-INF/lib
86 | if [ ! -z "$ADMIN_PASSWD" ]; then
87 | echo "Changing Admin password for setup"
88 | sed -i -- "s/login \"Admin\" \"admin\"/login \"Admin\" \"admin\"\nsetPassword \"Admin\" \"$ADMIN_PASSWD\"\nlogin \"Admin\" \"$ADMIN_PASSWD\"/g" "${OPENCMS_HOME}/WEB-INF/setupdata/cmssetup.txt"
89 | fi
90 |
91 | CLASSPATH="$(shell_classpath)"
92 | echo "Install OpenCms using org.opencms.setup.CmsAutoSetup with properties \"${CONFIG_FILE}\"" && \
93 | echo "Classpath: $CLASSPATH" && \
94 | java -classpath "${CLASSPATH}" org.opencms.setup.CmsAutoSetup -path ${CONFIG_FILE}
95 |
96 | echo "Deleting no longer used files"
97 | rm -rf ${OPENCMS_HOME}/setup
98 | rm -rf ${OPENCMS_HOME}/WEB-INF/packages/modules/*.zip
99 | fi
100 |
101 | echo "Deleting artifacts folder"
102 | rm -rf ${ARTIFACTS_FOLDER}
103 | rm -rf ${OPENCMS_HOME}/setup
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # Official OpenCms Docker Image
8 |
9 | Welcome to the official OpenCms Docker image maintained by [Alkacon](https://github.com/alkacon/).
10 |
11 | Here you find a Docker Compose setup with a ready to use OpenCms installation including Jetty and MariaDB.
12 |
13 | OpenCms can be used with other databases as described below.
14 |
15 | ## Available tags
16 |
17 | * [latest, 20.1](https://github.com/alkacon/opencms-docker/blob/20.1/image/Dockerfile)
18 | * [20.0](https://github.com/alkacon/opencms-docker/blob/20.0/image/Dockerfile)
19 | * [19.0](https://github.com/alkacon/opencms-docker/blob/19.0/image/Dockerfile)
20 | * [18.0](https://github.com/alkacon/opencms-docker/blob/18.0/image/Dockerfile)
21 | * [17.0](https://github.com/alkacon/opencms-docker/blob/17.0/image/Dockerfile)
22 | * [16.0](https://github.com/alkacon/opencms-docker/blob/16.0/image/Dockerfile)
23 | * [15.0](https://github.com/alkacon/opencms-docker/blob/15.0/image/Dockerfile)
24 | * [14.0](https://github.com/alkacon/opencms-docker/blob/14.0/image/Dockerfile)
25 | * [13.0](https://github.com/alkacon/opencms-docker/blob/13.0/image/Dockerfile)
26 | * [12.0](https://github.com/alkacon/opencms-docker/blob/12.0/image/Dockerfile)
27 | * [11.0.2](https://github.com/alkacon/opencms-docker/blob/11.0.2/image/Dockerfile)
28 | * [11.0.1](https://github.com/alkacon/opencms-docker/blob/11.0.1/image/Dockerfile)
29 | * [11.0.0](https://github.com/alkacon/opencms-docker/blob/11.0.0/image/Dockerfile)
30 |
31 | Images for older OpenCms versions are also available, see [here](https://github.com/alkacon/opencms-docker/blob/pre_11_images/README.md).
32 |
33 | ## How to use this image
34 |
35 | ### Step 1: docker-compose.yml
36 |
37 | Save the following *docker-compose.yml* file to your host machine.
38 |
39 | ```
40 | services:
41 | mariadb:
42 | image: mariadb:latest
43 | container_name: mariadb
44 | init: true
45 | restart: always
46 | volumes:
47 | - ~/dockermount/opencms-docker-mysql:/var/lib/mysql
48 | environment:
49 | - "MYSQL_ROOT_PASSWORD=secretDBpassword"
50 | opencms:
51 | image: alkacon/opencms-docker:20.1
52 | container_name: opencms
53 | init: true
54 | restart: always
55 | depends_on: [ "mariadb" ]
56 | links:
57 | - "mariadb:mysql"
58 | ports:
59 | - "80:8080"
60 | volumes:
61 | - ~/dockermount/opencms-docker-webapps:/container/webapps
62 | command: ["/root/wait-for.sh", "mysql:3306", "-t", "30", "--", "/root/opencms-run.sh"]
63 | environment:
64 | - "DB_PASSWD=secretDBpassword"
65 | ```
66 |
67 | Change the MariaDB root password `secretDBpassword`.
68 |
69 | ### Step 2: Persist data
70 |
71 | Adjust the following directories for your host system:
72 |
73 | * `~/dockermount/opencms-docker-mysql` the directory where all MariaDB data are persisted
74 | * `~/dockermount/opencms-docker-webapps` the Tomcat webapps directory that contains important configurations, caches and indices of OpenCms
75 |
76 | Configured in this way, it is possible to upgrade the `opencms` and `mariadb` containers while keeping all your OpenCms and MariaDB data. See the upgrade guide below.
77 |
78 | On the other hand, if you like to start with a completely fresh OpenCms installation, do not forget to delete both mounted directories before.
79 |
80 | ### Step 3: Start OpenCms and MariaDB
81 |
82 | Navigate to the folder with the *docker-compose.yml* file and execute `docker-compose up -d`.
83 |
84 | Startup will take a while since numerous modules are installed.
85 |
86 | You can follow the installation process with `docker-compose logs -f opencms`.
87 |
88 | ### Step 4: Login to OpenCms
89 |
90 | When the containers are set up, you can access the OpenCms workplace via `http://localhost/system/login`.
91 |
92 | The default account is username `Admin` with password `admin`.
93 |
94 | ## Environment variables
95 |
96 | In addition to `DB_PASSWD`, the following environment variables are supported:
97 |
98 | * `DB_HOST`, the database host name, defaults to `mysql`
99 | * `DB_USER`, the database user, default is `root`
100 | * `DB_PASSWD`, the database password, is not set by default
101 | * `DB_PASSWD_FILE`, file in the container where the database password is stored (`/run/secrets/`); to be used with docker compose `secrets`
102 | * `DB_NAME`, the database name, default is `opencms`
103 | * `ADMIN_PASSWD`, the admin password, defaults to `admin`
104 | * `ADMIN_PASSWD_FILE`, file in the container where the admin password is stored (`/run/secrets/`); to be used with docker compose `secrets`
105 | * `OPENCMS_COMPONENTS`, the OpenCms components to install, default is `workplace,demo`; to not install the demo template use `workplace`
106 | * `JETTY_OPTS`, the Jetty startup options (in addition to predefined options), default is `-Xmx2g`
107 | * `DEBUG`, flag indicating whether to enable verbose debug logging and allowing connections via {docker ip address}:8000, defaults to `false`
108 | * `JSONAPI`, flag indicating whether to enable the JSON API, default is `false`
109 | * `SERVER_URL`, the server URL, default is `http://localhost`
110 |
111 | The variables `DB_PASSWD` and `DB_PASSWD_FILE` respectively `ADMIN_PASSWD` and `ADMIN_PASSWD_FILE` are alternatives. Read more about docker compose secrets [here](https://docs.docker.com/compose/how-tos/use-secrets/).
112 |
113 | ## Upgrade the image
114 |
115 | *Before upgrading the image, make sure that you have persisted your OpenCms data and MariaDB data with Docker volumes as described above. Otherwise you will lose your data.*
116 |
117 | *When upgrading from an older version of this image, read the image history below at first.*
118 |
119 | Enter the target version of the OpenCms image in your docker-compose.yml file.
120 |
121 | ```
122 | opencms:
123 | image: alkacon/opencms-docker:20.1
124 | ```
125 |
126 | Navigate to the folder with the docker-compose.yml file and execute `docker-compose up -d`.
127 |
128 | During startup, the Docker setup will update several modules as well as JAR files and configurations in the `/container/webapps` directory.
129 |
130 | You can follow the installation process with `docker compose logs -f opencms`.
131 |
132 | *It is recommended to remove the* `/container/webapps/ROOT/WEB-INF/index` *folder after upgrade and do a full Solr reindex.*
133 |
134 | ## Support for other databases
135 |
136 | OpenCms uses a special configuration file called [setup.properties](https://github.com/alkacon/opencms-core/blob/master/src-setup/org/opencms/setup/setup.properties.example) to establish a database connection.
137 |
138 | In order to connect to a database other than MariaDB, this image supports connection via a custom *setup.properties* file.
139 |
140 | The file must be named `custom-setup.properties` and must be available in the root folder of the docker container.
141 |
142 | An example setup for PostgreSQL can be found [here](https://github.com/alkacon/opencms-docker/tree/master/compose/postgres).
143 |
144 | For more information on the DB configuration options, see the [OpenCms documentation](https://documentation.opencms.org/opencms-documentation/server-administration/headless-installation/).
145 |
146 | Note: when using a custom configuration file, the environment variables `DB_HOST, DB_USER, DB_PASSWD, DB_NAME, OPENCMS_COMPONENTS, SERVER_URL` are ignored.
147 |
148 | ## Building the image
149 |
150 | Since the image is available on Docker Hub, you do not need to build it yourself. If you want to build it anyway, here's how to do it:
151 |
152 | Download the [opencms-docker](https://github.com/alkacon/opencms-docker) repository.
153 |
154 | Go to the repository's main folder and type `docker compose build opencms`.
155 |
156 | ## License
157 |
158 | View the [licence information on GitHub](https://github.com/alkacon/opencms-docker/blob/master/LICENSE).
159 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | (This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.)
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 | {description}
474 | Copyright (C) {year} {fullname}
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
489 | USA
490 |
491 | Also add information on how to contact you by electronic and paper mail.
492 |
493 | You should also get your employer (if you work as a programmer) or your
494 | school, if any, to sign a "copyright disclaimer" for the library, if
495 | necessary. Here is a sample; alter the names:
496 |
497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
498 | library `Frob' (a library for tweaking knobs) written by James Random
499 | Hacker.
500 |
501 | {signature of Ty Coon}, 1 April 1990
502 | Ty Coon, President of Vice
503 |
504 | That's all there is to it!
505 |
506 |
--------------------------------------------------------------------------------