Monday, June 15, 2015

Installing Oracle XE, ORDS and Apex on CentOS - Part Two: Installation

This is part two in a series of blog posts about how to install Oracle 11g Express Edition (XE) with Oracle Application Express (Apex) on a CentOS Linux server, with Apex served by Oracle REST Data Services (ORDS) running on top of Tomcat and Apache.

Let's get right to it, starting with Oracle XE.

Installing Oracle XE

This is actually quite straightforward, assuming you have followed the prerequisite steps in part one.

As part of the installation, we created a user called oracle. It is useful to set up the default environment of this user to include the path to the sqlplus executable, so we can start sqlplus from anywhere.

Now, let's log in to Oracle as SYS and check that everything looks OK:

At this point you have an Oracle XE instance running, which also includes Apex 4.0 and the Embedded PL/SQL Gateway (EPG) running on port 8080. That is nice, but it's an old Apex version and the EPG web server is not really suited for heavy usage. We want the latest Apex version, and we want to use ORDS. Read on...

Installing Java

ORDS and Tomcat are both Java applications, so we need to install Java. Actually, we need the Java JDK (Java Development Kit), as opposed to just the Java JRE (Java Runtime Environment). There may already be something called the OpenJDK on the CentOS server, but we want the Oracle-supplied JDK, so let's remove OpenJDK and install the JDK that we downloaded from Oracle:

To have the Java binaries available from anywhere, we add the Java path to the bash profile of the root user:

Installing Tomcat

To install Tomcat, we will download the installation file directly to the server using the wget command, and then unzip it. Create a tomcat user to run the tomcat process.

To avoid conflicts with Oracle XE running the Embedded PL/SQL Gateway on port 8080, change Tomcat's default port number to 8090 by editing the server.xml file. (Note: Because we will put Apache in front of Tomcat, we won't ever access Tomcat directly on port 8090, and we will soon disable EPG, but let's just avoid possible conflicts anyway by assigning different ports.) It's also important to set the URIEncoding to UTF-8.

Next we need to create a script that can be used to start, stop and restart Tomcat as a service. Save the following as tomcat under /etc/init.d/

Then we need to set up the above script to run automatically if the server is rebooted.

Installing ORDS

The Oracle Rest Data Services (ORDS) installation consists of unzipping the installation file, running the configuration to specify database details, and then copying the ords.war file into the Tomcat webapps folder.

Installing Apache

The last step in completing our web stack is to install the Apache HTTP server and place it "in front of" Tomcat. This means that all requests to the server go to Apache first. Requests for static files (images, Javascript and CSS) is served directly by Apache. Requests for dynamic content (ie the actual HTML pages generated by Apex via ORDS) is served by Tomcat, using Apache as a proxy.

Installing Apache is very straightforward:

Then we need to add our custom configuration. By default, Apache is set up to read any .conf file placed in the /conf.d/ subfolder, so let's create an apex.conf file there. Note that these additional config files are read and processed in alphabetical order, so name your custom config accordingly if you use multiple config files.

Installing (upgrading to) latest Apex version

Finally, we need to upgrade the Apex installation that came bundled with Oracle XE to the latest and greatest Apex version (version 5.0 at the time of writing).

This is done by unzipping the Apex installation file, then running the Apex installation script via sqlplus. There are two different Apex installations to choose from: Either a full installation that includes the Application Builder (suitable for a development environment), and a more lightweight and secure "runtime-only" installation (suitable for test and production environments). Running the full installation on the standard 1GB server at DigitalOcean should take about 12-15 minutes.

We also need to make sure the apex_public_user schema is unlocked (and stays that way!).

We need to copy all the static Apex files (images, CSS, Javascript) to the Apache web folder.

When running on top of ORDS, Apex 5 uses the "RESTful Service" feature to serve any application-specific or workspace-specific static files, so we need to configure Apex with REST:

Now (finally!), if everything works, we should be able to access the new Apex installation by going to the following URL:


If everything works, you should see this familiar page:

Did it work? Great, now enjoy Apex 5! But wait, we are not fully done yet! In the next part of this series, I will describe various additional configuration that you should perform for a more secure and scalable server.

Stay tuned!


Anonymous said...

if SELINUX is activated then

chcon -R --reference=/var/www /var/www/apex/images

Rob van Wijk said...

Hi Morten,

Thank you for saving me -and likely other people as well- lots of time figuring out all these details. Great job!

Extra tip for other readers: don't be stubborn like me to choose ORDS 3.0 instead of 2.0.10 for now. Using 3.0 will lead to a 404 with the top line of the Java stack saying "oracle.dbtools.http.errors.NotFoundException"


Kai Donato said...

Thank you for this awesome tutorial.
I got it working with Tomcat 8 and ORDS 3.0 - with some modifications of course.

Best Regards!

Niall Mc Phillips said...

Thanks for these great notes.

In my case, Centos7 required libaio - this was easily fixed with the "yum install libaio -y" command

rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
error: Failed dependencies:
libaio >= 0.3.104 is needed by oracle-xe-11.2.0-1.0.x86_64

Georg said...

Thanks for this tutorial!
Please tell me what adjustments need to be made to make it working with ORDS 3.0.2?
Thanks in advance

Georg said...

Thanks for this tutorial!

Could you please tell my how to get this system running with the latest ORDS 3.0.2 and tomcat 8 (java jdk 8.66) installed?
Requesting /ords leads to a 404 http error.
Thanks in advance.

Peter said...

two things in your tutorial concerning the server ports are not quite clear to me:

1) Tomcat is configured for port 8090, but the default port offered by the ords
installation is 8080!?
2) The Apex port in the Apache configuration is 8009 - is this a typo??

it's a miracle to me - please help!

Thanks in Advance

Morten Braten said...

@Peter: To clarify regarding the port numbers:

* Port 80: Apache listens on this port. This is the standard port for HTTP requests.

* Port 443: Apache listens on this port if you have enabled SSL. This is the standard port for HTTPS requests.

* Port 8080: This is the default port for the Embedded PL/SQL Gateway (aka DBMS_EPG). The EPG should not be used in production deployments, and should be disabled.

* Port 8090: In this tutorial, Tomcat is set up to use port 8090, since the default for Tomcat is port 8080, and this would conflict with EPG. It is explained in the article: "To avoid conflicts with Oracle XE running the Embedded PL/SQL Gateway on port 8080, change Tomcat's default port number to 8090 by editing the server.xml file. (Note: Because we will put Apache in front of Tomcat, we won't ever access Tomcat directly on port 8090, and we will soon disable EPG, but let's just avoid possible conflicts anyway by assigning different ports.)"

* Port 8009: This is not a typo. This is the port used by Tomcat to talk to the Apache server via the AJP protocol. Port number 8009 is the default for the AJP protocol in Tomcat. We therefore add this port number to the Apache configuration so it knows which port it should talk with Tomcat on. All traffic to Apache for the "/ords" folder will be redirected to Tomcat on port 8009.

Remember that the only ports that should be open in the firewall to the outside world is port 80 (for http) and port 443 (for https). And since you need to be able to login via ssh to administer the machine, you need to open port 22 (or whatever port you have assigned for ssh), but for this port you could also set additional restrictions such as only allowing certain IP addresses to login via ssh.

- Morten