Quick and Easy Setup – Oracle Xe and ORDS Using Docker

In this post I’ll show you how to stand up a couple of Docker containers running Oracle Database Xe and Oracle REST Data Services.

I will assume you are familiar with using Docker.  If not checkout this getting started guide.

Required Downloads

Oracle docker-images repository

Oracle provides a GitHub repository with a log of great examples.  Clone repository into the directory where you want to work.

Oracle Xe

You can find more information about Oracle Xe at https://www.oracle.com/rest.

Download the installer and place it in the docker-images/OracleDatabase/SingleInstance/dockerfiles/18.4.0 directory.

I’ll be using oracle-database-xe-18c-1.0-1.x86_64.rpm .

Oracle Rest Data Services (ORDS)

You can find more information about ORDS at https://www.oracle.com/rest.

Download the installer and place it in the docker-images/OracleRestDataServices/dockerfiles directory.

I’ll be using ords-19.1.0.092.1545.zip .

ORDS runs in Java, so you’ll need a Java JRE.  Download the Server JRE and place it in the docker-images/OracleJava/java-8 directory.

I’ll be using server-jre-8u211-linux-x64.tar.gz .

Docker Network

We’ll be running the database and ORDS in separate docker containers.  Define a docker network that they will use to communicate.

Oracle Database Xe

Change into the docker-images/OracleDatabase/SingleInstance/dockerfiles/18.4.0 directory.  Make sure the Oracle Xe install file (oracle-database-xe-18c-1.0-1.x86_64.rpm)  is in this directory.

This directory contains a Dockerfile.xe ready for us to use.  Take a minute and read through the file to see what it is going to do.

Build the Oracle Database Docker Image

The repository includes a shell script (buildDockerImage.sh) that you can use to build the docker image for Xe and other Oracle Databases.

It can be found in the docker-images/OracleDatabase/SingleInstance/dockerfiles directory.  Instructions for using this script can be found here.

I won’t be using the shell script.

The shell script will generate and run something similar to the following command that I will use:
*Notice the dot at the end, this is not a typo.

You can find an explanation of the Docker Build parameters here.

If this command doesn’t work for you, try using the shell script.

Verify that your image was created:

You should see something like this:

Once you have created the docker image it’s time to

Create a Docker Container

The following command is similar to the command you’ll find on the GitHub repository, but I’ve added a ‘-d’ to run the container in detached mode and I’m not defining any data volumes so my data will not persist when I delete the container.

You can find more information on the docker run command parameters here.

This will take a few minutes.

You can watch the progress and troubleshoot any issues with with this command:
(You can use the container name or id.)

When the last line of the log looks like this, you are ready to proceed.

Verify that your container was created and is up:

You should see something like this:

Now try to connect to your new Oracle Xe Database.

To connect with SQLcl:

Oracle REST Data Services

Before we create the ORDS container, we need to create a Docker image with Oracle Linux 7 and a Java JRE installed.  We will use this as a base image to build on top of.

Oracle Linux 7 and Java JRE Base Image

Change into the docker-images/OracleJava/java-8 directory.  In there you will find a Dockerfile and the server-jre-8uXXX-linux-x64.tar.gz file you downloaded earlier.

Take a minute and read through the Dockerfile to see what it is going to do.

Run the following to build the image:
*Notice the dot at the end, this is not a typo.

We do not need to create a Docker container from this image.  We will only need the image as a base for the ORDS image.

Verify that your image was created:

You should see something like this:

Now we can create the ORDS image.

ORDS

Change into the docker-images/OracleRestDataServices/dockerfiles directory.  In there you will find a Dockerfile and the ords-19.1.0.092.1545.zip file you downloaded earlier.

Take a minute and read through the Dockerfile to see what it is going to do.

Pre-Checks

Verify that the docker network we created earlier is ready:

You should see something like this.

Make sure your Xe database is running with the docker ps  command above.

If the Xe database container is not started, start it with the following command:

Build the ORDS Docker Image

The repository includes a shell script (buildDockerImage.sh) that you can use to build the ORDS docker image.

It can be found in the docker-images/OracleRestDataServices/dockerfiles directory.  Instructions for using this script can be found here.

If you choose to run the shell script instead of the below command, and there is not a Checksum file included for the version of ORDS you are installing, use the -i 1 command line argument to ignore the check.

The shell script will generate and run something similar to the following:
*Notice the dot at the end, this is not a typo.

Verify that your image was created:

You should see something like this:

Now we can create the ORDS container.

Create an ORDS Docker Container

The following command is similar to the command you’ll find on the GitHub repository, but I’ve added a ‘-d’ to run the container in detached mode and I’m not defining any data volumes so my data will not persist when I delete the container.

Make sure that you set  -e ORACLE_HOST=oracleXe to the name you used for the Oracle Xe Database container you created above.  ORDS will not find your database if you use localhost.  The containers are basically separate servers running on the same network --network=OrdsXeNet .

The parameter -e ORACLE_PWD="Password1_One" is the SYS/SYSTEM password you used when you created the Oracle Xe Database above.

The parameter -e ORDS_PWD="ORDS_Password1"  will be used as the ORDS admin password.  It does not need to be the same as the database password.

Verify that your container was created and is up:

You should see something like this:

You should now have an Oracle Xe database up and running in one container and an ORDS instance running in the other.

Connect to your database and test that ORDS is properly installed and configured.  A quick way to tell using Oracle SQL Developer is:

  1. Create a new database user.
  2. Connect as that user.
  3. Right click on the connection.
  4. Look towards the bottom of the menu for “REST Services”.

Have fun creating your new REST modules!

4 thoughts on “Quick and Easy Setup – Oracle Xe and ORDS Using Docker”

  1. Thank you very much for the install process, I’m having an issue with ports, so I changed the apex startup to use 8081.
    While to process is up, and I got browser

    http://otswjvydlq2apxl.tfayd.com:8081/ords/

    500 Internal Server Error
    An unexpected error with the following message occurred: null

    during container build , I got an error that port was in use so I altered to parameter for port setup.
    did I need to make the port change else where.

    How do I debug this.
    2019-04-28 05:30:58.114:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@2f686d1f{/ords,null,AVAILABLE}
    2019-04-28 05:30:58.114:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@5700d6b1{/,null,AVAILABLE}
    2019-04-28 05:30:58.115:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@5bcab519{/i,null,AVAILABLE}
    2019-04-28 05:30:58.116:INFO:oejs.AbstractNCSARequestLog:main: Opened /tmp/ords_log/ords_2019_04_28.log
    2019-04-28 05:30:58.124:INFO:oejs.AbstractConnector:main: Started ServerConnector@661972b0{HTTP/1.1,[http/1.1, h2c]}{0.0.0.0:8888}
    2019-04-28 05:30:58.124:INFO:oejs.Server:main: Started @3091ms
    Apr 28, 2019 5:52:53 AM
    SEVERE: null
    java.lang.NullPointerException
    at oracle.dbtools.url.mapping.db.DatabaseURLMappingBase.injectPLSQLGatewayConnection(DatabaseURLMappingBase.java:874)
    at oracle.dbtools.url.mapping.db.DatabaseURLMappingBase.addServices(DatabaseURLMappingBase.java:317)
    at oracle.dbtools.url.mapping.URLMappingBase.doFilter(URLMappingBase.java:79)
    at oracle.dbtools.url.mapping.filter.URLMappingFilter.doFilter(URLMappingFilter.java:130)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.auth.external.ExternalSessionFilter.doFilter(ExternalSessionFilter.java:59)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.rt.authentication.apex.ApexSessionQueryRewriteFilter.doFilter(ApexSessionQueryRewriteFilter.java:58)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.cors.CORSResponseFilter.doFilter(CORSResponseFilter.java:88)
    at oracle.dbtools.http.filters.HttpResponseFilter.doFilter(HttpResponseFilter.java:45)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.filters.AbsoluteLocationFilter.doFilter(AbsoluteLocationFilter.java:65)
    at oracle.dbtools.http.filters.HttpResponseFilter.doFilter(HttpResponseFilter.java:45)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.errors.ErrorPageFilter.doFilter(ErrorPageFilter.java:85)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.secure.ForceHttpsFilter.doFilter(ForceHttpsFilter.java:74)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.auth.ForceAuthFilter.doFilter(ForceAuthFilter.java:44)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.filters.Filters.filter(Filters.java:67)
    at oracle.dbtools.http.entrypoint.EntryPoint.service(EntryPoint.java:82)
    at oracle.dbtools.http.entrypoint.EntryPointServlet.service(EntryPointServlet.java:102)
    at oracle.dbtools.entrypoint.WebApplicationRequestEntryPoint.service(WebApplicationRequestEntryPoint.java:50)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:867)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
    at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:174)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:502)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:748)

    Apr 28, 2019 5:57:01 AM

    1. If you got a port conflict when you were doing the “docker run” command, that means there’s something else on your host machine listening on that port.
      Don’t change anything inside the docker image, change the port argument “-p 8080:8888” in the run command.

      The ORDS image by default is listening on and exposing port 8888. As long as you haven’t added anything else in the image that would be listening on port 8888 your image should build fine.

      When you create (run) the container with the port argument “-p 8080:8888” it is mapping the container port 8888 to 8080 on your host machine (localhost:8080). If your getting a port conflict at that point, change the 8080 part of that argument “-p 8081:8888” and it will map the new port to the container port 8888 (localhost:8081).

Leave a Reply

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