This is an automated email from the ASF dual-hosted git repository. danwatford pushed a commit to branch release22.01 in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/release22.01 by this push: new 55987e5627 Implemented: Add docker build functionality to release22.01 branch (OFBIZ-12797) 55987e5627 is described below commit 55987e56278d468c2d69cf97936539e02858ae61 Author: Daniel Watford <dan...@watfordconsulting.com> AuthorDate: Tue Apr 11 19:52:12 2023 +0100 Implemented: Add docker build functionality to release22.01 branch (OFBIZ-12797) Added docker build sources, documentation and example usage to the release22.01 branch. Also added GitHub Actions workflow to build and push container images to the GitHub Container Registry (ghcr.io). --- .dockerignore | 30 ++ .github/workflows/docker-image.yaml | 151 ++++++++ DOCKER.md | 189 ++++++++++ Dockerfile | 128 +++++++ build.gradle | 8 + docker/disable-component.xslt | 33 ++ docker/docker-entrypoint.sh | 392 +++++++++++++++++++++ .../after-config-applied.d/applySolrConfig.sh | 26 ++ docker/examples/postgres-demo/docker-compose.yml | 49 +++ docker/examples/postgres-demo/ofbiz-postgres.env | 32 ++ .../postgres-initdb.d/10-init-user-db.sh | 35 ++ docker/examples/postgres-demo/postgres.env | 21 ++ docker/send_ofbiz_stop_signal.sh | 39 ++ docker/templates/postgres-entityengine.xml | 176 +++++++++ 14 files changed, 1309 insertions(+) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..24f2d41429 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +Dockerfile +.gradle/ +/bin/ +/build/ +/runtime/ +/themes/common-theme/webapp/common/js/node_modules/ +/themes/common-theme/webapp/common-theme/js/node_modules/ +/plugins/.svn +/plugins/.github +/plugins/.git + diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml new file mode 100644 index 0000000000..da5cef1103 --- /dev/null +++ b/.github/workflows/docker-image.yaml @@ -0,0 +1,151 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. + +############################################################################# +# Local testing of this workflow can be carried out using +# act (https://github.com/nektos/act). +# +# Act will set an environment variable, ACT, to indicate that it is running the workflow. +# This environment variable is used to skip some build steps, such as logging in to +# a container registry or pushing container images. +# +# On first run, act will prompt you to select a micro, medium or large runner image. This +# workflow can be run using the medium image. +# +# Some actions, such as docker/metadata-action, require a GITHUB_TOKEN. To meet this +# requirement when using act you will need to create a Personal Access Token on GitHub. +# You can then run act using a command similar to: +# act --job docker_build --secret GITHUB_TOKEN +# Act will then prompt you to enter your token. + + +name: Build and push docker images + +on: + push: + branches: [ release22.01 ] + tags: + - '**' + +jobs: + docker_build: + name: Build and push OFBiz docker container images + runs-on: ubuntu-latest + steps: + - name: Check out OFBiz sources + uses: actions/checkout@v3 + + - name: Log in to the Container registry + if: ${{ !env.ACT }} + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + ############################################################################ + # Build and push a container image of the OFBiz Framework without any data loaded. + - name: Determine metadata (tags, labels) for Docker runtime build + id: runtimemeta + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 + with: + images: ghcr.io/apache/ofbiz + tags: | + # Extract container tag from git tag. + type=match,pattern=release(.*),group=1 + # Build container tag based on branch name and string '-snapshot' + type=ref,event=branch,suffix=-snapshot,priority=650 + + - name: Update VERSION file + run: | + # Populate the VERSION file based on the outputs of the metadata-action above. + # The same VERSION file will be used for all container images built in this workflow. + + # Set the version label for this build. + echo "${{fromJSON(steps.runtimemeta.outputs.json).labels['org.opencontainers.image.version']}}. " > VERSION + + # Append the git commit SHA. + echo '${uiLabelMap.CommonRevision}:' "${{fromJSON(steps.runtimemeta.outputs.json).labels['org.opencontainers.image.revision']}}. " >> VERSION + + # Append the timestamp. + echo '${uiLabelMap.CommonBuiltOn}:' "${{fromJSON(steps.runtimemeta.outputs.json).labels['org.opencontainers.image.created']}}. " >> VERSION + + echo "Version file contents:" + cat VERSION + + + - name: Build and push runtime docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + target: runtime + push: ${{ !env.ACT }} + tags: ${{ steps.runtimemeta.outputs.tags }} + labels: ${{ steps.runtimemeta.outputs.labels }} + + ############################################################################ + # Build and push a container image of the OFBiz Framework preloaded with demo data + - name: Determine metadata (tags, labels) for Docker demo-preload build + id: demometa + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 + with: + images: ghcr.io/apache/ofbiz + tags: | + type=match,pattern=release(.*),group=1,suffix=-preloaddemo + type=ref,event=branch,suffix=-preloaddemo-snapshot,priority=650 + + - name: Build and push demo docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + target: demo + push: ${{ !env.ACT }} + tags: ${{ steps.demometa.outputs.tags }} + labels: ${{ steps.demometa.outputs.labels }} + + ############################################################################ + # Build and push a container image of the OFBiz Framework plus Plugins, + # without any data loaded. + # We need to use gradle to download sources as plugins might include an install + # task in their own build.gradle files. If the project drops support for plugins' + # install tasks then we can replace the JDK and gradle related steps below with + # a git checkout from the https://github.com/apache/ofbiz-plugins repository. + - name: Set up JDK 17 + uses: actions/setup-java@v3.6.0 + with: + java-version: 17 + distribution: temurin + cache: 'gradle' + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew pullAllPluginsSource + - name: Determine metadata (tags, labels) for Docker framework with plugins build + id: pluginsmeta + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 + with: + images: ghcr.io/apache/ofbiz + tags: | + type=match,pattern=release(.*),group=1,suffix=-plugins + type=ref,event=branch,suffix=-plugins-snapshot,priority=650 + + - name: Build and push framework with plugins docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + target: runtime + push: ${{ !env.ACT }} + tags: ${{ steps.pluginsmeta.outputs.tags }} + labels: ${{ steps.pluginsmeta.outputs.labels }} diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000000..50ecdf093e --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,189 @@ +# Building and running OFBiz using Docker + +OFBiz includes a Dockerfile which can be used to build a container image for running OFBiz. +The container image is built based on the sources already available in the build +content, i.e. it only uses sources that you have already downloaded. + +If you want to include any plugins in your container image, you must download those +plugins before running the build. (See the plugin documentation in README.adoc). + +## Quickstart +Follow these instructions to qet started building and running OFBiz using Docker. + +### Build the OFBiz container image + +From the sources directory (i.e. the directory containing Docker.md), run +```shell script +DOCKER_BUILDKIT=1 docker build --tag ofbiz-docker . +``` + +### Run the OFBiz container + +Run the following command: +```shell script +docker run -it -e OFBIZ_DATA_LOAD=demo --name ofbiz-docker -p 8443:8443 ofbiz-docker +``` + +This will start an instance of the ofbiz-docker container, publish port 8443 to localhost, +load the OFBiz demo data, and then run the OFBiz server. + +Once start up completes, you can access OFBIZ at http://localhost:8443/partymgr + +## Other container building options + +The OFBiz `Dockerfile` defines a mult-stage build. The default container image produced by the build is named `runtime` +and consists of an unintialized OFBiz installation. + +During the first run of a container based on this image, seed or demo data can be loaded, and an admin user created. + +The runtime container is the default target of a docker build and can be created with commands similar to: +```shell script +DOCKER_BUILDKIT=1 docker build --tag ofbiz-docker . +``` +OR +```shell script +DOCKER_BUILDKIT=1 docker build --target runtime --tag ofbiz-docker . +``` + +The Dockerfile also defines another stage, `demo`, which produces a container image with demonstration data already +loaded. This container image may be useful in cases where containers are frequency run and destroyed and the time +taken to load demo data is becoming noticeable. + +To build a container image pre-loaded with demo data, run: +```shell script +DOCKER_BUILDKIT=1 docker build --target demo --tag ofbiz-docker . +``` + +## Container runtime options + +The container's behaviour at runtime is controlled via environment variables, 'hook' scripts and XML entity import +files. These items will only be applied to a container during its first run. Flags stored in +`/ofbiz/runtime/container_state` will prevent the repeated application of these items during subsequent starts of the +container. + +Use of environment variables, hook scripts and XML entity import files are manged by the docker-entrypoint.sh script. + +### Environment variables +Environment variables are used in `docker-entrypoint.sh` to control configuration options for the OFBiz container. + +|Environment variable | Default value | Description | +|---|---|---| +|OFBIZ_SKIP_INIT | *empty* | Any non-empty value will cause the docker-entrypoint.sh script to skip any initialisation steps. | +|OFBIZ_ADMIN_USER | admin | Sets the username of the OFBIZ admin user. | +|OFBIZ_ADMIN_PASSWORD | ofbiz | Sets the password of the OFBIZ admin user. | +|OFBIZ_DATA_LOAD | seed | Determine what type of data loading is required. *none*: No data loading is perfomed. *seed*: Seed data is loaded. *demo*: Demo data is loaded. | +|OFBIZ_HOST | <empty> | Specify the hostname used to access OFBiz. If empty then the default value of host-headers-allowed from framework/security/config/security.properties is used. | +|OFBIZ_CONTENT_URL_PREFIX | <empty> | Used to set the content.url.prefix.secure and content.url.prefix.standard properties in `framework/webapp/config/url.properties`. | +|OFBIZ_ENABLE_AJP_PORT | *empty* | Enable the AJP (Apache JServe Protocol) port to allow communication with OFBiz via a reverse proxy. Enabled when this environment variable contains a non-empty value. | +|OFBIZ_SKIP_DB_DRIVER_DOWNLOAD | *empty* | Any non-empty value will cause the docker-entrypoint.sh script to skip downloading of any database drivers. | +|OFBIZ_DISABLE_COMPONENTS | plugins/birt/ofbiz-component.xml | Commas seperated list of paths to ofbiz-component.xml files of the components that should not be loaded. | + +### Hooks +At various steps of initialisation, the `docker-entrypoint.sh` script will check for +'hook' scripts in various directories. + +Users of the container can mount files into these directories and influence the OFBiz startup process. + +Only script files with filename extension `.sh` will be processed. If the file is executable, it will +be executed, otherwise it will be sourced. + +|Directory | Step | +|---|---| +| `/docker-entrypoint-hooks/before-config-applied.d` | Scripts processed before configuration, such as modifications to property files, are applied. | +| `/docker-entrypoint-hooks/after-config-applied.d` | Scripts processed after configuration modifications have been applied. | +| `/docker-entrypoint-hooks/before-data-load.d` | Scripts processed before data loading is executed. Could be used to apply modifications to data files.| +| `/docker-entrypoint-hooks/after-data-load.d` | Scripts processed after data loading is executed. | + +### Data files +During the data loading step - but after either seed or demo data has been loaded - directory +`/docker-entrypoint-hooks/additional-data.d` will be checked to see if any files are present. + +If files are present then the load-data functionality in OFBiz will be executed, specifying the +`/docker-entrypoint-additional-data.d` directory as a data source. Any `.xml` files in this +directory will be treated as a data source and will be imported by the entity engine. + +This functionality can be used to pre-load OFBiz with user-specific data, such as +a chart of accounts. + +### Database +By default the OFBiz container will use an internal Derby database, storing database related files +in the /ofbiz/runtime volume. + +Use of an external database can be configured through environment variables. + +#### Derby +To use the embedded Derby database, ensure all database related environment variables are unset. + +#### PostgreSQL +To use a Postgres database set the `OFBIZ_POSTGRES_HOST` environment variable. + +Environment variable | Default | Description +---|---|--- +OFBIZ_POSTGRES_HOST | *unset* | Hostname of the PostgreSQL database server. +OFBIZ_POSTGRES_OFBIZ_DB | ofbiz | Name of the *ofbiz* database. +OFBIZ_POSTGRES_OFBIZ_USER | ofbiz | Username when connecting to the ofbiz database. +OFBIZ_POSTGRES_OFBIZ_PASSWORD | ofbiz | Password when connecting to the ofbiz database. +OFBIZ_POSTGRES_OLAP_DB | ofbizolap | Name of the *olap* database. +OFBIZ_POSTGRES_OLAP_USER | ofbizolap | Username when connecting to the olap database. +OFBIZ_POSTGRES_OLAP_PASSWORD | ofbizolap | Password when connecting to the olap database. +OFBIZ_POSTGRES_TENANT_DB | ofbiztenant | Name of the *tenant* database. +OFBIZ_POSTGRES_TENANT_USER | ofbiztenant | Username when connecting to the tenant database. +OFBIZ_POSTGRES_TENANT_PASSWORD | ofbiztenant | Password when connecting to the tenant database. + +The docker-entrypoint.sh script will download a JDBC driver to access the PostgreSQL server and +place the script in the `/ofbiz/lib-extra` volume. If you wish to skip this step then set the +OFBIZ_SKIP_DB_DRIVER_DOWNLOAD environment variable to a non-empty value. This would be +useful if you have already placed a suitable database driver in the `/ofbiz/lib-extra` volume. + +## Examples of running the OFBiz container + +``` +docker run -it -p 8443:8443 ofbiz-docker +``` +Launch the OFBiz container, load the seed data, create the administrator user with +name `admin` and password `ofbiz`, listen on port 8443 for connections to `localhost`. + +Users can access OFBiz at https://localhost:8443/partymgr + +The docker container will remain attached the terminal. Interrupting the container, +i.e. pressing Ctrl-C, will trigger a graceful shutdown of the container. + +``` +docker run -it -e OFBIZ_DATA_LOAD=demo -p 8443:8443 ofbiz-docker +``` +Launch the OFBiz container, load the demo data, listen on port 8443 for connections to `localhost`. + +The demo data includes the administrator user with name `admin` and password `ofbiz`. + +``` +docker run -it -e OFBIZ_DATA_LOAD=seed -e OFBIZ_ADMIN_USER=localadmin -e OFBIZ_ADMIN_PASSWORD=TTTTT -p 8443:8443 ofbiz-docker +``` +Launch the OFBiz container, load the seed data, create the administrator user with +name `localadmin` and password `TTTTT`, listen on port 8443 for connections to `localhost`. + +``` +docker run -it -v 'C:\ofbiz-framework\add-data':/docker-entrypoint-additional-data.d -p 8443:8443 ofbiz-docker +``` +Example of running on Windows. + +Launches the container with default seed data and administrator user. + +After data is loaded, any `.xml` files in directory `C:\ofbiz-framework\add-data` are imported by +the OFBiz entity engine. + +``` +docker run -it -p 8443:8443 ofbiz-docker +``` +Launch the OFBiz container, load the seed data, create the administrator user with +name `admin` and password `ofbiz`, listen on port 8443 for connections to `localhost`. + +Users can access OFBiz at https://localhost:8443/partymgr + +The docker container will remain attached the terminal. Interrupting the container, +i.e. pressing Ctrl-C, will trigger a graceful shutdown of the container. + + +``` +docker run -it -e OFBIZ_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" -p 8443:8443 -p 5005:5005 ofbiz-docker +``` +Creates a debuggable instance of OFBiz, listening on port 5005. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..23d7470c7e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,128 @@ +# syntax=docker/dockerfile:1 +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +FROM eclipse-temurin:17 AS builder + +# Git is used for various OFBiz build tasks. +RUN apt-get update \ + && apt-get install -y --no-install-recommends git \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /builder + +# Add and run the gradle wrapper to trigger a download if needed. +COPY --chmod=755 gradle/init-gradle-wrapper.sh gradle/ +COPY --chmod=755 gradlew . +RUN ["sed", "-i", "s/shasum/sha1sum/g", "gradle/init-gradle-wrapper.sh"] +RUN ["gradle/init-gradle-wrapper.sh"] + +# Run gradlew to trigger downloading of the gradle distribution (if needed) +RUN --mount=type=cache,id=gradle-cache,sharing=locked,target=/root/.gradle \ + ["./gradlew", "--console", "plain"] + +# Copy all OFBiz sources. +COPY applications/ applications/ +COPY config/ config/ +COPY framework/ framework/ +COPY gradle/ gradle/ +COPY lib/ lib/ +# We use a regex to match the plugins directory to avoid a build error when the directory doesn't exist. +COPY plugin[s]/ plugins/ +COPY themes/ themes/ +COPY APACHE2_HEADER build.gradle common.gradle gradle.properties NOTICE settings.gradle . + +# Build OFBiz while mounting a gradle cache +RUN --mount=type=cache,id=gradle-cache,sharing=locked,target=/root/.gradle \ + --mount=type=tmpfs,target=runtime/tmp \ + ["./gradlew", "--console", "plain", "distTar"] + +################################################################################### + +FROM eclipse-temurin:17 AS runtimebase + +# xsltproc is used to disable OFBiz components during first run. +RUN apt-get update \ + && apt-get install -y --no-install-recommends xsltproc \ + && rm -rf /var/lib/apt/lists/* + +RUN ["useradd", "ofbiz"] + +# Create directories used to mount volumes where hooks into the startup process can be placed. +RUN ["mkdir", "--parents", \ + "/docker-entrypoint-hooks/before-config-applied.d", \ + "/docker-entrypoint-hooks/after-config-applied.d", \ + "/docker-entrypoint-hooks/before-data-load.d", \ + "/docker-entrypoint-hooks/after-data-load.d", \ + "/docker-entrypoint-hooks/additional-data.d"] +RUN ["/usr/bin/chown", "-R", "ofbiz:ofbiz", "/docker-entrypoint-hooks" ] + +USER ofbiz +WORKDIR /ofbiz + +# Extract the OFBiz tar distribution created by the builder stage. +RUN --mount=type=bind,from=builder,source=/builder/build/distributions/ofbiz.tar,target=/mnt/ofbiz.tar \ + ["tar", "--extract", "--strip-components=1", "--file=/mnt/ofbiz.tar"] + +# Create directories for OFBiz volume mountpoints. +RUN ["mkdir", "/ofbiz/runtime", "/ofbiz/config", "/ofbiz/lib-extra"] + +# Append the java runtime version to the OFBiz VERSION file. +COPY --chmod=644 --chown=ofbiz:ofbiz VERSION . +RUN echo '${uiLabelMap.CommonJavaVersion}:' "$(java --version | grep Runtime | sed 's/.*Runtime Environment //; s/ (build.*//;')" >> /ofbiz/VERSION + +# Leave executable scripts owned by root and non-writable, addressing sonarcloud rule, +# https://sonarcloud.io/organizations/apache/rules?open=docker%3AS6504&rule_key=docker%3AS6504 +COPY --chmod=555 docker/docker-entrypoint.sh docker/send_ofbiz_stop_signal.sh . + +COPY --chmod=444 docker/disable-component.xslt . +COPY --chmod=444 docker/templates templates + +EXPOSE 8443 +EXPOSE 8009 +EXPOSE 5005 + +ENTRYPOINT ["/ofbiz/docker-entrypoint.sh"] +CMD ["bin/ofbiz"] + +################################################################################### +# Load demo data before defining volumes. This results in a container image +# that is ready to go for demo purposes. +FROM runtimebase AS demo + +USER ofbiz + +RUN /ofbiz/bin/ofbiz --load-data +RUN mkdir --parents /ofbiz/runtime/container_state +RUN touch /ofbiz/runtime/container_state/data_loaded +RUN touch /ofbiz/runtime/container_state/admin_loaded +RUN touch /ofbiz/runtime/container_state/db_config_applied + +VOLUME ["/docker-entrypoint-hooks"] +VOLUME ["/ofbiz/config", "/ofbiz/runtime", "/ofbiz/lib-extra"] + + +################################################################################### +# Runtime image with no data loaded. +FROM runtimebase AS runtime + +USER ofbiz + +VOLUME ["/docker-entrypoint-hooks"] +VOLUME ["/ofbiz/config", "/ofbiz/runtime", "/ofbiz/lib-extra"] diff --git a/build.gradle b/build.gradle index 4b1f6b4d87..e4a52406a4 100644 --- a/build.gradle +++ b/build.gradle @@ -125,6 +125,14 @@ node { npmInstallCommand = System.getenv("CI") ? 'ci' : 'install' } +tasks.getByName("distTar") { + dependsOn "npmInstall" +} + +tasks.getByName("distZip") { + dependsOn "npmInstall" +} + java { sourceCompatibility(JavaVersion.VERSION_17) targetCompatibility(JavaVersion.VERSION_17) diff --git a/docker/disable-component.xslt b/docker/disable-component.xslt new file mode 100644 index 0000000000..04e926ba09 --- /dev/null +++ b/docker/disable-component.xslt @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + +http://www.apache.org/licenses/LICENSE-2.0 + +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. +--> + +<!-- + Copy all attributes and elements of the root ofbiz-component element in an XML document, changing the enabled + attribute to false. +--> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="/"> + <xsl:element name="ofbiz-component"> + <xsl:copy-of select="ofbiz-component/@*"/> + <xsl:attribute name="enabled">false</xsl:attribute> + <xsl:copy-of select="ofbiz-component/node()"/> + </xsl:element> + </xsl:template> +</xsl:stylesheet> diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 0000000000..baa1536c94 --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,392 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +############################################################################### + +############################################################################### +# OFBiz initialisation script for use as the entry point in a docker container. +# +# Triggers the loading of data and configuration of various OFBiz properties before +# executing the command given as arguments to the script. +# +# +# Behaviour controlled by environment variables: +# +# OFBIZ_SKIP_INIT +# Any non-empty value will cause this script to skip any initialisation steps. +# Default: <empty> +# +# OFBIZ_ADMIN_USER +# The username of the OFBIZ admin user. +# Default: admin +# +# OFBIZ_ADMIN_PASSWORD +# The password of the OFBIZ admin user. +# Default: ofbiz +# +# OFBIZ_DATA_LOAD +# Determine what type of data loading is required. +# Default: seed +# Values: +# - none: No data loading is performed. +# - seed: Seed data is loaded. +# - demo: Demo data is loaded. +# +# OFBIZ_HOST +# Specify the hostname used to access OFBiz. +# Used to populate the host-headers-allowed property in framework/security/config/security.properties. +# Default: default value of host-headers-allowed from framework/security/config/security.properties. +# +# OFBIZ_CONTENT_URL_PREFIX +# Used to set the content.url.prefix.secure and content.url.prefix.standard properties in +# framework/webapp/config/url.properties. +# Default: <empty> +# +# OFBIZ_ENABLE_AJP_PORT +# Enable the AJP (Apache JServe Protocol) port to allow communication with OFBiz via a reverse proxy. +# Enabled when this environment variable contains a non-empty value. +# Default value: <empty> +# +# OFBIZ_SKIP_DB_DRIVER_DOWNLOAD +# When connecting to databases other than the OFBiz embedded Derby database a suitable driver will be needed. +# This script will attempt to download a suitable driver unless the OFBIZ_SKIP_DB_DRIVER_DOWNLOAD contains a non-empty +# value. +# +# OFBIZ_POSTGRES_HOST +# Sets the name of the PostgreSQL database host. +# If OFBIZ_POSTGRES_HOST is non-empty, then the following OFBIZ_POSTGRES_* environment variables are used to configure +# access to PostgreSQL databases. +# OFBIZ_POSTGRES_OFBIZ_DB Default: ofbiz +# OFBIZ_POSTGRES_OFBIZ_USER Default: ofbiz +# OFBIZ_POSTGRES_OFBIZ_PASSWORD Default: ofbiz +# OFBIZ_POSTGRES_OLAP_DB Default: ofbizolap +# OFBIZ_POSTGRES_OLAP_USER Default: ofbizolap +# OFBIZ_POSTGRES_OLAP_PASSWORD Default: ofbizolap +# OFBIZ_POSTGRES_TENANT_DB Default: ofbiztenant +# OFBIZ_POSTGRES_TENANT_USER Default: ofbiztenant +# OFBIZ_POSTGRES_TENANT_PASSWORD Default: ofbiztenant +# +# OFBIZ_DISABLE_COMPONENTS +# Prevents loading of ofbiz-components. +# Contains a comma separated list of relative paths from the ofbiz sources directory to the ofbiz-component.xml files +# that should be prevented from loading. +# Default: plugins/birt/ofbiz-component.xml +# +# Hooks are executed at the various stages of the initialisation process by executing scripts in the following +# directories. Scripts must be executable and have the .sh extension: +# +# /docker-entrypoint-hooks/before-config-applied.d +# Executed before any changes are applied to the OFBiz configuration files. +# +# /docker-entrypoint-hooks/after-config-applied.d +# Executed after any changes are applied to the OFBiz configuration files. +# +# /docker-entrypoint-hooks/before-data-load.d +# Executed before any data loading is about to be performed. Only executed if data loading is required. +# Example usage would be to alter the data to be loaded. +# +# /docker-entrypoint-hooks/additional-data.d +# Any data files (.xml files) in this directory are loaded after seed/demo data. +# +# /docker-entrypoint-hooks/after-data-load.d +# Executed after any data loading has been performed. Only executed if data loading was required. +# +############################################################################### +set -x +set -e + +trap shutdown_ofbiz SIGTERM SIGINT + +CONTAINER_STATE_DIR="/ofbiz/runtime/container_state" +CONTAINER_DATA_LOADED="$CONTAINER_STATE_DIR/data_loaded" +CONTAINER_ADMIN_LOADED="$CONTAINER_STATE_DIR/admin_loaded" +CONTAINER_CONFIG_APPLIED="$CONTAINER_STATE_DIR/config_applied" +CONTAINER_DB_CONFIG_APPLIED="$CONTAINER_STATE_DIR/db_config_applied" + +POSTGRES_DRIVER_URL="https://jdbc.postgresql.org/download/postgresql-42.5.4.jar" + +############################################################################### +# Validate and apply defaults to any environment variables used by this script. +# See script header for environment variable descriptions. +ofbiz_setup_env() { + case "$OFBIZ_DATA_LOAD" in + none | seed | demo) ;; + *) + OFBIZ_DATA_LOAD="seed" + ;; + esac + + OFBIZ_ADMIN_USER=${OFBIZ_ADMIN_USER:-admin} + + OFBIZ_ADMIN_PASSWORD=${OFBIZ_ADMIN_PASSWORD:-ofbiz} + + OFBIZ_POSTGRES_OFBIZ_DB=${OFBIZ_POSTGRES_OFBIZ_DB:-ofbiz} + OFBIZ_POSTGRES_OFBIZ_USER=${OFBIZ_POSTGRES_OFBIZ_USER:-ofbiz} + OFBIZ_POSTGRES_OFBIZ_PASSWORD=${OFBIZ_POSTGRES_OFBIZ_PASSWORD:-ofbiz} + + OFBIZ_POSTGRES_OLAP_DB=${OFBIZ_POSTGRES_OLAP_DB:-ofbizolap} + OFBIZ_POSTGRES_OLAP_USER=${OFBIZ_POSTGRES_OLAP_USER:-ofbizolap} + OFBIZ_POSTGRES_OLAP_PASSWORD=${OFBIZ_POSTGRES_OLAP_PASSWORD:-ofbizolap} + + OFBIZ_POSTGRES_TENANT_DB=${OFBIZ_POSTGRES_TENANT_DB:-ofbiztenant} + OFBIZ_POSTGRES_TENANT_USER=${OFBIZ_POSTGRES_TENANT_USER:-ofbiztenant} + OFBIZ_POSTGRES_TENANT_PASSWORD=${OFBIZ_POSTGRES_TENANT_PASSWORD:-ofbiztenant} + + OFBIZ_DISABLE_COMPONENTS=${OFBIZ_DISABLE_COMPONENTS-plugins/birt/ofbiz-component.xml} +} + +############################################################################### +# Create the runtime container state directory used to track which initialisation +# steps have been run for the container. +# This directory should be hosted on a volume that persists for the life of the container. +create_ofbiz_runtime_directories() { + if [ ! -d "$CONTAINER_STATE_DIR" ]; then + mkdir --parents "$CONTAINER_STATE_DIR" + fi +} + +############################################################################### +# Execute the shell scripts at the paths passed to this function. +# Args: +# 1: Name of the hook stage being executed. Used for logging. +# 2+: Variable number of paths to the shell scripts to be executed. +# Only scripts with the .sh extension are executed. +# Scripts will be sourced if they are not executable. +run_init_hooks() { + local hookStage="$1" + shift + local filePath + for filePath; do + case "$filePath" in + *.sh) + if [ -x "$filePath" ]; then + printf '%s: running %s\n' "$hookStage" "$filePath" + "$filePath" + else + printf '%s: sourcing %s\n' "$hookStage" "$filePath" + . "$filePath" + fi + ;; + *) + printf '%s: Not a script. Ignoring %s\n' "$hookStage" "$filePath" + ;; + esac + done +} + +############################################################################### +# If required, load data into OFBiz. +load_data() { + if [ ! -f "$CONTAINER_DATA_LOADED" ]; then + run_init_hooks before-data-load /docker-entrypoint-hooks/before-data-load.d/* + + case "$OFBIZ_DATA_LOAD" in + none) ;; + + seed) + /ofbiz/bin/ofbiz --load-data readers=seed,seed-initial + ;; + + demo) + /ofbiz/bin/ofbiz --load-data + # Demo data includes the admin user so indicate that the user is already loaded. + touch "$CONTAINER_ADMIN_LOADED" + ;; + esac + + # Load any additional data files provided. + if [ -z $(find /docker-entrypoint-hooks/additional-data.d/ -prune -empty) ]; then + /ofbiz/bin/ofbiz --load-data dir=/docker-entrypoint-hooks/additional-data.d + fi + + touch "$CONTAINER_DATA_LOADED" + + run_init_hooks after-data-load /docker-entrypoint-hooks/after-data-load.d/* + fi +} + +############################################################################### +# Create and load the password hash for the admin user. +load_admin_user() { + if [ ! -f "$CONTAINER_ADMIN_LOADED" ]; then + TMPFILE=$(mktemp) + + # Concatenate a random salt and the admin password. + SALT=$(tr --delete --complement A-Za-z0-9 </dev/urandom | head --bytes=16) + SALT_AND_PASSWORD="${SALT}${OFBIZ_ADMIN_PASSWORD}" + + # Take a SHA-1 hash of the combined salt and password and strip off any additional output form the sha1sum utility. + SHA1SUM_ASCII_HEX=$(printf "$SALT_AND_PASSWORD" | sha1sum | cut --delimiter=' ' --fields=1 --zero-terminated | tr --delete '\000') + + # Convert the ASCII Hex representation of the hash to raw bytes by inserting escape sequences and running + # through the printf command. Encode the result as URL base 64 and remove padding. + SHA1SUM_ESCAPED_STRING=$(printf "$SHA1SUM_ASCII_HEX" | sed -e 's/\(..\)\.\?/\\x\1/g') + SHA1SUM_BASE64=$(printf "$SHA1SUM_ESCAPED_STRING" | basenc --base64url --wrap=0 | tr --delete '=') + + # Concatenate the hash type, salt and hash as the encoded password value. + ENCODED_PASSWORD_HASH="\$SHA\$${SALT}\$${SHA1SUM_BASE64}" + + # Populate the login data template + sed "s/@userLoginId@/$OFBIZ_ADMIN_USER/g; s/currentPassword=\".*\"/currentPassword=\"$ENCODED_PASSWORD_HASH\"/g;" framework/resources/templates/AdminUserLoginData.xml >"$TMPFILE" + + # Load data from the populated template. + /ofbiz/bin/ofbiz --load-data "file=$TMPFILE" + + rm "$TMPFILE" + + touch "$CONTAINER_ADMIN_LOADED" + fi +} + +############################################################################### +# Modify the given ofbiz-component configuration XML file to set the root +# component's 'enabled' attribute to false. +# $1 - Path to the XML file to be modified. +disable_component() { + XML_FILE="/ofbiz/$1" + if [ -f "$XML_FILE" ]; then + TMPFILE=$(mktemp) + + xsltproc /ofbiz/disable-component.xslt "$XML_FILE" > "$TMPFILE" + mv "$TMPFILE" "$XML_FILE" + else + echo "Cannot find ofbiz-component configuration file. Not disabling component: $XML_FILE" + fi +} + +############################################################################### +# Modify the given ofbiz-component configuration XML files to set their root +# components' 'enabled' attribute to false. +# $1 - Comma separated list of paths to configuration XML files to be modified. +disable_components() { + COMMA_SEPARATED_PATHS="$1" + + if [ -n "$COMMA_SEPARATED_PATHS" ]; then + + # Split the comma separated paths into separate arguments. + IFS=, + set "$COMMA_SEPARATED_PATHS" + + while [ -n "$1" ]; do + disable_component "$1" + shift + done + fi +} + +############################################################################### +# Apply any configuration changes required. +# Changed property files need to be placed in /ofbiz/config so they appear earlier +# in the classpath and override the build-time copies of the properties in ofbiz.jar. +apply_configuration() { + if [ ! -f "$CONTAINER_CONFIG_APPLIED" ]; then + run_init_hooks before-config-applied /docker-entrypoint-hooks/before-config-applied.d/* + + if [ -n "$OFBIZ_ENABLE_AJP_PORT" ]; then + # Configure tomcat to listen for AJP connections on all interfaces within the container. + sed --in-place \ + '/<property name="ajp-connector" value="connector">/ a <property name="address" value="0.0.0.0"/>' \ + /ofbiz/framework/catalina/ofbiz-component.xml + fi + + if [ -n "$OFBIZ_HOST" ]; then + sed "s/host-headers-allowed=.*/host-headers-allowed=${OFBIZ_HOST}/" \ + framework/security/config/security.properties >config/security.properties + fi + + if [ -n "$OFBIZ_CONTENT_URL_PREFIX" ]; then + sed \ + --expression="s#content.url.prefix.secure=.*#content.url.prefix.secure=${OFBIZ_CONTENT_URL_PREFIX}#;" \ + --expression="s#content.url.prefix.standard=.*#content.url.prefix.standard=${OFBIZ_CONTENT_URL_PREFIX}#;" \ + framework/webapp/config/url.properties >config/url.properties + fi + + if [ -n "$OFBIZ_DISABLE_COMPONENTS" ]; then + disable_component "$OFBIZ_DISABLE_COMPONENTS" + fi + + touch "$CONTAINER_CONFIG_APPLIED" + run_init_hooks after-config-applied /docker-entrypoint-hooks/after-config-applied.d/* + fi +} + +############################################################################### +# Set up the connection to the OFBiz database. +configure_database() { + if [ ! -f "$CONTAINER_DB_CONFIG_APPLIED" ]; then + if [ -n "$OFBIZ_POSTGRES_HOST" ]; then + sed \ + --expression="s/@HOST@/$OFBIZ_POSTGRES_HOST/;" \ + --expression="s/@OFBIZ_DB@/$OFBIZ_POSTGRES_OFBIZ_DB/;" \ + --expression="s/@OFBIZ_USERNAME@/$OFBIZ_POSTGRES_OFBIZ_USER/;" \ + --expression="s/@OFBIZ_PASSWORD@/$OFBIZ_POSTGRES_OFBIZ_PASSWORD/;" \ + --expression="s/@OLAP_DB@/$OFBIZ_POSTGRES_OLAP_DB/;" \ + --expression="s/@OLAP_USERNAME@/$OFBIZ_POSTGRES_OLAP_USER/;" \ + --expression="s/@OLAP_PASSWORD@/$OFBIZ_POSTGRES_OLAP_PASSWORD/;" \ + --expression="s/@TENANT_DB@/$OFBIZ_POSTGRES_TENANT_DB/;" \ + --expression="s/@TENANT_USERNAME@/$OFBIZ_POSTGRES_TENANT_USER/;" \ + --expression="s/@TENANT_PASSWORD@/$OFBIZ_POSTGRES_TENANT_PASSWORD/;" \ + templates/postgres-entityengine.xml > config/entityengine.xml + + if [ -z "$OFBIZ_SKIP_DB_DRIVER_DOWNLOAD" ]; then + echo "Retrieving PostgreSQL driver from $POSTGRES_DRIVER_URL" + wget --verbose --directory-prefix=lib-extra "$POSTGRES_DRIVER_URL" + fi + fi + + touch "$CONTAINER_DB_CONFIG_APPLIED" + fi +} + +############################################################################### +# Send a shutdown signal to OFBiz +shutdown_ofbiz() { + /ofbiz/send_ofbiz_stop_signal.sh +} + +_main() { + if [ -z "$OFBIZ_SKIP_INIT" ]; then + ofbiz_setup_env + create_ofbiz_runtime_directories + configure_database + apply_configuration + load_data + load_admin_user + fi + + unset OFBIZ_SKIP_INIT + unset OFBIZ_ADMIN_USER + unset OFBIZ_ADMIN_PASSWORD + unset OFBIZ_DATA_LOAD + unset OFBIZ_ENABLE_AJP_PORT + unset OFBIZ_HOST + unset OFBIZ_CONTENT_URL_PREFIX + unset OFBIZ_POSTGRES_OFBIZ_DB + unset OFBIZ_POSTGRES_OFBIZ_USER + unset OFBIZ_POSTGRES_OFBIZ_PASSWORD + unset OFBIZ_POSTGRES_OLAP_DB + unset OFBIZ_POSTGRES_OLAP_USER + unset OFBIZ_POSTGRES_OLAP_PASSWORD + unset OFBIZ_POSTGRES_TENANT_DB + unset OFBIZ_POSTGRES_TENANT_USER + unset OFBIZ_POSTGRES_TENANT_PASSWORD + + # Continue loading OFBiz. + exec "$@" +} + +_main "$@" diff --git a/docker/examples/postgres-demo/after-config-applied.d/applySolrConfig.sh b/docker/examples/postgres-demo/after-config-applied.d/applySolrConfig.sh new file mode 100644 index 0000000000..71c891dfdb --- /dev/null +++ b/docker/examples/postgres-demo/after-config-applied.d/applySolrConfig.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +set -x + +if [ -d /ofbiz/plugins/solr ]; then + sed "s/^solr.webapp.domainName=.*/solr.webapp.domainName=${OFBIZ_HOST}/" \ + /ofbiz/plugins/solr/config/solrconfig.properties > /ofbiz/config/solrconfig.properties +fi diff --git a/docker/examples/postgres-demo/docker-compose.yml b/docker/examples/postgres-demo/docker-compose.yml new file mode 100644 index 0000000000..fcafaaf788 --- /dev/null +++ b/docker/examples/postgres-demo/docker-compose.yml @@ -0,0 +1,49 @@ +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +version: "2.4" + +services: + db: + image: postgres:13 + mem_limit: 300M + memswap_limit: 300M + cpu_shares: 200 + restart: "no" + volumes: + - ./postgres-initdb.d:/docker-entrypoint-initdb.d + env_file: + - postgres.env + - ofbiz-postgres.env + + ofbiz: + image: ofbiz-docker:release22.01-snapshot + mem_limit: 2400M + memswap_limit: 2400M + cpu_shares: 200 + ports: + - 8443:8443 + volumes: + - ./after-config-applied.d:/docker-entrypoint-hooks/after-config-applied.d + env_file: + - ofbiz-postgres.env + environment: + OFBIZ_DATA_LOAD: demo + OFBIZ_HOST: example.internal + OFBIZ_CONTENT_URL_PREFIX: https://example.internal:8443 diff --git a/docker/examples/postgres-demo/ofbiz-postgres.env b/docker/examples/postgres-demo/ofbiz-postgres.env new file mode 100644 index 0000000000..ebe1e567cb --- /dev/null +++ b/docker/examples/postgres-demo/ofbiz-postgres.env @@ -0,0 +1,32 @@ +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +OFBIZ_POSTGRES_HOST=db + +OFBIZ_POSTGRES_OFBIZ_DB=ofbizmaindb +OFBIZ_POSTGRES_OFBIZ_USER=ofbiz +OFBIZ_POSTGRES_OFBIZ_PASSWORD="Ab6SqDD2YM2lmEsvao-" + +OFBIZ_POSTGRES_OLAP_DB=ofbizolapdb +OFBIZ_POSTGRES_OLAP_USER=ofbizolap +OFBIZ_POSTGRES_OLAP_PASSWORD="P7TFUtQHSuvha8gSxMME" + +OFBIZ_POSTGRES_TENANT_DB=ofbiztenantdb +OFBIZ_POSTGRES_TENANT_USER=ofbiztenant +OFBIZ_POSTGRES_TENANT_PASSWORD="4oXET73QGriblUejjbvR" diff --git a/docker/examples/postgres-demo/postgres-initdb.d/10-init-user-db.sh b/docker/examples/postgres-demo/postgres-initdb.d/10-init-user-db.sh new file mode 100644 index 0000000000..d3130c15ed --- /dev/null +++ b/docker/examples/postgres-demo/postgres-initdb.d/10-init-user-db.sh @@ -0,0 +1,35 @@ +#!/bin/bash +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +set -e + +psql -v ON_ERROR_STOP=1 --username "postgres" --dbname "postgres" <<-EOSQL + CREATE USER $OFBIZ_POSTGRES_OFBIZ_USER WITH PASSWORD '$OFBIZ_POSTGRES_OFBIZ_PASSWORD'; + CREATE DATABASE $OFBIZ_POSTGRES_OFBIZ_DB; + GRANT ALL PRIVILEGES ON DATABASE $OFBIZ_POSTGRES_OFBIZ_DB TO $OFBIZ_POSTGRES_OFBIZ_USER; + + CREATE USER $OFBIZ_POSTGRES_OLAP_USER WITH PASSWORD '$OFBIZ_POSTGRES_OLAP_PASSWORD'; + CREATE DATABASE $OFBIZ_POSTGRES_OLAP_DB; + GRANT ALL PRIVILEGES ON DATABASE $OFBIZ_POSTGRES_OLAP_DB TO $OFBIZ_POSTGRES_OLAP_USER; + + CREATE USER $OFBIZ_POSTGRES_TENANT_USER WITH PASSWORD '$OFBIZ_POSTGRES_TENANT_PASSWORD'; + CREATE DATABASE $OFBIZ_POSTGRES_TENANT_DB; + GRANT ALL PRIVILEGES ON DATABASE $OFBIZ_POSTGRES_TENANT_DB TO $OFBIZ_POSTGRES_TENANT_USER; +EOSQL diff --git a/docker/examples/postgres-demo/postgres.env b/docker/examples/postgres-demo/postgres.env new file mode 100644 index 0000000000..86924ae3b2 --- /dev/null +++ b/docker/examples/postgres-demo/postgres.env @@ -0,0 +1,21 @@ +##################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +##################################################################### + +# Mandatory environment variable to set the password of the postgres superuser. +POSTGRES_PASSWORD="20wganpfDASBtBXY7GQ6" \ No newline at end of file diff --git a/docker/send_ofbiz_stop_signal.sh b/docker/send_ofbiz_stop_signal.sh new file mode 100755 index 0000000000..6a15c120c2 --- /dev/null +++ b/docker/send_ofbiz_stop_signal.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +############################################################################### + +set -e + +# Read a property value. Assumes all properties are single line and do not have spaces around the '=' sign or comments following the valuel. +function getPropertyValue +{ + echo "$1" | sed "/^$2=/!d; s///" +} + +echo "Getting admin port and key..." +START_PROPERTIES_CONTENT=$(cat /ofbiz/framework/start/src/main/resources/org/apache/ofbiz/base/start/start.properties) + +OFBIZ_ADMIN_PORT=$(getPropertyValue "$START_PROPERTIES_CONTENT" "ofbiz.admin.port") +echo Admin port: $OFBIZ_ADMIN_PORT; + +OFBIZ_ADMIN_KEY=$(getPropertyValue "$START_PROPERTIES_CONTENT" "ofbiz.admin.key") +echo Admin key: $OFBIZ_ADMIN_KEY; + +echo "Sending shutdown signal..." +echo "$OFBIZ_ADMIN_KEY:SHUTDOWN" | curl telnet://localhost:$OFBIZ_ADMIN_PORT +echo "Done" diff --git a/docker/templates/postgres-entityengine.xml b/docker/templates/postgres-entityengine.xml new file mode 100644 index 0000000000..b9485c3407 --- /dev/null +++ b/docker/templates/postgres-entityengine.xml @@ -0,0 +1,176 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + +http://www.apache.org/licenses/LICENSE-2.0 + +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. +--> +<!-- + - This file configures the Entity Engine JDBC (or other DataSource) and JTA +access. For a detailed description see the core/docs/entityconfig.html file. +--> +<entity-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://ofbiz.apache.org/dtds/entity-config.xsd"> + <resource-loader name="fieldfile" class="org.apache.ofbiz.base.config.FileLoader" + prepend-env="ofbiz.home" prefix="/framework/entity/fieldtype/"/> + + <!-- the transaction factory class to use, one is needed for each way of getting JTA interfaces --> + <!-- Use this one for Geronimo --> + <transaction-factory class="org.apache.ofbiz.entity.transaction.GeronimoTransactionFactory"/> + + <!-- the connection factory class to use, one is needed for obtaining connections/pools for defined resources --> + <connection-factory class="org.apache.ofbiz.entity.connection.DBCPConnectionFactory"/> + + <debug-xa-resources value="false" /> <!-- see https://issues.apache.org/jira/browse/OFBIZ-4282 for more --> + + <delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" distributed-cache-clear-enabled="false"> + <group-map group-name="org.apache.ofbiz" datasource-name="localpostgres"/> + <group-map group-name="org.apache.ofbiz.olap" datasource-name="localpostgresolap"/> + <group-map group-name="org.apache.ofbiz.tenant" datasource-name="localpostgrestenant"/> + </delegator> + + <!-- May be used when you create a service that manages many data for massive imports, this for performance reason or to escape functional cases --> + <delegator name="default-no-eca" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" entity-eca-enabled="false" distributed-cache-clear-enabled="false"> + <group-map group-name="org.apache.ofbiz" datasource-name="localpostgres"/> + <group-map group-name="org.apache.ofbiz.olap" datasource-name="localpostgresolap"/> + <group-map group-name="org.apache.ofbiz.tenant" datasource-name="localpostgrestenant"/> + </delegator> + + <!-- Be sure that your default delegator (or the one you use) uses the same datasource for test. You must run "gradlew loadAll" before running "gradlew testIntegration" --> + <delegator name="test" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main"> + <group-map group-name="org.apache.ofbiz" datasource-name="localderby"/> + <group-map group-name="org.apache.ofbiz.olap" datasource-name="localpostgresolap"/> + <group-map group-name="org.apache.ofbiz.tenant" datasource-name="localpostgrestenant"/> + </delegator> + + + <!-- need to at least define a name for each component to use --> + <entity-model-reader name="main"/> + + <!-- need to at least define a name for each component to use --> + <entity-group-reader name="main"/> + + <!-- need to at least define a name for each component to use --> + <entity-eca-reader name="main"/> + + <!-- need to at least define a name for each component to use --> + <entity-data-reader name="tenant"/> + <entity-data-reader name="seed"/> + <entity-data-reader name="seed-initial"/> + <entity-data-reader name="demo"/> + <entity-data-reader name="ext"/> + <entity-data-reader name="ext-test"/> + <entity-data-reader name="ext-demo"/> + + <field-type name="postgres" loader="fieldfile" location="fieldtypepostgres.xml"/> + + <datasource name="localpostgres" + helper-class="org.apache.ofbiz.entity.datasource.GenericHelperDAO" + schema-name="public" + field-type-name="postgres" + check-on-start="true" + add-missing-on-start="true" + use-fk-initially-deferred="false" + alias-view-columns="false" + join-style="ansi" + use-binary-type-for-blob="true" + use-order-by-nulls="true" + offset-style="limit" + result-fetch-size="50"> <!-- Comment out the result-fetch-size attribute for jdbc driver versions older than 8.0. + Not recommended to use those though. They are archived unsupported versions: http://jdbc.postgresql.org/download.html --> + + <read-data reader-name="tenant"/> + <read-data reader-name="seed"/> + <read-data reader-name="seed-initial"/> + <read-data reader-name="demo"/> + <read-data reader-name="ext"/> + <read-data reader-name="ext-test"/> + <read-data reader-name="ext-demo"/> + <inline-jdbc + jdbc-driver="org.postgresql.Driver" + jdbc-uri="jdbc:postgresql://@HOST@/@OFBIZ_DB@" + jdbc-username="@OFBIZ_USERNAME@" + jdbc-password="@OFBIZ_PASSWORD@" + isolation-level="ReadCommitted" + pool-minsize="2" + pool-maxsize="250" + time-between-eviction-runs-millis="600000"/><!-- Be warned that at this date (2009-09-20) the max_connections parameters in postgresql.conf + is set by default to 100 by the initdb process see http://www.postgresql.org/docs/8.4/static/runtime-config-connection.html#GUC-MAX-CONNECTIONS--> + </datasource> + + <datasource name="localpostgresolap" + helper-class="org.apache.ofbiz.entity.datasource.GenericHelperDAO" + schema-name="public" + field-type-name="postgres" + check-on-start="true" + add-missing-on-start="true" + use-fk-initially-deferred="false" + alias-view-columns="false" + join-style="ansi" + result-fetch-size="50" + use-binary-type-for-blob="true" + use-order-by-nulls="true" + offset-style="limit"> + <read-data reader-name="tenant"/> + <read-data reader-name="seed"/> + <read-data reader-name="seed-initial"/> + <read-data reader-name="demo"/> + <read-data reader-name="ext"/> + <read-data reader-name="ext-test"/> + <read-data reader-name="ext-demo"/> + <inline-jdbc + jdbc-driver="org.postgresql.Driver" + jdbc-uri="jdbc:postgresql://@HOST@/@OLAP_DB@" + jdbc-username="@OLAP_USERNAME@" + jdbc-password="@OLAP_PASSWORD@" + isolation-level="ReadCommitted" + pool-minsize="2" + pool-maxsize="250" + time-between-eviction-runs-millis="600000"/><!-- Be warned that at this date (2009-09-20) the max_connections parameters in postgresql.conf + is set by default to 100 by the initdb process see http://www.postgresql.org/docs/8.4/static/runtime-config-connection.html#GUC-MAX-CONNECTIONS--> + </datasource> + + <datasource name="localpostgrestenant" + helper-class="org.apache.ofbiz.entity.datasource.GenericHelperDAO" + schema-name="public" + field-type-name="postgres" + check-on-start="true" + add-missing-on-start="true" + use-fk-initially-deferred="false" + alias-view-columns="false" + join-style="ansi" + result-fetch-size="50" + use-binary-type-for-blob="true" + use-order-by-nulls="true" + offset-style="limit"> + <read-data reader-name="tenant"/> + <read-data reader-name="seed"/> + <read-data reader-name="seed-initial"/> + <read-data reader-name="demo"/> + <read-data reader-name="ext"/> + <read-data reader-name="ext-test"/> + <read-data reader-name="ext-demo"/> + <inline-jdbc + jdbc-driver="org.postgresql.Driver" + jdbc-uri="jdbc:postgresql://@HOST@/@TENANT_DB@" + jdbc-username="@TENANT_USERNAME@" + jdbc-password="@TENANT_PASSWORD@" + isolation-level="ReadCommitted" + pool-minsize="2" + pool-maxsize="250" + time-between-eviction-runs-millis="600000"/><!-- Be warned that at this date (2009-09-20) the max_connections parameters in postgresql.conf + is set by default to 100 by the initdb process see http://www.postgresql.org/docs/8.4/static/runtime-config-connection.html#GUC-MAX-CONNECTIONS--> + </datasource> +</entity-config>