Oracle Essbase on Docker: What, How, Why

I am very pleased to announce the availability of the new open source docker-essbase project to use Essbase with Docker. I have been working with Docker over the last couple of years and have found it to be a very compelling technology. I gave a presentation on Docker & Essbase, and this year I will be presenting Docker & Essbase at Collaborate19 in April and at Kscope19 in June.

The docker-essbase project is an open source project licensed under the very friendly MIT open source license. You are free to use, copy, and modify the files in this project.

First of all, a little background on Docker: Docker is a “container” technology. You’re most likely already familiar with virtual machines that emulate an entire operating system. You can think of Docker as a virtual machine for a single application. If you’ve ever worked with VMs then you might see some immediate appeal in this approach. When I first came into contact with Docker, Essbase immediately came to mind as a use case because of all of the quirks I’ve experienced using Essbase VMs.

What are those quirks? Here are a few:

  • Large image size: My Essbase VMs tend to weigh in at 40-80GB, depending on what all is installed.
  • Difficulties starting up services: When moving between networks, such as from home to a client network to the coffee shop or wherever, I frequently run into networking issues that are hard to troubleshoot and usually resolved by restarting the entire VM (and hoping for the best).
  • Tendency to destabilize over time: Typically Essbase VMs are used to develop and test ideas and often that means tweaking Sample/Basic or creating a bunch of one-off cubes/scripts.
  • Not much in the way of convenience features: Sometimes running MaxL scripts is a chore because the MaxL command isn’t on the system path, and other little one-off things that generally weren’t set or set properly.

Some of these issues can be mitigated by simply creating a snapshot of your virtual machine that you can revert back to. But that doesn’t do anything for our image size issues. On the other hand, Docker offers some very interesting benefits including:

  • The Docker Essbase image is defined in terms of a Dockerfile and scripts. A Dockerfile defines a Docker image, which is to say that the Dockerfile and associated scripts essentially define how an Essbase image is built. We can treat the Dockerfile as code, and we can version it.
  • We can define multiple versions of Essbase images: For a software company this is quite useful as we’re able to have different images for different patch levels of Essbase and easily switch between them.
  • Smaller footprint: the Dockerized Essbase image is much smaller than a traditional VM.

It’s important to point out that while there is significant overlap between Docker and traditional VMs, Docker isn’t really meant to be a better VM. In fact, one of the most useful aspects of using Essbase on Docker is that I can and do often throw away my container when I’m done with it and just start up a new one when I need to use it. That said, you can treat it a little like a VM and indeed I have developed some of the related scripts to startup Essbase as gracefully as possible when you resume a stopped (paused) image.

Evolution from “Generation 1” Docker Essbase image to Current State

At my first talk on Docker with Essbase I showed what a “monolithic” Essbase image: an image with an Oracle relational database installed on it as well as a full Essbase installation. This image weighs in at around 40GB. This would be common for a VM but quite large for a Docker image. Furthermore, it’s not really the way that a Docker image “likes” to be configured. I mentioned at the time that the most pressing to-do item for the Docker Essbase image was simply to get away from the bundled relational database and instead switch to a composed Docker image.

A composed image is what it sounds like: it’s much more idiomatic in Docker to compose or tie together multiple disparate Docker images into a cohesive whole, rather than attempting to put everything in one image. In this next generation image I am relying on a Microsoft SQL Server on Linux Docker image (provided by Microsoft). This greatly simplifies the Essbase image by allowing me to skip having 3.5+ GB of Oracle RDBMS installers and the need to install that database first. The Microsoft SQL Server on Linux image is fantastic – it comes up fast, and more importantly, is available “off the shelf”. The DB2 image provided by IBM is also fantastic.

Switching from Oracle to SQL Server was the single biggest bang-for-buck improvement to the image size and simplicity, quickly followed by moving to a “multi-stage” build. You can read more details on this over on the public GitHub repository but in short, this technique allows me to essentially not take a hit to the image size when it comes to temporary files. This allows me to trim the image down by doing the Essbase install in one stage and then copying the essential files over in another stage. I’ve also done many other things to trim the image size:

  • Consolidate down to a single JDK (instead of 2/3)
  • Remove various unused 32-bit files
  • Remove unneeded patch files
  • Remove unused Merant ODBC drivers/docs
  • Remove other files we can live without

Additionally, several convenience settings and actions are performed at startup: load and calculate the sample databases, add startMaxl.sh to the system path, create a symlink for the import_export folder, and more.

The result is this: the final image size is just under 4GB (3.96GB last I checked). You get a “vanilla” Essbase server, automatically loaded sample databases, some convenience features on the command line, all fired up and ready to go. You can throw it away when you’re done with it, or just stop the services and come back to your tests later.

Who this is for

I think this image will be most useful for developers and consultants. As an independent software vendor whose flagship software works with Essbase, it’s very useful for testing purposes.

Who this isn’t for

Please note that this Docker project only assumes and installs Essbase – it doesn’t have do Planning, FR, or any of the other tools. An intrepid developer could, though, use these files as a basis for supporting Planning and other technologies.

Also, to be very clear, this image isn’t meant to run in production or to take the place of your Essbase servers, virtual or otherwise.

How to get started

Please note that if you are already familiar with Docker you may be used to being able to pull an image from the global Docker hub or another repository and get up and running right away. For example, you could run the Microsoft SQL Server on Linux from Microsoft with just a single command, assuming you have Docker installed already. That’s not quite the case here. In this case you’ll have to build the Essbase image first, using the files in this GitHub repository combined with the Essbase installation media that you download from Oracle yourself. After the first build that creates the Essbase image locally, you’ll then have the ability to run it.

Altogether, you’ll need Docker installed on your machine, the Essbase installation media, Java installation media, and of course the files in this open source project repository.

The following shell examples show that I am on a Linux server, testing that Docker is installed/available, checking my current directory, and checking the version of Git that is available:

jason@docker1:~/docker-essbase-demo$ docker --version
 Docker version 18.06.1-ce, build e68fc7a

jason@docker1:~/docker-essbase-demo$ pwd
 /home/jason/docker-essbase-demo

jason@docker1:~/docker-essbase$ git version
git version 2.17.1

The next thing to do is pull down the files from the Git repository using the clone command:

jason@docker1:~/docker-essbase-demo$ git clone https://github.com/appliedolap/docker-essbase.git
 Cloning into 'docker-essbase'…
 remote: Enumerating objects: 131, done.
 remote: Counting objects: 100% (131/131), done.
 remote: Compressing objects: 100% (71/71), done.
 remote: Total 131 (delta 72), reused 112 (delta 53), pack-reused 0
 Receiving objects: 100% (131/131), 612.99 KiB | 14.59 MiB/s, done.
 Resolving deltas: 100% (72/72), done.
 jason@docker1:~/docker-essbase-demo$ ls
 docker-essbase
 jason@docker1:~/docker-essbase-demo$ cd docker-essbase
 jason@docker1:~/docker-essbase-demo/docker-essbase$ ls
 config-and-start.sh  Dockerfile           essbash.sh              load-sample-databases.msh  restart.sh             start_scripts
 deploy-landing.sh    essbase-config.xml   follow-essbase-logs.sh  odbc.ini                   run.sh                 start-scripts.sh
 docker-compose.yml   essbase-install.xml  jtds12.jar              README.md                  SimpleJdbcRunner.java  welcome.sh
 jason@docker1:~/docker-essbase-demo/docker-essbase$ 

After the Git repository files are cloned, you need to add in the Essbase 11.1.2.4 installation media. This includes these files:

  • Foundation-11124-linux64-Part1.zip
  • Foundation-11124-linux64-Part2.zip
  • Foundation-11124-linux64-Part4.zip
  • Foundation-11124-Part3.zip
  • Essbase-11124-linux64.zip

I also recommend you download the latest version of the Java 7 JDK, also available from Oracle. Note that the version in use is higher than what is publicly available on Oracle’s download site, you will need to get this version from Oracle’s download site after logging in:

  • jdk-7u211-linux-x64.tar.gz

The file listing should now look like this:

jason@docker1:~/docker-essbase$ ls -l
total 6707580
-rwxrwxr-x 1 jason jason 5281 Mar 4 16:25 config-and-start.sh
-rw-rw-r-- 1 jason jason 966 Jan 7 20:57 deploy-landing.sh
-rw-rw-r-- 1 jason jason 953 Mar 4 16:52 docker-compose.yml
-rw-rw-r-- 1 jason jason 7070 Mar 4 16:49 Dockerfile
-rwxrwxr-x 1 jason jason 1368259501 Dec 28 21:25 Essbase-11124-linux64.zip
-rw-rw-r-- 1 jason jason 13648 Jan 11 02:39 essbase-config.xml
-rw-rw-r-- 1 jason jason 939 Jan 3 19:28 essbase-install.xml
-rwxrwxr-x 1 jason jason 47 Jan 3 19:29 essbash.sh
-rwxrwxr-x 1 jason jason 177 Jan 3 19:20 follow-essbase-logs.sh
-rwxrwxr-x 1 jason jason 1174052554 Dec 28 21:22 Foundation-11124-linux64-Part1.zip
-rwxrwxr-x 1 jason jason 1516370785 Dec 28 21:22 Foundation-11124-linux64-Part2.zip
-rwxrwxr-x 1 jason jason 980505762 Dec 28 21:22 Foundation-11124-linux64-Part4.zip
-rwxrwxr-x 1 jason jason 1529284475 Dec 28 21:22 Foundation-11124-Part3.zip
-rw-r--r-- 1 jason jason 145798191 Feb 6 20:14 jdk-7u211-linux-x64.tar.gz
-rw-r--r-- 1 jason jason 153530841 Jan 8 06:47 jdk-7u80-linux-x64.tar.gz
-rwxr-xr-x 1 jason jason 611504 Dec 31 21:19 jtds12.jar
-rw-rw-r-- 1 jason jason 607 Jan 15 05:42 load-sample-databases.msh
-rw-r----- 1 jason jason 1411 Jan 14 20:54 odbc.ini
-rw-rw-r-- 1 jason jason 15313 Jan 9 21:50 README.md
-rwxrwxr-x 1 jason jason 523 Jan 9 19:03 restart.sh
-rwxrwxr-x 1 jason jason 51 Jan 9 18:57 run.sh
-rw-rw-r-- 1 jason jason 5049 Jan 9 19:48 SimpleJdbcRunner.java
drwxrwxr-x 2 jason jason 4096 Mar 4 16:23 start_scripts
-rw-rw-r-- 1 jason jason 80 Jan 14 20:03 start-scripts.sh
-rw-rw-r-- 1 jason jason 43 Jan 8 07:19 welcome.sh
jason@docker1:~/docker-essbase$

We can now perform the first time image build with Docker:

jason@docker1:~/docker-essbase$ docker build -t essbase .

You’ll see a lot of text scroll by on your console. Docker will pull files from the cloud that it needs (such as the base OS image), then start building the image step by step by reading through the Dockerfile. This step will take awhile but it only needs to be done once:

Sending build context to Docker daemon  6.869GB
Step 1/57 : ARG ORACLE_ROOT_DEFAULT=/opt/Oracle
Step 2/57 : FROM centos:6.9 as media
---> e88c611d16a0
Step 3/57 : ARG ORACLE_ROOT_DEFAULT
---> Using cache
---> 56b038ecf1e6
Step 4/57 : RUN touch /var/lib/rpm/* && yum -y install unzip
---> Running in 38987aabe3fb
Loaded plugins: fastestmirror, ovl
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package unzip.x86_64 0:6.0-5.el6 will be installed
--> Finished Dependency Resolution
================================================================================
Package Arch Version Repository Size
Installing:
unzip x86_64 6.0-5.el6 base 152 kTransaction Summary
Install 1 Package(s)
Total download size: 152 k
Installed size: 324 k
Downloading Packages:
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) centos-6-key@centos.org
Package: centos-release-6-9.el6.12.3.x86_64 (@CentOS/6.9)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : unzip-6.0-5.el6.x86_64 1/1
Verifying : unzip-6.0-5.el6.x86_64 1/1
Installed:
unzip.x86_64 0:6.0-5.el6
Complete!
Removing intermediate container 38987aabe3fb
---> 0dbb210931bf
Step 5/57 : RUN mkdir -p /root/epmmedia/extracted
---> Running in 46f0adfd365f
Removing intermediate container 46f0adfd365f
---> 997ff1f0f532
Step 6/57 : WORKDIR /root/epmmedia
---> Running in 6afd053d8f0b
Removing intermediate container 6afd053d8f0b
---> 7d3c7191629b
Step 7/57 : RUN groupadd -f dba && groupadd -f oinstall && useradd -G dba oracle
---> Running in 7fa40b3cf4f5
Removing intermediate container 7fa40b3cf4f5
---> 2f399bd90787
Step 8/57 : ENV ORACLE_ROOT $ORACLE_ROOT_DEFAULT

I’ve clipped out steps 9 through 19 as they are particularly verbose. Continuing on:

Step 20/57 : ENV TMP /tmp
---> Running in 53283b9e1e82
Removing intermediate container 53283b9e1e82
---> 3b51e21392b0
Step 21/57 : COPY essbase-install.xml .
---> 9af674185fa7
Step 22/57 : RUN sed -i "s|ORACLE_ROOT|$ORACLE_ROOT|g" $HOME/essbase-install.xml && $HOME/extracted/installTool.sh -silent $HOME/essbase-install.xml
---> Running in 37714c324e0a
INFO: File descriptor soft limit increased from 1024 to 4096.
WARNING: You must manually configure the file descriptor limit to
4096, or higher, in the login profile for the user that
will start the applications being configured.
Installer Path check… Ok
Checking if running under root account… Ok
Current user is not root.
EPMINS-01087: Checking if the file exist and have read permissions: /home/oracle/extracted/assemblies… Ok
EPMINS-01087: Checking if the file exist and have read permissions: /home/oracle/extracted/jre… Ok
EPMINS-01087: Checking if the file exist and have read permissions: /home/oracle/extracted/setup.jar… Ok
Checking environment variables…
Environment variable TMP would be used.
Ok
EPMINS-01087: Checking if the file exist and have read permissions: /home/oracle…
Ok
EPMINS-01099: User home have to exist for successful installation.
EPMINS-01002: All installation prerequisites have been met. Starting EPM System Installer.
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
sh: /usr/bin/ipcs: No such file or directory
/bin/cat: /proc/sys/net/core/wmem_default: No such file or directory

EPMINS-01032: Checking for available disk space in the /opt/Oracle/Middleware/EPMSystem11R1 directory.
EPMINS-01033: The selected components require 6315 MB free disk space.
EPMINS-01034: You have 744295 MB free disk space.

I’ve omitted some other output for brevity but you may notice that in the above step the actual EPM installation is being called, and then the actual Essbase image is starting to be built below:

Step 25/57 : FROM centos:6.9
---> e88c611d16a0
Step 26/57 : ARG ORACLE_ROOT_DEFAULT
---> Using cache
---> 56b038ecf1e6
Step 27/57 : LABEL maintainer="jason@appliedolap.com"
---> Using cache
---> 88f781ec9432
Step 28/57 : RUN touch /var/lib/rpm/* && yum -y install unzip compat-libcap1 libstdc++-devel sysstat gcc gcc-c++ ksh libaio libaio-devel lsof numactl glibc-devel glibc-devel.i686 libgcc libgcc.i686 compat-libstdc++-33 compat-libstdc++-33.i686 openssh-clients && yum clean all
---> Using cache
---> 1408dd6fa584
Step 29/57 : RUN groupadd -f dba && groupadd -f oinstall && useradd -G dba oracle
---> Using cache
---> bc06dc9b9840
Step 30/57 : ENV ORACLE_ROOT $ORACLE_ROOT_DEFAULT
---> Using cache
---> d248c42fd11e
Step 31/57 : RUN mkdir -p $ORACLE_ROOT && chown oracle:dba $ORACLE_ROOT
---> Using cache
---> 904c5aad603f
Step 32/57 : WORKDIR /home/oracle
---> Using cache
---> dc3ed83b5a02
Step 33/57 : COPY --from=media --chown=oracle:dba $ORACLE_ROOT $ORACLE_ROOT
---> f79f5daa7bfa
Step 34/57 : COPY --chown=oracle:dba SimpleJdbcRunner.java config-and-start.sh jtds12.jar essbase-config.xml load-sample-databases.msh welcome.sh ./
---> fe88dd1556a9
Step 35/57 : RUN mkdir -p init-data && chown oracle:oracle init-data
---> Running in e3130161e20f
Removing intermediate container e3130161e20f
---> dd41a469a10e
Step 36/57 : ENV JAVA_HOME $ORACLE_ROOT/Middleware/jdk160_35
---> Running in 3123fdd81715
Removing intermediate container 3123fdd81715
---> 5185168850f6
Step 37/57 : ENV JAVA_VENDOR Sun
---> Running in f1f8ca16e335
Removing intermediate container f1f8ca16e335
---> 557f1986154e
Step 38/57 : ENV JAVA_OPTIONS -XX:+UnlockCommercialFeatures
---> Running in 9ea50292f53a
Removing intermediate container 9ea50292f53a
---> 4d7e74a76a0e
Step 39/57 : ENV EPM_ORACLE_INSTANCE $ORACLE_ROOT/Middleware/user_projects/epmsystem1
---> Running in 079c006c443f
Removing intermediate container 079c006c443f
---> dfe4367e3b49
Step 40/57 : ENV PATH="${JAVA_HOME}/bin:${EPM_ORACLE_INSTANCE}/EssbaseServer/essbaseserver1/bin:${PATH}"
---> Running in 07972de36062
Removing intermediate container 07972de36062
---> d22af6d116a1
Step 41/57 : ENV EPM_ORACLE_HOME $ORACLE_ROOT/Middleware/EPMSystem11R1
---> Running in 8e37016a11a5
Removing intermediate container 8e37016a11a5
---> 80d8f5339e66
Step 42/57 : ENV USER_PROJECTS $ORACLE_ROOT/Middleware/user_projects
---> Running in 9289ce855d7d
Removing intermediate container 9289ce855d7d
---> 70927570793a
Step 43/57 : ENV TMP /tmp
---> Running in 3e2d30b0518d
Removing intermediate container 3e2d30b0518d
---> c8735e90a8da
Step 44/57 : ENV EPM_ADMIN admin
---> Running in b1facbf77b3d
Removing intermediate container b1facbf77b3d
---> 74ed11bedc93
Step 45/57 : ENV EPM_PASSWORD password1
---> Running in 522922e6e819
Removing intermediate container 522922e6e819
---> 502b5a0f0e76
Step 46/57 : ENV ESS_START_PORT="32768" ESS_END_PORT="32778"
---> Running in 7866c68e1ba0
Removing intermediate container 7866c68e1ba0
---> b25174a0c8e9
Step 47/57 : ENV LCM_CMD $USER_PROJECTS/epmsystem1/bin/Utility.sh
---> Running in 65f573b97574
Removing intermediate container 65f573b97574
---> 76a870442a71
Step 48/57 : ENV WL_CMD ="java -cp $ORACLE_ROOT/Middleware/wlserver_10.3/server/lib/weblogic.jar weblogic.Deployer -adminurl t3://127.0.0.1:7001 -user $EPM_ADMIN -password $EPM_PASSWORD"
---> Running in df13370b1425
Removing intermediate container df13370b1425
---> 29a26fe66f47
Step 49/57 : ENV SQL_HOST db
---> Running in c9b19f3d7b21
Removing intermediate container c9b19f3d7b21
---> 50119770001a
Step 50/57 : ENV SQL_USER sa
---> Running in cfcb8506281e
Removing intermediate container cfcb8506281e
---> 21e451e7b107
Step 51/57 : ENV SQL_PASSWORD password
---> Running in 88271902fb21
Removing intermediate container 88271902fb21
---> 3c73d260fbff
Step 52/57 : ENV AUTO_START_ADMIN_CONSOLE false
---> Running in fb14162b86d1
Removing intermediate container fb14162b86d1
---> 89feffc9b7db
Step 53/57 : ENV NO_CONFIG false
---> Running in 65b1ba611cc9
Removing intermediate container 65b1ba611cc9
---> 7ee999fd5cce
Step 54/57 : RUN echo source welcome.sh >> /home/oracle/.bashrc
---> Running in 6a0659f27375
Removing intermediate container 6a0659f27375
---> 01b47eae9269
Step 55/57 : USER oracle
---> Running in 6e02f60bde06
Removing intermediate container 6e02f60bde06
---> 3e927ba22740
Step 56/57 : EXPOSE 9000 1423 $ESS_START_PORT-$ESS_END_PORT 7001
---> Running in c0206a101e5a
Removing intermediate container c0206a101e5a
---> 2dc9065f4012
Step 57/57 : CMD ["./config-and-start.sh"]
---> Running in eee87d98563c
Removing intermediate container eee87d98563c
---> 0619eb6e4a0f
Successfully built 0619eb6e4a0f
Successfully tagged essbase:latest
jason@docker1:~/docker-essbase$

After the last step, the image has now been successfully built. We can now run the image and create an actual container. You can do so by using the docker-compose command:

jason@docker1:~/docker-essbase$ docker-compose up --no-build --detach
Creating network "docker-essbase_default" with the default driver
Creating docker-essbase_db_1 … done
Creating essbase … done
jason@docker1:~/docker-essbase$

Your shell should now return you to a normal prompt. You can run the included “follow-essbase-logs.sh” script (if on Windows open this script and run its command directly, docker-compose logs --follow essbase) to specifically attach and follow the console output from the Essbase container:

jason@docker1:~/docker-essbase$ ./follow-essbase-logs.sh 
Attaching to essbase
essbase | Starting up Essbase container, checking if configuration is needed
essbase | java version "1.7.0_211"
essbase | Java(TM) SE Runtime Environment (build 1.7.0_211-b31)
essbase | Java HotSpot(TM) 64-Bit Server VM (build 24.211-b31, mixed mode)
essbase | Performing first-time configuration
essbase | Unable to connect to database on attempt 1, waiting 5s before attempting again, will try 4 more times
essbase | Executing: DROP DATABASE IF EXISTS EPM_HSS, EPM_EAS
essbase | Executing: CREATE DATABASE EPM_HSS
essbase | Executing: CREATE DATABASE EPM_EAS
essbase | Running preconfig checks…
essbase | Running EPM_ORACLE_HOME…
essbase | EPM_ORACLE_HOME environment variable value: /opt/Oracle/Middleware/EPMSystem11R1
essbase | JAVA_HOME environment variable value: /opt/Oracle/Middleware/EPMSystem11R1/../jdk160_35
essbase | EPM_ORACLE_HOME succeeded
essbase | Running .oracle.products … .oracle.products succeeded
essbase | Running Jars manifest …
essbase | Time spent for manifests parsing: 111 ms
essbase | Maximum jars depth achieved: 6, while restriction was: unrestricted
essbase | Parsed 421 manifests
essbase | Total jars and classpath entries encountered: 421
essbase | Total not-existing referenced classpath entries count: 31
essbase | Total classpath elements to check: 58
essbase | Jars manifest succeeded
essbase | Running Environment variables …
essbase | Environment variable TMP would be used
essbase | Environment variables succeeded
essbase | Preconfig checks passed! Proceeding further

The console will stay on this message for awhile, since the EPM installer is performing a first-time configuration (setting up files, database tables, etc.). After a few minutes the installer will move on:

essbase    | Context:
essbase | declare -x AUTO_START_ADMIN_CONSOLE="false"
essbase | declare -x EPM_ADMIN="admin"
essbase | declare -x EPM_ORACLE_HOME="/opt/Oracle/Middleware/EPMSystem11R1"
essbase | declare -x EPM_ORACLE_INSTANCE="/opt/Oracle/Middleware/user_projects/epmsystem1"
essbase | declare -x EPM_PASSWORD="password1"
essbase | declare -x ESS_END_PORT="32778"
essbase | declare -x ESS_START_PORT="32768"
essbase | declare -x HOME="/home/oracle"
essbase | declare -x HOSTNAME="3683b4d53745"
essbase | declare -x JAVA_HOME="/opt/Oracle/Middleware/jdk160_35"
essbase | declare -x JAVA_OPTIONS="-XX:+UnlockCommercialFeatures"
essbase | declare -x JAVA_VENDOR="Sun"
essbase | declare -x LCM_CMD="/opt/Oracle/Middleware/user_projects/epmsystem1/bin/Utility.sh"
essbase | declare -x NO_CONFIG="false"
essbase | declare -x OLDPWD
essbase | declare -x ORACLE_ROOT="/opt/Oracle"
essbase | declare -x PATH="/opt/Oracle/Middleware/jdk160_35/bin:/opt/Oracle/Middleware/user_projects/epmsystem1/EssbaseServer/essbaseserver1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
essbase | declare -x PWD="/home/oracle"
essbase | declare -x RESTART_EPM_AFTER_LCM_IMPORT="false"
essbase | declare -x SHLVL="1"
essbase | declare -x SQL_HOST="db"
essbase | declare -x SQL_PASSWORD="AAbb11##"
essbase | declare -x SQL_USER="sa"
essbase | declare -x TMP="/tmp"
essbase | declare -x USER_PROJECTS="/opt/Oracle/Middleware/user_projects"
essbase | declare -x WL_CMD="=java -cp /opt/Oracle/Middleware/wlserver_10.3/server/lib/weblogic.jar weblogic.Deployer -adminurl t3://127.0.0.1:7001 -user admin -password password1"
essbase | Calling EPM start script
essbase | Starting all
essbase | Apache Ant version 1.7.1 compiled on June 27 2008
essbase | Buildfile: /opt/Oracle/Middleware/EPMSystem11R1/common/config/11.1.2.0/resources/instance/start.xml

On the last line in the preceding section you see that it’s running the start.xml. EPM/Essbase on Linux uses an Ant file to start up services. After the service startup finishes, you’ll see some logs fly by as well as the output from the default MaxL script:

essbase    | 
essbase | Essbase MaxL Shell 64-bit - Release 11.1.2 (ESB11.1.2.4.000B193)
essbase | Copyright (c) 2000, 2015, Oracle and/or its affiliates.
essbase | All rights reserved.
essbase |
essbase | MAXL> login "admin" "password1" on "localhost";
essbase |
essbase | OK/INFO - 1051034 - Logging in user [admin@Native Directory].
essbase | OK/INFO - 1241001 - Logged in to Essbase.
essbase |
essbase | MAXL> import database "Sample"."Basic" data
essbase | 2> from server data_file "Calcdat"
essbase | 3> on error abort;
essbase |
essbase | OK/INFO - 1054014 - Database Basic loaded.
essbase | OK/INFO - 1054014 - Database Xchgrate loaded.
essbase | OK/INFO - 1054014 - Database Interntl loaded.
essbase | OK/INFO - 1051061 - Application Sample loaded - connection established.
essbase | OK/INFO - 1054027 - Application [Sample] started with process id [2986].
essbase | OK/INFO - 1003040 - Parallel dataload enabled: [1] block prepare threads, [1] block write threads..
essbase | OK/INFO - 1003037 - Data Load Updated [67176] cells.
essbase | OK/INFO - 1003052 - Data Load Elapsed Time for [Calcdat.txt] : [0.12] seconds.
essbase | OK/INFO - 1241113 - Database import completed ['Sample'.'Basic'].
essbase |
essbase | MAXL> execute calculation default
essbase | 2> on "Sample"."Basic";
essbase |
essbase | OK/INFO - 1012675 - Commit Blocks Interval for the calculation is [3000].
essbase | OK/INFO - 1012684 - Multiple bitmap mode calculator cache memory usage has a limit of [50000] bitmaps..
essbase | OK/INFO - 1012669 - Calculating [ Measures(All members) Year(All members) Scenario(All members) Product(All members) Market(All members)].
essbase | OK/INFO - 1012677 - Calculating in serial.
essbase | OK/INFO - 1012550 - Total Calc Elapsed Time : [0.069] seconds.
essbase | OK/INFO - 1013274 - Calculation executed.
essbase |
essbase | MAXL> import database "Demo"."Basic" data
essbase | 2> from server data_file "Data"
essbase | 3> on error abort;
essbase |
essbase | OK/INFO - 1054014 - Database Basic loaded.
essbase | OK/INFO - 1051061 - Application Demo loaded - connection established.
essbase | OK/INFO - 1054027 - Application [Demo] started with process id [3065].
essbase | OK/INFO - 1003040 - Parallel dataload enabled: [1] block prepare threads, [1] block write threads..
essbase | OK/INFO - 1003037 - Data Load Updated [54468] cells.
essbase | OK/INFO - 1003052 - Data Load Elapsed Time for [Data.txt] : [0.1] seconds.
essbase | OK/INFO - 1241113 - Database import completed ['Demo'.'Basic'].
essbase |
essbase | MAXL> execute calculation default
essbase | 2> on "Demo"."Basic";
essbase |
essbase | OK/INFO - 1012675 - Commit Blocks Interval for the calculation is [3000].
essbase | OK/INFO - 1012684 - Multiple bitmap mode calculator cache memory usage has a limit of [50000] bitmaps..
essbase | OK/INFO - 1012669 - Calculating [ Accounts(All members) Year(All members) Scenario(All members) Market(All members) Product(All members)].
essbase | OK/INFO - 1012677 - Calculating in serial.
essbase | OK/INFO - 1012600 - Member [Profit_%] attempts to divide by Missing, Invalid, or Near Zero value (Message will not repeat).
essbase | OK/INFO - 1012550 - Total Calc Elapsed Time : [0.042] seconds.
essbase | OK/INFO - 1013274 - Calculation executed.
essbase |
essbase | MAXL> import database "ASOsamp"."Sample" data
essbase | 2> from server data_file "dataload"
essbase | 3> using server rules_file "dataload"
essbase | 4> on error abort;
essbase |
essbase | OK/INFO - 1054014 - Database Sample loaded.
essbase | OK/INFO - 1051061 - Application ASOsamp loaded - connection established.
essbase | OK/INFO - 1054027 - Application [ASOsamp] started with process id [3142].
essbase | OK/INFO - 1019061 - Reading Rule SQL Information For Database [Sample].
essbase | OK/INFO - 1019025 - Reading Rules From Rule Object For Database [Sample].
essbase | OK/INFO - 1003040 - Parallel dataload enabled: [1] block prepare threads, [1] block write threads..
essbase | OK/INFO - 1003051 - Data Load Elapsed Time for [dataload.txt] with [dataload.rul] : [1.68] seconds.
essbase | OK/INFO - 1241113 - Database import completed ['ASOsamp'.'Sample'].
essbase |
essbase | WARNING - 1003065 - Data load stream contains [0] zero and [309615] #MISSING cells.
essbase | MAXL> execute aggregate process on database "ASOsamp"."Sample"
essbase | 2> stopping when total_size exceeds 1.1;
essbase |
essbase | OK/INFO - 1270045 - Successfully built [7] new aggregate views. Elapsed time [11.78] sec.
essbase | OK/INFO - 1243014 - Aggregates processed on database ASOsamp.Sample.
essbase |
essbase | MAXL> logout;
essbase |
essbase | User admin is logged out
essbase |
essbase |
essbase | MaxL Shell completed
essbase |

The included MaxL script that loads and calcs the default databases is pretty straightforward. Because the Essbase admin username and password are configurable and available as environment variables, we can reference them directly in the MaxL script to keep things clean:

/* invoked with startMaxl.sh */

login "$EPM_ADMIN" "$EPM_PASSWORD" on "localhost";

import database "Sample"."Basic" data
        from server data_file "Calcdat"
        on error abort;

execute calculation default
        on "Sample"."Basic";

import database "Demo"."Basic" data
        from server data_file "Data"
        on error abort;

execute calculation default
        on "Demo"."Basic";

import database "ASOsamp"."Sample" data
        from server data_file "dataload"
        using server rules_file "dataload"
        on error abort;

execute aggregate process on database "ASOsamp"."Sample"
        stopping when total_size exceeds 1.1;

logout;
exit;

Once the configuration and startup has been completed, you’ll now have a running Essbase server waiting for connection requests and can treat it as you would any other Essbase server. By default, the console will just follow various Essbase log files, such as:

essbase    | ==> /opt/Oracle/Middleware/user_projects/domains/EPMSystem/servers/EPMServer0/logs/EPMServer0.log <==
essbase    | ####   <3683b4d53745>   <> <> <> <1552933627482>  <83% of the total memory in the server is free> 

In a typical Docker image, the last step/command runs a service or runs something and “waits”. If it didn’t, then the container would just be “done” and exit. In order to keep the container running, it’s very common to just have the last line in your script just run a tail command, which will watch the output of a file indefinitely. That’s exactly what’s going on here, although in this case the tail command is being used to watch several log files.

You should now be able to pull up the EAS console page by visting http://localhost:9000/easconsole and login to Workspace by visiting http://localhost:9000/workspace. To stop following the console (but to leave the Essbase server running) you press Ctrl+C.

Managing Your Containers With Docker Commands

You will likely want to use some Docker commands (or perhaps a GUI-based front end) to manage your running Docker containers. To list the running containers:

docker ps

You’ll see output similar to the following:

CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                                                                                                                                  NAMES

3683b4d53745 essbase:11.1.2.4 "./config-and-start.…" 8 minutes ago Up 8 minutes 0.0.0.0:1423->1423/tcp, 0.0.0.0:7001->7001/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:9443->9443/tcp, 0.0.0.0:32768-32778->32768-32778/tcp essbase

a943411b0bc4 microsoft/mssql-server-linux:2017-latest "/opt/mssql/bin/sqls…" 8 minutes ago Up 8 minutes 1433/tcp docker-essbase_db_1
jason@docker1:~/docker-essbase$

You may want to stop your running Essbase server and SQL database:

jason@docker1:~/docker-essbase$ docker-compose stop
Stopping essbase … done
Stopping docker-essbase_db_1 … done
jason@docker1:~/docker-essbase$

You can see that now nothing is listed as running:

jason@docker1:~/docker-essbase$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
jason@docker1:~/docker-essbase$

You can even connect to the Bash instance inside your Essbase container by using the included convenience script, essbash.sh. It’s just a handy way to run the command docker-compose exec essbase bash.

jason@docker1:~/docker-essbase$ ./essbash.sh 
Welcome to the Essbase Docker image!

Inside the Essbase container you can list the files and see what’s there, if you want:

$ ls -l
total 672
lrwxrwxrwx 1 oracle oracle 80 Mar 18 18:23 app -> /opt/Oracle/Middleware/user_projects/epmsystem1/EssbaseServer/essbaseserver1/app
-rwxrwxr-x 1 oracle dba 5281 Feb 9 03:54 config-and-start.sh
-rw-rw-r-- 1 oracle dba 13543 Mar 18 18:23 essbase-config.xml
-rwxr-x--- 1 oracle oracle 172 Mar 18 18:24 exec.sh
lrwxrwxrwx 1 oracle oracle 61 Mar 18 18:23 import_export -> /opt/Oracle/Middleware/user_projects/epmsystem1/import_export
drwxr-xr-x 2 oracle oracle 4096 Mar 4 16:50 init-data
-rwxr-xr-x 1 oracle dba 611504 Dec 31 21:19 jtds12.jar
-rw-rw-r-- 1 oracle dba 607 Jan 15 05:42 load-sample-databases.msh
drwxr----- 3 oracle oracle 4096 Mar 18 18:25 oradiag_oracle
-rw-r--r-- 1 oracle oracle 3506 Mar 18 18:23 SimpleJdbcRunner.class
-rw-rw-r-- 1 oracle dba 5049 Jan 9 19:48 SimpleJdbcRunner.java
drwxrwxr-x 2 1000 1000 4096 Mar 4 16:23 start_scripts
lrwxrwxrwx 1 oracle oracle 75 Mar 18 18:23 startWebLogicAdminConsole.sh -> /opt/Oracle/Middleware/user_projects/domains/EPMSystem/bin/startWebLogic.sh
-rw-rw-r-- 1 oracle dba 43 Jan 8 07:19 welcome.sh

You can run the classic ps aux command to see what’s running on the Essbase Linux container:

$ ps aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
oracle 1 0.0 0.0 11368 2496 ? Ss 18:33 0:00 /bin/bash ./config-and-start.sh
oracle 66 0.0 0.0 67116 12616 ? Ss 18:33 0:00 /opt/Oracle/Middleware/EPMSystem11R1/opmn/bin/opmn -d
oracle 85 2.6 0.2 2770768 177636 ? Sl 18:33 0:04 /opt/Oracle/Middleware/EPMSystem11R1/products/Essbase/EssbaseServer/bin/ESSBASE ** 1423 -agents
oracle 165 0.4 0.0 1288996 26804 ? Sl 18:33 0:00 /opt/Oracle/Middleware/EPMSystem11R1/opmn/bin/opmn -d
oracle 197 0.0 0.0 11368 2440 ? S 18:33 0:00 /bin/sh /opt/Oracle/Middleware/user_projects/domains/EPMSystem/bin/startManagedWebLogic.sh EPMServer0 t
oracle 198 0.0 0.0 11504 2608 ? S 18:33 0:00 /bin/sh /opt/Oracle/Middleware/user_projects/domains/EPMSystem/bin/startWebLogic.sh -DEPM_ORACLE_INSTAN
oracle 326 27.2 1.7 13658696 1173876 ? Sl 18:33 0:48 /opt/Oracle/Middleware/jdk160_35/bin/java -server -Xms128m -XX:PermSize=64m -XX:MaxPermSize=512m -Xmx80
oracle 456 0.0 0.0 4168 472 ? S 18:34 0:00 tail -F /opt/Oracle/Middleware/user_projects/domains/EPMSystem/servers/EPMServer0/logs/EPMServer0.log /
oracle 463 0.0 0.0 108380 3212 pts/0 Ss 18:35 0:00 bash
oracle 499 0.0 0.0 110256 2344 pts/0 R+ 18:36 0:00 ps aux

Where to go from here

I have to admit that classic, large enterprise applications don’t completely lend themselves to these modern containerization and cloud technologies. It took more than a bit of engineering to get this all working. There were also some challenges owing to being stuck on older WebLogic and Java instances. And my goodness, how many years ago did 11.1.2.4 show up? Nevertheless, building this container out has been incredibly useful and educational. I am excited to get this work out into the open so that others can benefit from it as well as be ideally positioned for future Essbase releases. Once I get my hands on the upcoming on-premises releases of Essbase I will use the development and lessons from this project in order to make Dockerfiles available for those as well.

How you can help

You can help simply by running the Essbase image and providing any feedback you have. I generally run this on a Mac or directly from a Linux server, either a physical server in my lab or on a Linux image running on the cloud. Several members of my team are using this on Windows with success (albeit with some quirks). You may even develop some enhancements to the script/files that you’d like to contribute – please feel free to do so by creating a pull request on GitHub.

8 thoughts on “Oracle Essbase on Docker: What, How, Why

  1. Jason,

    Very interesting post! I’ve been working with Docker myself for about one year.

    Please confirm; from what I gather, Oracle is not providing a docker image of Essbase. You are simply providing code on how to “Dockerize” Essbase using the existing install files and process?

    Assuming that’s the case, for clarity purposes, the licensing details you state are only for your code and not for the Essbase installation?

    Reid K.

    • That’s exactly right, Reid. We definitely don’t have rights to distribute Essbase software itself. My analogy is that this is the recipe. You need to go get the Essbase .zip files (the ingredients) to then go bake the cookies (the thing you want – the Essbase server!). The MIT open source license applies to just the scripts and files we’re providing. Also for what it’s worth I can easily say that these scripts to define a perfectly setup Essbase server with some customizations took well over 200 hours to develop.

  2. Sreekumar Hariharan

    Hello Jason,

    Hope you are doing well. I wanted to ask you one question, have tried installing docker in windows 10 and then Essbase on it.

  3. Hi Jason, I am trying to install Essbase on Docker and stuck with this step:
    Step 18/33 : RUN ./apply_patches.sh
    —> Running in 7b35cc934f78
    /bin/sh: ./apply_patches.sh: /bin/sh^M: bad interpreter: No such file or directory
    The command ‘/bin/sh -c ./apply_patches.sh’ returned a non-zero code: 126

    PLease help.

    Thanks,
    Your Fan.

    • Hi Sowmya, I would try commenting out line 92 on the Dockerfile (the line that runs the apply_patches.sh script) and see what happens. It seems that while it works for me on my system, maybe there is something wrong with that file on yours.

  4. Hi Jason, I installed it successfully and could login via MAXL script but however via EAS not working. In this case the URL http://localhost:9000/easconsole giving me this error. “From RFC 2068 Hypertext Transfer Protocol — HTTP/1.1:”.

    Please help. I am just one step away from the final one !
    Thanks so much for this lovely blog.

    Thanks,
    Sowmya

  5. Hi Jason,

    Please help sir. I did everything as mentioned and login via Maxl is also happening. However logging into Essbase and Workspace is not happening and getting this error.

    Error 404–Not Found
    From RFC 2068 Hypertext Transfer Protocol — HTTP/1.1:
    10.4.5 404 Not Found
    Can you help.

    Thanks,
    Sowmya

Leave a Reply

Your email address will not be published. Required fields are marked *