I’m a huge fan of Oracle REST Data Services (ORDS) and use it extensively. I’m also very fond of the official container image, significantly simplifying the way I work with ORDS. The best thing is: I don’t need to concern myself with the REST and APEX installation – the image is clever enough to do that for me when I point it to a database.
Sometimes, however, I misconfigure things, and some troubleshooting is needed. Let’s have a look how to do that.
As a prerequisite, you need an Oracle Database to connect to. In my case I used a simple compose file to create the Oracle Database 23ai instance. I didn’t start ORDS via compose, too, to keep things simple.
Important: this post applies to ORDS 25.1.0 up to, and including 25.2.2. Previous versions of this image behaved differently. ORDS 25.2.3 provides a debug flag you can set and safe yourself some time.
Podman compose tells me that the database is up and running:
(.venv) martin@zenbook:~/devel/javascript/javascript-blogposts/database$ podman-compose -f compose-podman-db.yml ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a444596a4a3 docker.io/gvenzl/oracle-free:23.8 9 minutes ago Up 9 minutes (healthy) 0.0.0.0:1521->1521/tcp database_oracle_1
Looking at the compose file I can extract the necessary details to start the ORDS container:
- the podman network name to connect to the database
- the Oracle username and password to facilitate the automatic installation
Let’s get started:
$ podman run --rm -it --name some-ords \
> -p 8080:8080 -p 8443:8443 -p 27017:27017 \
> -e CONN_STRING=oracle -e ORACLE_PWD=secret \
> --network database_backend \
> container-registry.oracle.com/database/ords:25.2.0
INFO : Testing your connection variables.
/bin/bash: line 1: tput: command not found
/bin/bash: line 1: tput: command not found
ERROR: Cannot connect to the database with the shared credentials it is necessary to meet one of the below requirements:
- CONN_STRING and ORACLE_PWD variables declared.
- DBHOST, DBPORT, DBSERVICENAME, and ORACLE_PWD variables declared.
Please refer to the documentation if you’re unsure about the options to provide to the ORDS image.
As you can see, this didn’t work. But what exactly failed as part of the installation? Container images are instructed to run something when you start them. These things are detailed as entrypoints and commands (detailed in the Dockerfile reference). If the image starts a script, and you cannot influence the execution, you need to pass a different one to the image for debugging. Inspecting the ORDS image I can make out what its entrypoint is:
podman inspect container-registry.oracle.com/database/ords:25.2.0 | jq .[].Config
{
"User": "oracle",
"Env": [
"PATH=/opt/graalvm-ee-java17/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"ORDS_VER=25.2.0"
],
"Entrypoint": [
"docker-entrypoint.sh"
],
"WorkingDir": "/opt/oracle/ords",
"Labels": {
"io.buildah.version": "1.33.11"
}
}
Since the entrypoint script isn’t shown with its fully qualified path, it’s got to the in the user’s path. Maybe I can find it anyway. But first I need to tell the image to use bash as my new entrypoint.
podman run --rm -it --name some-ords \
-p 8080:8080 -p 8443:8443 -p 27017:27017 \
-e CONN_STRING=oracle -e ORACLE_PWD=secret \
--network database_backend \
--entrypoint bash \
container-registry.oracle.com/database/ords:25.2.0
The key to circumventing the default entrypoint is to specify your own – bash in the above example. Now I can run the entrypoint script with additional logging/debugging enabled. But first I need to find where the docker-entrypoint.sh script lives
IFS=':' read -r -a directories <<< "$PATH"
for dir in "${directories[@]}"; do
> echo checking if the entrypoint script lives in $dir
> [[ -f "${dir}/docker-entrypoint.sh" ]] && echo found it in "${dir}"
> done
checking if the entrypoint script lives in /home/oracle/.local/bin
checking if the entrypoint script lives in /home/oracle/bin
checking if the entrypoint script lives in /opt/graalvm-ee-java17/bin/
checking if the entrypoint script lives in /usr/local/sbin
checking if the entrypoint script lives in /usr/local/bin
checking if the entrypoint script lives in /usr/sbin
checking if the entrypoint script lives in /usr/bin
found it in /usr/bin
checking if the entrypoint script lives in /sbin
checking if the entrypoint script lives in /bin
found it in /bin
It appears to live in /usr/bin – let’s try it
bash -xv /usr/bin/docker-entrypoint.sh
...
+ _run_script
+ '[' '' = '' ']'
+ '[' '!' -z ']'
+ '[' '!' -z oracle']'
+ '[' '!' -z secret ']'
+ mkdir -p /tmp/install_logs
+ _test_database
+ printf '%s%s\n' 'INFO : ' 'Testing your connection variables.'
INFO : Testing your connection variables.
++ _dbconnect_var
++ '[' -n secret ']'
++ '[' -n '' ']'
++ '[' -n oracle ']'
++ echo conn_type_string
++ cut -d_ -f 3
+ CONN_TYPE=string
+ case "${CONN_TYPE}" in
+ sql /nolog
+ RESULT=2
+ '[' 2 -eq 0 ']'
+ _connection_error
+ printf '\a%s%s\n' 'ERROR: ' 'Cannot connect to the database with the shared credentials it is necessary to meet one of the below requirements:'
I admit this was fairly obvious, the CONN_STRING merely named the database hostname (oracle), failing to specify the service name… Once that’s fixed the installation proceeds normally. This time however I don’t need to use the custom entrypoint:
$ podman run --rm -it --name some-ords \
> -p 8080:8080 -p 8443:8443 -p 27017:27017 \
> -e CONN_STRING=oracle/freepdb1 -e ORACLE_PWD=secret \
> --network database_backend \
> container-registry.oracle.com/database/ords:25.2.0
INFO : Testing your connection variables.
/bin/bash: line 1: tput: command not found
/bin/bash: line 1: tput: command not found
INFO : Database connection established.
/bin/bash: line 1: tput: command not found
/bin/bash: line 1: tput: command not found
INFO : The Oracle REST Data Services are not installed on your database.
INFO : Installing The Oracle REST Data Services 25.2.0.
INFO : The Oracle REST Data Services 25.2.0 has been installed correctly on your database.
INFO : Starting the Oracle REST Data Services instance.
2025-08-01T07:39:40Z INFO ORDS has not detected the option '--config' and this will be set up to the default directory.
ORDS: Release 25.2 Production on Fri Aug 01 07:39:41 2025
Note that the above command creates a throw-away container instance. It must be amended if you want to preserve the container and its configuration. It also doesn’t adhere to industry best practices concerning the use of sensitive information. Please refer to the ORDS image’s documentation for details how to do that.
Happy troubleshooting!