# Oracle Database 23ai + Oracle Apex with Docker Compose

Oracle's latest long-term release now has a developer-focused version available. Hopefully, our pleads for simplicity for the new setup are starting to show.

***Note: The ORDS docker image is using ORDS 24.1 but with Apex 23.2. You can build your own image with the latest version of Apex or update the ORDS container to host the new 24.1 Apex images.*** [***See this section for the latter.***](https://ora-wtf.com/oracle-database-23ai-oracle-apex-with-docker-compose#heading-update-ords-apex-images-to-241)

I was able to modify my previous 21c docker setup with success.

Notable changes: no container registry login required, faster container runtime due to PDB being already set up, removal of Enterprise Manager. :(

I am using Ubuntu 22.04 fresh installation.

To start the container, we need to prepare a directory for the database files, which is mounted into the container and is persistent (so we can store and save everything, which is one of the basic things a database is used for). For this, I create a directory and set the userid and group id of the Oracle user (inside the container!)

## Setup a user for the Oracle database

```bash
sudo groupadd --system --gid 54321 oracle
sudo adduser --system --shell /usr/sbin/nologin --gid 54321 --uid 54321 oracle
```

## Create the required volume folders and permissions

```bash
mkdir ~/oracle
mkdir ~/oracle/db
mkdir ~/oracle/ords
mkdir ~/oracle/db/oradata
mkdir ~/oracle/ords/ords_config
mkdir ~/oracle/ords/ords_secrets
mkdir ~/oracle/db/startup
mkdir ~/oracle/db/setup
sudo chmod 777 ~/oracle -R
sudo chown oracle:oracle ~/oracle/db/oradata
```

## Setup firewall

```bash
sudo ufw allow 1521
# sudo ufw allow 5500 # Enterprise Manager is disabled in 23c Free :(
```

## Install Docker

```bash
sudo apt update

sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce -y
sudo systemctl status docker
sudo usermod -aG docker ${USER}

# Reload shell then:
docker ps
# If prompting for sudo something is incorrect.
```

## Install Docker Compose

```bash
## Compose

mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.3.3/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose

docker compose version
```

## Docker-compose.yaml

Replace &lt;PASSWORD&gt;, &lt;EMAIL&gt; below. If running for a CI/CD setup consider using the lite version `23.4.0.0-lite`

The `Lite` image has a smaller storage footprint than the `Full` image (~80% image size reduction) and a substantial improvement in image pull time. This image is useful in CI/CD scenarios and for simpler use cases where advanced database features are not required.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Each password should be different for security.</div>
</div>

```dockerfile
version: '3'
services:
  database:
    image: container-registry.oracle.com/database/free:23.4.0.0
    volumes:
      - ~/oracle/db/oradata:/opt/oracle/oradata # persistent oracle database data.
      - ~/oracle/db/startup:/opt/oracle/scripts/startup # A volume with custom scripts to be run after database startup.
      - ~/oracle/db/setup:/opt/oracle/scripts/setup #  A volume with custom scripts to be run after database setup.
    ports:
      - 1521:1521
      - 2484:2484 #SSL port
    restart: unless-stopped
    environment:
      - ORACLE_PWD=<PASSWORD> # use for Sys, System users
    networks:
      - oracle_ntw
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
  ords:
    image: container-registry.oracle.com/database/ords:24.2.2
    volumes:
      - ~/oracle/ords/ords_secrets:/opt/oracle/variables 
      - ~/oracle/ords/ords_config:/etc/ords/config/
    environment:
      - ORDS_PWD="<PASSWORD>"
      - APEX_ADMIN_EMAIL=<EMAIL>
      - APEX_ADMIN_PWD=<PASSWORD>
    ports:
      - 8181:8181
    depends_on:
      - database
    restart: unless-stopped
    networks:
      - oracle_ntw
networks:
    oracle_ntw:
        # use the bridge driver
        driver: bridge
```

We need the DB to start before ORDS so run `docker compose up database`

Wait until you see

```bash
oracle-database-1 | ######################### 
oracle-database-1 | DATABASE IS READY TO USE! 
oracle-database-1 | #########################
```

## ORDS Setup

Create a conn\_string.txt to load the credentials into ORDS. This file is deleted when the container starts, and must be replaced if wrong values are provided. Replace &lt;PASSWORD&gt;

Note: the default 23c SID is `FREEPDB1`

`database` is the service name from the docker-compose file

```bash
## ORDS

# mkdir ords_secrets ords_config
echo 'CONN_STRING=sys/<PASSWORD>@database:1521/FREEPDB1' > ~/oracle/ords/ords_secrets/conn_string.txt
```

If everything is correct then use `docker compose up` to start the remaining ORDS service.

Use the below login credentials for first-time login to APEX service: (Also found in the container logs)

`Workspace: internal`

`User:      ADMIN`

`Password:  Welcome_1`

Create your workspace and enjoy getting the basic's started. :)

---

## Misc Commands

View ORDS logs:

`docker exec -it oracle-ords-1 tail -f /tmp/install_container.log`

View logs of the database, limit to last 1k:  
`docker logs oracle-database-1 -n 1000`

To access the running container:

`docker exec -it oracle-database-1 /bin/bash`

Edit ORDS Config:

`nano ords/ords_config/databases/default/pool.xml`

Setup ORDS SSL:

```bash
## ORDS SSL
cd ~/oracle/ords
mkdir -p ords_config/ssl
cp cert_file.crt ords_config/ssl/cert.crt
cp key_file.key  ords_config/ssl/key.key
```

## Update ORDS Apex images to 24.1

Since ORDS docker image has Apex bundled together you will have to point the ORDS config to look at new version 24.1 images. Otherwise you will be prompted of an error on login.

Run the standard Apex upgrade path to install the new Apex 24 schema. After installation, we have to update the images on the web server.

Download apex\_latest.zip from the Oracle website, and mount the images directory in docker-compose file:

```dockerfile
- ~/apex_latest/images/:/opt/oracle/apex_images/24/
```

Now edit the ORDS config to assign `apex-images` config variable to the path inside the container.

`nano ords/ords_config/global/settings.xml`

add entry:`<entry key="apex-images">/opt/oracle/apex/images/24/</entry>`

Restart the docker container

Most importantly, clear the browser cache. All new images and icons will be available.

### References

[https://blogs.oracle.com/coretec/post/oracle-database-with-docker](https://blogs.oracle.com/coretec/post/oracle-database-with-docker)

[https://docs.oracle.com/en/database/oracle/oracle-database/21/deeck/index.html#GUID-375BBD63-755D-4477-AE2A-13384B7B1631](https://docs.oracle.com/en/database/oracle/oracle-database/21/deeck/index.html#GUID-375BBD63-755D-4477-AE2A-13384B7B1631)

[https://docs.oracle.com/en/operating-systems/oracle-linux/docker/docker-InstallingOracleContainerRuntimeforDocker.html#docker-install-storage-driver](https://docs.oracle.com/en/operating-systems/oracle-linux/docker/docker-InstallingOracleContainerRuntimeforDocker.html#docker-install-storage-driver)

[https://datmt.com/backend/how-to-install-oracle-database-on-docker/](https://datmt.com/backend/how-to-install-oracle-database-on-docker/)

[https://docs.oracle.com/en/operating-systems/oracle-linux/docker/docker-SecurityRecommendations.html#docker-security-images](https://docs.oracle.com/en/operating-systems/oracle-linux/docker/docker-SecurityRecommendations.html#docker-security-images)
