Fast-path to developing with Oracle Application Express and Multilingual Engine

January 23, 2024 | 5 minute read
Text Size 100%:

Support for In-Database JavaScript is one of the most exciting new features in Oracle Database 23c Free. JavaScript is the first language supported by Oracle Multilingual Engine (MLE), powered by GraalVM. Oracle Application Express, or APEX for short, was one of the first platforms to support server-side JavaScript. If you want to get started developing using MLE and APEX without having to concern yourself with the installation, using container images is the fastest way to create a lab environment. It can be as simple as podman-compose up.

This post describes a fast path to getting a development environment to experiment with MLE and APEX using Docker Compose. Why compose? Because it can be used to consistently tie multiple container images together, including network & and name resolution, with a single command to start and stop containers. Please note that the compose format is not exclusively tied to Docker. This post was created using podman-compose on Oracle Linux 9.3.

Lab environment

This post was written using Oracle Linux 9.3 (x86-64) and

  • podman 4.6.1
  • podman-compose 1.0.6
  • podman-plugins 4.6.1
  • kernel-uk 5.15.0-201.135.6.el9uek.x86_64

These were installed using the standard package sources and were current at the time of this writing.

Oracle's Container Registry

Oracle provides a container registry for all container images used in this post. These are:

| Software | Usage Instructions | | -- | -- | | Oracle Database 23c Free | | | Oracle REST Data Services | |

Save yourself some time by pulling the container images from the registry and read on while they are downloading.

podman pull
podman pull

This might take a minute, depending on your bandwidth.


The compose file you'll see in this article creates two services based on the container images just downloaded:

  1. Oracle Database 23c Free (23.3.0)
  2. ORDS (23.4.0)

If you read this sometime after its publication, versions might have changed, but the overall principles should still apply.

The database provided by the container image will automatically create a single Pluggable Database (PDB) named freepdb1 when the container is started for the first time. The ORDS container image will automatically install APEX and ORDS into that PDB.

Ensure you have enough memory and disk space to run both containers.

Compose File

The following is an example of a minimally viable compose file. It doesn't do anything to harden the setup, there is no TLS (aka SSL), and the initial DBA passwords are defined in clear text. In other words, it is utterly unfit for production use. Please use it as your lab only.

version: "3"
            - 1521:1521
            - ORACLE_PWD=secretPassword
            - oradata-vol:/opt/oracle/oradata
            - backend

            - backend
            - ords-config-vol:/etc/ords/config
            - ./setup:/opt/oracle/variables:Z
            - 8181:8181


Store the file in a directory of your liking as compose.yml.

If you are unfamiliar with compose files, I suggest you look at the reference documentation.

Note that the Oracle DBA passwords are provided as part of this file, which is a Very Bad Practice and one of the reasons this file isn't suitable for production use. However, the passwords are used for the initial setup only; later, you can read how to reset them after the setup is complete. Unfortunately (Podman) secrets didn't work with the compose file, or else they would have been used.

Firstboot: installing APEX and ORDS

The database must be started first. Otherwise, the ORDS container cannot perform the APEX installation.

podman-compose up dbfree

The database should be up and running in less than a minute - the first step has been completed. Now, please create a directory named setup in the same directory storing the compose.yml file and create setup/conn_string.txt with the following contents:


The connection string in this file is used to install APEX and ORDS in freepdb1. Start the installation by bringing the ORDS container up.

podman-compose up ords

The ORDS container will detect the absence of a configuration and use the information in conn_string.txt to connect to the database and perform the APEX and ORDS installation. After the installation has been completed, you can test if it was successful by connecting to ORDS using your favourite browser. How do you know if the installer completed its work? Your terminal should show you something along these lines:


2024-01-11T10:51:09.473Z INFO        

Mapped local pools from /etc/ords/config/databases:
  /ords/                              => default                        => VALID     

2024-01-11T10:51:09.522Z INFO        Oracle REST Data Services initialized
Oracle REST Data Services version : 23.4.0.r3461619
Oracle REST Data Services server info: jetty/10.0.18
Oracle REST Data Services java info: Java HotSpot(TM) 64-Bit Server VM 11.0.15+8-LTS-149

Once you're happy that your installation worked, remove setup/conn_string.txt if it still exists. Otherwise, the ORDS container assumes that the installation has to be repeated. You should also change the DBA passwords as described in the container image's documentation.

You should also ensure the default APEX admin password is changed. Log in to the ADMIN interface as described in the documentation change the password.

Next steps

After the validation of your environment, you can perform multiple steps:

  1. Change all passwords as mentioned above if you haven't already
  2. Stop the environment using podman-compose stop
  3. Check the status using podman-compose ps
  4. Start the APEX environment when you need it using podman-compose start
  5. Check the logs of either container using podman logs. Adding the -f flag tails the log

Have fun!


Getting to a working APEX development environment for your lab with just two commands (initially, later, it's just one) is quite the time saver. Please remember that the procedure described in this post is merely suitable for your own lab. Have fun!

Martin Bach

Martin is a product manager at Oracle helping customers in Europe and around the world address their IT related problems. He is most interested in cloud technology, DevOps and how these can be used best with Oracle technology.

Previous Post

Using a proxy with the JavaScript fetch API and UTL_HTTP

Martin Bach | 5 min read

Next Post

The topmost requested Oracle-related books of 2023

Lisa Goldstein | 2 min read