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.

# install Oracle XE 11g on CentOS
# assumes the installation file has already been copied to /u01/download
# create Oracle user and groups
groupadd oinstall
groupadd dba
useradd -g oinstall -G dba,oinstall oracle
chown -R oracle:oinstall /u01
# change the password
passwd oracle
# unzip the installation files
cd /u01/download
unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
cd /u01/download/Disk1
# run installation
rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
# run the configuration script
# accept the defaults (unless you know what you are doing!)
/etc/init.d/oracle-xe configure
view raw xe_install.sh hosted with ❤ by GitHub


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.

# setup Oracle environment in bash profile to be able to access sqlplus from anywhere
# http://stackoverflow.com/questions/16823591/how-to-add-lines-to-end-of-file-linux
# this adds the Oracle environment variables to the "oracle" user, but you may also want to add it to root or any other users
echo '. /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh' >> /home/oracle/.bash_profile


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

# initial test of Oracle XE database after install
# become the "oracle" user
su - oracle
# connect to database
sqlplus /nolog
connect sys as sysdba
-- basic query to see stuff working
select sysdate, sys_context('userenv', 'server_host') from dual;
-- check components and versions
select comp_id, version, status
from dba_registry;
-- check users
select username, account_status
from dba_users
order by 1;


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:

# install Oracle Java JDK
# see http://stackoverflow.com/questions/20901442/how-to-install-jdk-in-centos
# remove OpenJDK
yum remove java*
# assume .rpm file is already copied to /u01/download
cd /u01/download
rpm -ivh jdk-7u79-linux-x64.rpm
# see the java_env.sh script for how to add the Java environment to the bash profile
# check the java version installed
java -version
To have the Java binaries available from anywhere, we add the Java path to the bash profile of the root user:

# setup Java environment in bash profile to be able to access java from anywhere
# http://stackoverflow.com/questions/16823591/how-to-add-lines-to-end-of-file-linux
# http://www.davidghedini.com/pg/entry/install_tomcat_7_on_centos
echo "JAVA_HOME=/usr/java/latest" >> /root/.bash_profile
echo "export JAVA_HOME" >> /root/.bash_profile
echo "PATH=$JAVA_HOME/bin:$PATH" >> /root/.bash_profile
echo "export PATH" >> /root/.bash_profile
view raw java_env.sh hosted with ❤ by GitHub

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.

# download and install Tomcat
cd /u01/download
# see https://tomcat.apache.org/download-70.cgi for latest version
wget "http://www.eu.apache.org/dist/tomcat/tomcat-7/v7.0.64/bin/apache-tomcat-7.0.64.zip"
# copy file and unzip it
cp apache-tomcat-7.0.64.zip /usr/share/apache-tomcat-7.0.64.zip
cd /usr/share
mkdir tomcat7
unzip apache-tomcat-7.0.64.zip -d tomcat7
# make a symbolic link so we can reference the latest version using /latest instead of a specific version
cd /usr/share/tomcat7
ln -s apache-tomcat-7.0.64 latest
# create tomcat group and user
groupadd tomcat
useradd -s /bin/bash -g tomcat tomcat
chown -Rf tomcat:tomcat /usr/share/tomcat7/apache-tomcat-7.0.64/
# set password
passwd tomcat
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.

<Connector port="8090" protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="400"
compression="on"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript"
redirectPort="8443"
server="whateverFakeName"
URIEncoding="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/

#!/bin/bash
# description: Tomcat Start Stop Restart
# processname: tomcat
# chkconfig: 234 20 80
JAVA_HOME=/usr/java/latest
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
CATALINA_HOME=/usr/share/tomcat7/latest
case $1 in
start)
/bin/su tomcat $CATALINA_HOME/bin/startup.sh
;;
stop)
/bin/su tomcat $CATALINA_HOME/bin/shutdown.sh
;;
restart)
/bin/su tomcat $CATALINA_HOME/bin/shutdown.sh
/bin/su tomcat $CATALINA_HOME/bin/startup.sh
;;
esac
exit 0

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

# assumes you have created a service script at /etc/init.d/tomcat
cd /etc/init.d/
# make the script executable
chmod 755 tomcat
# set to start at boot time
chkconfig --add tomcat
chkconfig --level 234 tomcat on
# verify it
chkconfig --list tomcat
# start tomcat
service tomcat start
# note: this gave error "Cannot find /usr/share/tomcat7/latest/bin/catalina.sh
# The file is absent or does not have execute permission"
# see http://louis-sawtell.com/content/tomcat-cannot-find-bincatalinash
cd /usr/share/tomcat7/latest/bin
chmod +x *.sh
chmod +x *.jar
# stop tomcat
service tomcat stop
# restart tomcat
service tomcat restart
# check logfile and look for any errors
cat /usr/share/tomcat7/latest/logs/catalina.out

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.

# install Oracle Rest Data Services (ORDS)
# assumes you have already downloaded ORDS from the Oracle website
# and copied the ORDS zip file to the server
# unzip the files, and move them into a dedicated directory
cd /u01/download
mkdir ords210
unzip ords.2.0.10.289.08.09.zip -d ords210
mv /u01/download/ords210 /u01/ords
# Run the ORDS configuration before deployment
cd /u01/ords
java -jar ords.war
# the ORDS configuration "wizard" will now start
# when prompted for ORDS configuration directory, enter /u01/ords/config
# then provide the necessary connection info (server, port, sid, passwords, etc)
# the values get stored in /u01/ords/config/defaults.xml and may be modified there
# IMPORTANT: "RESTful Services" is required by Apex 5,
# so enable this by specifying passwords for the APEX_LISTENER and APEX_REST_PUBLIC_USER when prompted
# for a DEV environment, open the config file and set "debug.printDebugToScreen" to "true" to get detailed errors on screen
# for a production environment, this setting should be left as "false"
# the "tomcat" user (created as part of Tomcat install) needs write access to the /config/ folder
chown -R tomcat:tomcat /u01/ords/config
# copy the .war into the webapps folder
cp ords.war /usr/share/tomcat7/latest/webapps/ords.war
# restart Tomcat to deploy the .war
service tomcat restart
# if using Tomcat standalone, copy the Apex image files to Tomcat "i" folder
# NOTE: no need to do this if using Apache as web server in front of Tomcat
# cp -r /u01/download/apex/images /usr/share/tomcat7/latest/webapps/i/

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:

# install Apache on CentOS
# see https://www.linode.com/docs/websites/apache/apache-2-web-server-on-centos-6
# install
yum install httpd -y
# start the server
service httpd start
# set to start automatically on boot
chkconfig httpd on
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.

# customized Apache configuration
# add this to the end of /etc/httpd/conf/httpd.conf
# or put it in a separate file such as /etc/httpd/conf.d/apex.conf
# disable sensitive version info
ServerSignature Off
ServerTokens Prod
# standard alias for Apex image files
Alias /i/ "/var/www/apex/images/"
# forward dynamic (ORDS) requests to Tomcat
<VirtualHost *:80>
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /ords ajp://localhost:8009/ords
ProxyPassReverse /ords ajp://localhost:8009/ords
</VirtualHost>
# enable compression of static content
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css text/javascript
</IfModule>
# enable client caching of static content
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/png "access plus 7 days"
ExpiresByType text/css "access plus 7 days"
ExpiresByType text/javascript "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
ExpiresByType application/x-javascript "access plus 7 days"
</IfModule>

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.

# install (or upgrade) Apex on Oracle XE on CentOS
# change to the "oracle" user (created as part of XE installation)
su - oracle
# assumes you have already copied Apex installation file to server
cd /u01/download
unzip apex_5.0.1_en.zip
cd apex
# start sqlplus and run the installation script
sqlplus /nolog
# connect sys as sysdba
# -- run the following for a full installation (including the Application Builder)
# @apexins.sql SYSAUX SYSAUX TEMP /i/
# -- run the following for a runtime-only installation (for production environments)
# @apxrtins.sql SYSAUX SYSAUX TEMP /i/
# check the installation log (last 200 lines)
tail -n 200 *.log
# rename the folder so we can have multiple versions downloaded (apex501, apex502, apex60, etc)
cd /u01/download/
mv apex apex501
# now remember to copy the Apex images files into the web server "/i/" folder
view raw apex_install.sh hosted with ❤ by GitHub

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

-- run as SYS
-- set up service profile to avoid expiring passwords
create profile web_service_profile
limit password_life_time unlimited;
alter user apex_public_user profile web_service_profile;
alter user apex_listener profile web_service_profile;
alter user apex_rest_public_user profile web_service_profile;
-- unlock the apex public user and set a password
alter user apex_public_user account unlock;
alter user apex_public_user identified by pick_a_password;
-- remove previous versions of Apex, if desired
-- drop user apex_040000 cascade;
-- drop user apex_040100 cascade;
-- drop user apex_040200 cascade;
We need to copy all the static Apex files (images, CSS, Javascript) to the Apache web folder.

# copy the Apex image files to corresponding Apache web folder
# assumes you have unzipped the Apex files already
mkdir -p /var/www/apex/images
cp -rf /u01/download/apex501/images/ /var/www/apex
# note: make sure you have set up an Apache alias "/i/" to the /images folder above
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:

# configure ORDS RESTful Services for Apex
# see https://docs.oracle.com/cd/E59726_01/install.50/e39144/listener.htm#HTMIG29335
su - oracle
cd /u01/download/apex501
sqlplus /nolog
connect sys as sysdba
@apex_rest_config.sql
Now (finally!), if everything works, we should be able to access the new Apex installation by going to the following URL:

  http://servername/ords/apex

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!

Tuesday, June 9, 2015

Installing Oracle XE, ORDS and Apex on CentOS - Part One: Preparation

This is part one 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.


Provisioning the server


First of all, we need a server to install the software on. There are many hosting providers that offer cheap Linux servers. I have been trying out DigitalOcean, where you can get a nice little server suitable for Oracle XE for as little as USD 10 per month. After you sign up, a new server complete with the operating system installed can be up and running in as little as 50 seconds (!). It is also very easy to scale up (or down) the server according to your needs.

A note on security


Linux security is a big topic in itself. In order to keep this blog post short and sweet, I will describe some security recommendations in a separate blog post. But in general, always use strong passwords (and/or certificates and/or two-factor authentication), never install more components than you need, and always apply the principles of minimal privileges and defense in-depth.

Creating the server


First you need to sign up to DigitalOcean (or another cloud provider of your choice). The sign-up process is quick and painless. I like that you can pay DigitalOcean using PayPal, so you don't need to give them your credit card details.




After signing up, create a new server (called a "droplet" in DigitalOcean's terminology).
When choosing a server size, keep in mind that Oracle XE cannot use more than 1 GB of memory. As we will see later, you can happily run Oracle XE together with Apache, Tomcat and ORDS, all on a 1GB server. (It is tempting to compare that to, say, the minimum requirements for Sharepoint... but let's stay on topic! :-)



You get to choose the physical location of the server. Select a data center that is geographically close to you and your users, as this will obviously reduce data transfer times across the network.

Select the 64-bit version of CentOS 6.5 (while CentOS 7.x is also available, this is not in widespread use yet, so I'm sticking with the more well-known version 6.x for now).


Logging in to the new server


When the server is created, you get the "root" password emailed to you, so you can login to the server. The root user on Linux is similar to the local Administrator account in Windows. As we will get back to later, it is actually recommended not to use the root user regularly, and only "become root" (via the "sudo" command or via other users defined as administrators in the "sudoers" file) when necessary. To keep things simple, we'll use the root user for now, but get back to security best practices in a later post.

Logging in to the new server is done via "ssh" (secure shell). If you have a Mac, just open a terminal and type ssh root@server_ip_address and when prompted enter your password to login.

If you have a Windows machine, there is no built-in ssh client, so you need to install some additional software. I recommend pimping up your Windows console window with cmder, a good-looking console emulator (make sure you download the full version of cmder that bundles the "msysgit" suite which includes a bunch of Unix commands, including ssh). Once you have cmder installed, use the same command as for the Mac above to login.

If you managed to login as root, run the command ls -la / and you should see something similar to this:



Congratulations, you now have your very own Linux server to play around with! :-)

Check out these links for more information:

Installing some basic utils


After logging in to the new server for the first time, let's install some basic utilities that we will need later. In CentOS, the "package manager" that you use to download and install software from a standard repository is called "yum". Run the following commands:

#install some basic utils
yum install nano -y
yum install unzip -y
yum install bc -y
yum install wget -y

The basic utilities include "nano" (a text editor which I prefer over the default "vim" editor; the latter is probably very productive for power users, but a pain in the ass to use unless you remember a series of cryptic commands -- a bit like Linux in general I guess!), as well as "wget" (to get/download files from the Internet using the command line), "unzip" (self-explanatory) and "bc" (a basic calculator).

Setting the server time zone


It's useful to have the server date and time automatically synchronized based on a remote server, so let's set up Network Time Protocol (NTP).

# setup Network Time Protocol (NTP)
# see http://www.uptimemadeeasy.com/networking/setup-ntp-on-centos-linux/
# check current date/time
date
# setup time zone
mv /etc/localtime /etc/localtime.bkp
cp /usr/share/zoneinfo/Europe/Oslo /etc/localtime
# install NTP
yum install ntp -y
chkconfig ntpd on
cat >> /etc/ntp.conf << EOF
server 0.no.pool.ntp.org
server 1.no.pool.ntp.org
server 2.no.pool.ntp.org
server 3.no.pool.ntp.org
EOF
cat >> /etc/ntp/step-tickers << EOF
0.no.pool.ntp.org
1.no.pool.ntp.org
2.no.pool.ntp.org
3.no.pool.ntp.org
EOF
service ntpd restart
# wait 5-10 minutes and check current date/time again
date
view raw centos_ntp.sh hosted with ❤ by GitHub

Adding swap space


Oracle XE needs a certain amount of swap space (a file where the operating system can "swap" stuff from memory to disk when there is too little physical memory available), so let's set that up.

# Oracle XE requires a swap file of at least twice the size of physical memory
# see https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-centos-6
# check current swap file
swapon -s
# check available space
df
# setup 2GB swap file
dd if=/dev/zero of=/swapfile bs=1024 count=2048k
mkswap /swapfile
swapon /swapfile
# check swap file again
swapon -s
# make the swap file permanent
# see http://blog.allanglesit.com/2012/05/bash-programmatically-add-entries-in-fstab/
echo "/swapfile swap swap defaults 0 0" >> /etc/fstab
# prevent file from being world-readable
chown root:root /swapfile
chmod 0600 /swapfile

Setting up the fully qualified domain name (FQDN)


The "hosts" file contains a mapping between IP addresses and domain names. We need to make sure that the server's IP address is mapped to a "fully qualified domain name" (FQDN), otherwise the Oracle XE installation will fail, as described in detail here.

So, to make sure we have a fully qualified domain name in our hosts file, run nano /etc/hosts and put in a line with your IP address and your server name.

# sample /etc/hosts file
# see http://unix.stackexchange.com/questions/13046/format-of-etc-hosts-on-linux-different-from-windows
# IPv4
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
# IPv6
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# put your IP address and your hostname and aliases below
1.2.3.4 myserver.mydomain.example myserver

Setting up a firewall


We should only allow access to the server on the ports that we need. For a typical web server, this will be ports 80 and/or 443 (for HTTP and/or HTTPS), and port 22 (for SSH). Actually, you should change the default SSH port from 22 to some other random number, but we will get back to that later when we talk about hardening the server.

Tim Hall has written an excellent article about the Linux firewall, known as "iptables". Rather than repeat what Tim has already explained, I suggest you read his article, and then copy the following and save it as firewall.sh in the /root folder of your server. Then make the file executable by running chmod u+x /root/firewall.sh and then type ./root/firewall.sh to run the script.

#!/bin/bash
# see http://oracle-base.com/articles/linux/linux-firewall.php
# Set the default policies to allow everything while we set up new rules
# Prevents cutting yourself off when running from remote SSH
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# Flush any existing rules, leaving just the defaults
iptables -F
# Open port 22 for incoming SSH connections
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Open port 80 for incoming HTTP requests
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Open port 443 for incoming HTTPS requests
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# open port 8080 for Oracle XDB/EPG (uncomment if required)
#iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
# open port 1521 for SQL*Net (uncomment if required)
# NOTE: this is not needed for a web server, but can be useful for a dev environment
# replace 1.2.3.4 with your own client IP address
#iptables -A INPUT -p tcp --dport 1521 -s 1.2.3.4 -j ACCEPT
# *** Put any additions to the INPUT chain here
#
# *** End of additions to INPUT chain
# accept any localhost (loopback) calls
iptables -A INPUT -i lo -j ACCEPT
# allow any existing connection to remain
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# reset the default policies to stop all incoming and forward requests
iptables -P INPUT DROP
iptables -P FORWARD DROP
# accept any outbound requests from this server
iptables -P OUTPUT ACCEPT
# save the settings
service iptables save
# display the settings
iptables -L -v --line-numbers

Uploading Oracle software to the server


As the final part of preparing to install Oracle XE, ORDS and Apex on the server, we need to upload the different installation files to the server, so we can run them there.

Lets create a folder on the server where we can put the installation files:

mkdir -p /u01/download

The -p flag makes it possible to create two (or more) folders with a single command.

Why is the root folder called "u01"? Turns out this is a naming convention for Oracle software that goes way back. Linux folder names don't always make much sense, but I guess "u01" is as good as any.

And I guess there is an argument to be made for the sub-folder to be called "upload", as we will copy, or upload, stuff into it, but because it holds installation files that we would normally download directly to the server, I have called it "download".

The thing is, when downloading stuff from Oracle, you generally have to click an "Accept License Agreement" radio button and also login with an OTN account to actually get access to the file you wish to download. If it wasn't for this, the "wget" command could be used from the command line on the server to download the files directly to the server. As things stand, I find it best to download the desired software using a regular web browser on the client computer (ie my laptop) and then use the "scp" (secure copy) command to upload the files to the server.

So, go download the following software to your local computer:
  • Oracle Express Edition (XE) 11g for Linux x64
  • Java JDK 1.7 for Linux x64
  • Oracle Rest Data Services (ORDS) 2.0.10
  • Oracle Application Express (Apex) 5.0
I won't provide download links, as Oracle often changes the URLs on its web page and thus breaking the links, but a Google search should easily find these files on OTN. Download these to your local computer. Then copy the files to the server. If using a Mac, simply open a terminal window and use the scp command to copy the files:

# copy files from client to server
# assumes you have downloaded everything into an "install" folder
# adjust SSH port number, file paths, server/host name and version numbers as appropriate
cd /users/yourname/install/oracle
scp -P 22 oracle-xe-11.2.0-1.0.x86_64.rpm.zip root@server-name-or-ip:/u01/download/
scp -P 22 apex_5.0.1_en.zip root@server-name-or-ip:/u01/download/
scp -P 22 jdk-7u79-linux-x64.rpm root@server-name-or-ip:/u01/download/
scp -P 22 ords.2.0.10.289.08.09.zip root@server-name-or-ip:/u01/download/
If using Windows, either install a Unix emulation package (such as CygWin, cmder, msysgit, etc) that includes the scp command, or use the free WinSCP program if you prefer a graphical interface.

You should now have the installers for the various Oracle applications sitting in the /u01/download folder on the server.

Next Steps


Finally, we are now ready to install the Oracle software! This will be covered in part two of this series of blog posts.

Monday, June 8, 2015

Installing Oracle XE, ORDS and Apex on CentOS

I am writing 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.

This is perhaps better explained with an illustration of the setup:

Best of all, this setup consists only of free (license-free) software, and as you will see in this series of blog posts, you will be able to run it all on a cloud server for as little as USD 10 per month, serving hundreds of concurrent users. Gotta love Apex! :-)

The articles will be divided up as follows:

These blog posts will assume that you are familiar with Oracle and Apex, but that (like me) you are a relative newcomer when it comes to Linux. Keep in mind that with Linux, there are typically many alternative ways to accomplish things, and I have chosen the approaches that seem most straightforward to me. Your mileage may vary.

Stay tuned for part one!