Skip to Main Content

Spin Up an Oracle APEX Local Development Environment

If you spend any time developing with Oracle APEX, you likely already have a preferred way to run a local environment. The Oracle community has produced several excellent local setups (e.g., Docker/Podman-based options) over the years, and we are fortunate to have Oracle Container Registry making this very easy.

However, everyone has their own specific preferences for how a local stack should be managed. Recently, I wanted to spin up the 26ai Free database, ORDS, and the new APEX 26.1, but I wanted to eliminate as much of the manual post-installation clicking as possible.

I ended up building my own Docker Compose environment to automate this process. I am sharing it today on GitHub as just one more option for the community. Please keep in mind that this setup is intended strictly for local development, testing, and learning purposes—it is not secured or optimized for production use. If you prefer an automated, configuration-driven approach to your local stack, this might fit nicely into your workflow.

The Problem with Tearing Down and Rebuilding

Local development containers are meant to be disposable. However, whenever I rebuilt a fresh local APEX development environment, I found myself repeating the same tedious steps: configuring APEX instance parameters and creating workspaces.

The Goal: Configuration as Code

Rather than writing extensive setup guides or manual SQL scripts, I wanted to make the environment declarative, much like the Oracle APEX low-code development platform itself.

The core philosophy of this repository is that your desired state should be defined in simple files before the database even starts.

Instead of configuring APEX through the browser or SQL scripts, you simply define what you want in YAML templates:

  • Need a new workspace? Add it to the configuration file.
  • Need a specific developer user assigned to that workspace? Define it upfront.
  • Need to toggle an instance-level parameter like Database Actions? Set it before you spin up the container.

How does this actually work under the hood? At the highest level, Docker Compose acts as the orchestrator. It allows you to define and manage multiple interconnected containers (like the Oracle Database and ORDS) as a single unified application. Instead of running e.g. command-line scripts to link containers, Docker Compose reads your configuration files to automatically wire up the internal networks, mount persistent storage volumes, and inject the correct environment variables.

Once Docker Compose starts the environment, the database is automatically set up. Next, the ORDS container takes over to automatically install APEX into the database. After this base installation is complete, the custom scripts located in the ords-entrypoint.d directory take over. These scripts parse YAML configuration files and dynamically generate the corresponding SQL statements. The container then executes these generated SQL files against the database to handle the necessary schema creations, grant the required privileges, provision the APEX workspaces, and set up APEX instance parameters exactly as specified.

You can copy these generated SQL files from the ORDS container and reuse them to easily provision non-local environments, like a shared development or test database.

New schemas created by this process are REST-enabled. This unlocks the browser-based Database Actions and allows you to start developing e.g. ORDS REST modules. You don't necessarily need to install local client tools like SQLcl or SQL Developer for VS Code on your machine to start working—though having them is still incredibly helpful!

Available on GitHub

There is no shortage of great ways to set up local environments, but if you appreciate a YAML-driven, automated approach, feel free to give this one a try.

GitHub Repository: local-apex-dev (v1.1 Release)

(Note: If you are reading this in the future, be sure to check the main branch for the latest updates and features!)

Feedback, forks, and pull requests are always welcome!

Comments

No comments yet on this post