{"id":40798784,"url":"https://github.com/oraclesean/cloud-native-oracle","last_synced_at":"2026-01-21T20:41:46.452Z","repository":{"id":178456041,"uuid":"661880268","full_name":"oraclesean/cloud-native-oracle","owner":"oraclesean","description":"A repository of container image builds for Oracle databases, with support for Intel, Apple Silicon, and ARM processors.","archived":false,"fork":false,"pushed_at":"2025-04-21T16:41:48.000Z","size":73,"stargazers_count":33,"open_issues_count":2,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-21T17:41:56.934Z","etag":null,"topics":["cloud-native","cloud-native-database","container","container-image","containers","docker","docker-image","oracle","oracle-database","oracle-database-19c","oracle-database-docker"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oraclesean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-03T21:56:01.000Z","updated_at":"2025-04-21T16:41:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"732b75d5-41fa-40c4-a98d-2da2811ff532","html_url":"https://github.com/oraclesean/cloud-native-oracle","commit_stats":{"total_commits":33,"total_committers":2,"mean_commits":16.5,"dds":0.06060606060606055,"last_synced_commit":"ef7bbb99d0e31e5bc24ab22e47e11fa552fcd27d"},"previous_names":["oraclesean/cloud-native-oracle"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oraclesean/cloud-native-oracle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oraclesean%2Fcloud-native-oracle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oraclesean%2Fcloud-native-oracle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oraclesean%2Fcloud-native-oracle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oraclesean%2Fcloud-native-oracle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oraclesean","download_url":"https://codeload.github.com/oraclesean/cloud-native-oracle/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oraclesean%2Fcloud-native-oracle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28642223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloud-native","cloud-native-database","container","container-image","containers","docker","docker-image","oracle","oracle-database","oracle-database-19c","oracle-database-docker"],"created_at":"2026-01-21T20:41:46.356Z","updated_at":"2026-01-21T20:41:46.429Z","avatar_url":"https://github.com/oraclesean.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cloud-native-oracle\nA repository of container image builds for Oracle databases, with support for Intel, Apple Silicon, and ARM processors.\n\nJump to a section:\n- [Build an image](#build-an-image)\n  - [Build options and examples](#build-options-and-examples)\n  - [Build example: Apple Silicon/ARM systems](#build-example-macs-with-apple-siliconarm-systems)\n  - [Build example: Intel-based systems](#build-example-intel-based-systems-linux-mac-windows)\n  - [Note for OSX Users](#note-for-osx-users)\n- [Run a container](#run-a-container)\n  - [Examples: Run Oracle Database containers](#run-options-and-examples)\n- [Build and run on Apple Silicon/ARM systems](#example-for-apple-silicon)\n- [Directory structure](#directory-structure)\n  - [Where to put files](#file-placement)\n- [Why this Repo](#why-this-repo)\n  - [Features](#features)\n- [Errata](#errata)\n\n# Build an image\nOne [reason behind this repo](#why-this-repo) was reducing duplication. I wanted one set of scripts (not one-per-version) and less maintenance. That created a need for more than one Dockerfile (one per version) because building 11g and 21c images is *mostly* boilerplate, but not entirely, and Dockerfiles don't take variables. This repo solves that by taking boilerplate Dockerfile templates, processing them to substitute variables, and using them for the build. Named Dockerfiles enable matching .dockerignore files to limit context. But, every version still needs a unique Dockerfile. Rather than polluting the directory with versioned Dockerfiles run directly with `docker build` I'm hiding the complexity with temporary files and a shell script. Version and edition information passed to the script generates temporary Dockerfile and .dockerignore files, runs `docker build`, then deletes the temporary file.\n\nThis is a temporary workaround. I'm working on integrating new capabilities but until then, `buildDBImage.sh` manages Dockerfiles and builds.\n\n## Build options and examples\nTo build a database image, run `buildDBImage.sh` and pass optional values:\n```\n./buildDBImage.sh [Options]\n Options:\n        --build-arg stringArray     Set build-time variables\n    -d, --debug                     Turn on build debugging\n    -e, --edition string            Set the database edition\n                                        EE: Enterprise Edition (Default)\n                                        SE: Standard Edition\n                                        XE: Express Edition (Versions 11.2.0.2, 18.4, 23.1.0 only)\n        --force-patch string        Force patch download from MOS\n                                        all: Re-download all patches during install\n                                        opatch: Re-download opatch only\n                                        patch: Re-download patches but not opatch\n        --force-rm                  Force-remove build cache\n    -k, --dockerfile-keep           Keep the dynamically generated Dockerfile after build completion\n    -n, --image-name string         Repository name for the completed image (Default: oracle/db)\n        --no-cache                  Do not use cache when building the image\n        --no-sum                    Do not perform file checksums\n        --progress string           Display build progress\n                                        auto (Default)\n                                        plain: Show container output\n                                        tty: Show abbreviated output\n        --prune-cache               Prune build cache on success\n    -q, --quiet                     Suppress build output\n    -r, --force-rebuild             Force rebuild the base Linux image if it exists\n        --read-only-home            Configure a Read-Only Oracle Home\n        --remove-components string  Comma-delimited list of components to remove\n                                    Options: DBMA,HELP,ORDS,OUI,PATCH,PILOT,SQLD,SUP,UCP,TCP,ZIP,INV,DBCA,ADMIN,ROH\n                                    Default is all of the above\n        --rpm stringArray           Comma-delimited list of binaries/libraries to install\n                                        Default: bash-completion,git,less,strace,tree,vi,which\n        --secret string             File name containing MOS credentials for patch download\n    -S, --source-image string       Source OS image repository (Default: oraclelinux)\n    -T, --source-tag string         Source OS tag (Default: 8-slim)\n    -t, --tag string                Tag for the completed image (Default: [ORACLE_VERSION]-[ORACLE_EDITION])\n    -v, --version string            Oracle Database version (Default: 19.19)\n                                    The version must exist in the manifest file within the ./config directory\n    -h, --help                      This menu\n```\nImages created by the script are named as: `[repository]:[version]-[edition]`\nIt additionally creates a version-specific Linux image: `[source]-[tag]-[base_version]` where the base version is 11g, 12.1, 12.2, 18c, 19c, or 21c. This Linux image includes the database prerequisites for the given version and makes building multiple database images for the same database version faster. The majority of the build time is spent applying prerequisite RPMs. The build understands if a version-ready image is present and uses it.\n\n### Build example: Macs with Apple Silicon/ARM Systems\nThe only database currently supported for ARM architectures is Oracle 19.19. \n- [Download the Oracle Database 19c for LINUX ARM (aarch64)](https://www.oracle.com/database/technologies/oracle-database-software-downloads.html#db_ee) zip file and place it in the `database` subdirectory. Do not unzip the file.\n- From the base directory, run the `buildDBImage.sh` script:\n```\n./buildDBImage.sh\n# or:\n./buildDBImage.sh 19.19 EE\n```\nThis will create two images\n- A \"database-ready\" Oracle Enterprise Linux image, with `git`, `less`, `strace`, `tree`, `vi`, `which`, `bash-completion`, and `rlwrap` installed.\n  - Change these by editing the `RPM_LIST` in `templates/oraclelinux.dockerfile`, or pass a build argument.\n- A database image with a default `ORACLE_BASE` under `/u01/app/oracle` and an `ORACLE_HOME` under `$ORACLE_BASE/product/19c/dbhome_1`.\n  - Change these by editing the entries in `templates/db.dockerfile`, or pass build arguments for each parameter.\n\n### Build example: Intel-based systems (Linux, Mac, Windows)\nAll database versions are supported.\n- Download the appropriate installation file and place it in the `database` subdirectory.\n- Download any patches to be installed and place them in the `database/patches` subdirectory.\n- Update the `config/manifest` file if necessary. See the `README` file under `database` for details on formatting.\n- From the base directory, run the `buildDBImage.sh` script, passing the appropriate database version, edition, and OS version:\n```\n# Oracle 11g:\n./buildDBImage.sh 11.2.0.4 EE 7-slim\n# Oracle 12.1:\n./buildDBImage.sh 12.1.0.1 EE 7-slim\n# Oracle 12.2:\n./buildDBImage.sh 12.2 EE 7-slim\n# Oracle 18c:\n./buildDBImage.sh 18.3 EE 7-slim\n# Oracle 19c:\n./buildDBImage.sh 19 EE\n# or, to build a specific version:\n./buildDBImage.sh \u003cRelease Update\u003e EE\n# ... where \u003cRelease Update\u003e is the RU to apply atop the base 19.3\n# Oracle 21c:\n./buildDBImage.sh 21 EE\n# or, to build a specific version:\n./buildDBImage.sh \u003cRelease Update\u003e EE\n# ... where \u003cRelease Update\u003e is the RU to apply atop the base 21.3\n```\n\n### Note for OSX users\nThe default `/bin/bash` on OSX is 3.2, and the natively installed version of `getopt` is not GNU-compatible, meaning you won't be able to pass any parameters to the build script. To get around this limitation, install `bash` and `gnu-getopt` via `brew`:\n```\nbrew update\nbrew install bash\nbrew install gnu-getopt\n```\nAdd the following line to your `$HOME/.bash_profile` to pre-empt the default `getopt` (replace the path to `gnu-getopt` if `brew` installs to a different location on your system):\n```\nexport PATH=\"/opt/homebrew/opt/gnu-getopt/bin:$PATH\"\n```\nThen, `source $HOME/.bash_profile` and confirm that `getopt -V` returns the version (and not `--`).\n\nAs a workaround, edit the script and hardcode the options that would be set interactively.\n\n## FORCE_PATCH and `.netrc`\nWhen a `'.netrc` file is present, the `FORCE_PATCH` build argument enables patch downloads from My Oracle Support. Patches are downloaded when:\n- patches listed in the manifest aren't present in the build context (not added to the `./database/patches` directory)\n- the checksum of a patch doesn't match the value in the manifest\n- the `FORCE_PATCH` argument matches the patch type\n- the `FORCE_PATCH` argument includes the numeric patch ID\n\n`FORCE_PATCH` may have multiple options, separated by commas:\n- `all`: Download all patches listed in the manifest.\n- `opatch`: Download the latest version of `opatch`.\n- `patch`: Download patches but not `opatch`.\n- Patch ID: The numeric patch ID of patches to download.\n\nPass the FORCE_PATCH value to `docker build` as `--build-arg FORCE_PATCH=\u003cvalue_1\u003e(,\u003cvalue_2\u003e,\u003cvalue_n\u003e)`\n\nThe `.netrc` file is passed to the build process in an intermediate stage as a build secret. It is not copied to the final database image.\n\n# Run a container\nRun database containers as you would normally, using `docker run [options] [image-name]`.\n\n## Run options and examples\nOptions are controlled by environment variables set via the `docker run -e` flag:\n- `PDB_COUNT`: Create non-container databases by setting this value to 0, or set the number of pluggable databases to be spawned.\n- `CREATE_CONTAINER`: Ture/false, an alternate method for creating a non-CDB database.\n- `ORACLE_PDB`: This is the prefix for the PDB's (when PDB_COUNT \u003e 1) or the PDB_NAME (when PDB_COUNT=1, the default).\n- `DB_UNQNAME`: Set the database Unique Name. Default is ORACLE_SID; used mainly for creating containers used for Data Guard where the database and unique names are different, and avoids generating multiple diagnostic directory trees.\n- `PDB_LIST`: A comma-delimited list of PDB names. When present, overrides the PDB_COUNT and ORACLE_PDB values.\n- `ORACLE_CHARACTERSET` and `ORACLE_NLS_CHARACTERSET`: Set database character sets.\n- `INIT_PARAMS`: A list of parameters to set in the database at creation time. The default sets the DB_CREATE_FILE_DEST, DB_CREATE_ONLINE_LOG_DEST_1, and DB_RECOVERY_FILE_DEST to $ORADATA (enabling OMF) and turns off auditing.\n- `DEBUG=\"bash -x\"`: Debug container creation.\n\nCreate a non-container database:\n`docker run -d -e PDB_COUNT=0 IMG_NAME`\n\nCreate a container database with custom SID and PDB name:\n`docker run -d -e ORACLE_SID=mysid -e ORACLE_PDB=mypdb IMG_NAME`\n\nCreate a container database with a default SID and three PDB named mypdb[1,2,3]:\n`docker run -d -e PDB_COUNT=3 -e ORACLE_PDB=mypdb IMG_NAME`\n\nCreate a container database with custom SID and named PDB:\n`docker run -d -e ORACLE_SID=mydb -e PDB_LIST=\"test,dev,prod\" IMG_NAME`\n\nUsers running ARM/Apple Silicon do not need to do anything differently. On ARM/Apple Silicon, the build process creates an architecture-native image that runs without needing any special commands or virtualization (Colima, etc).\n\n# Example for Apple Silicon\nThis is an example of the output seen on a 2021 Apple MacBook Pro (M1, 16GB RAM, Ventura 13.4.1, Docker version 23.0.0, build e92dd87c32):\n```\n\n# ./buildDBImage.sh\n[+] Building 51.6s (8/8) FINISHED                                                   docker:desktop-linux\n =\u003e [internal] load .dockerignore                                                                   0.0s\n =\u003e =\u003e transferring context: 2B                                                                     0.0s\n =\u003e [internal] load build definition from Dockerfile.oraclelinux.202307031409.jTxd                  0.0s\n =\u003e =\u003e transferring dockerfile: 1.55kB                                                              0.0s\n =\u003e [internal] load metadata for docker.io/library/oraclelinux:8-slim                               1.3s\n =\u003e [internal] load build context                                                                   0.0s\n =\u003e =\u003e transferring context: 45.06kB                                                                0.0s\n =\u003e CACHED [1/3] FROM docker.io/library/oraclelinux:8-slim@sha256:0226d80b442e93f977753e1d          0.0s\n =\u003e =\u003e resolve docker.io/library/oraclelinux:8-slim@sha256:0226d80b442e93f977753e1d269c8ec          0.0s\n =\u003e [2/3] COPY manageOracle.sh /opt/scripts/                                                        0.0s\n =\u003e [3/3] RUN chmod ug+x /opt/scripts/manageOracle.sh \u0026\u0026      /opt/scripts/manageOracle.sh         48.7s\n =\u003e exporting to image                                                                              1.5s\n =\u003e =\u003e exporting layers                                                                             1.5s\n =\u003e =\u003e writing image sha256:6cdb5ddeb9d8ffbfcaeba0cb1fad0c003dbffc3cd77b204a8ddc60292e184b          0.0s\n =\u003e =\u003e naming to docker.io/library/oraclelinux:8-slim-19c                                           0.0s\noraclelinux:8-slim-19c\n[+] Building 193.8s (21/21) FINISHED                                                docker:desktop-linux\n =\u003e [internal] load .dockerignore                                                                   0.0s\n =\u003e =\u003e transferring context: 2B                                                                     0.0s\n =\u003e [internal] load build definition from Dockerfile.db.202307031410.NUni                           0.0s\n =\u003e =\u003e transferring dockerfile: 5.11kB                                                              0.0s\n =\u003e resolve image config for docker.io/docker/dockerfile:1.4                                        0.9s\n =\u003e CACHED docker-image://docker.io/docker/dockerfile:1.4@sha256:9ba7531bd80fb0a858632727c          0.0s\n =\u003e [internal] load metadata for docker.io/library/oraclelinux:8-slim-19c                           0.0s\n =\u003e [db 1/6] FROM docker.io/library/oraclelinux:8-slim-19c                                          0.0s\n =\u003e [internal] load build context                                                                  38.5s\n =\u003e =\u003e transferring context: 2.42GB                                                                38.5s\n =\u003e [db 2/6] COPY --chown=oracle:oinstall manageOracle.sh      /opt/scripts/                        0.6s\n =\u003e [stage-1 2/9] COPY --chown=oracle:oinstall ./config/dbca.*        /opt/install/                 0.6s\n =\u003e [stage-1 3/9] COPY --chown=oracle:oinstall ./config/*.tmpl        /opt/install/                 0.0s\n =\u003e [db 3/6] COPY --chown=oracle:oinstall ./config/inst.*     /opt/install/                         0.0s\n =\u003e [db 4/6] COPY --chown=oracle:oinstall ./config/manifest.* /opt/install/                         0.0s\n =\u003e [stage-1 4/9] COPY --chown=oracle:oinstall manageOracle.sh         /opt/scripts/                0.0s\n =\u003e [db 5/6] COPY --chown=oracle:oinstall ./database/         /opt/install/                         6.3s\n =\u003e [db 6/6] RUN  chmod ug+x /opt/scripts/manageOracle.sh \u0026\u0026      /opt/scripts/manageOracl         98.9s\n =\u003e [stage-1 5/9] COPY --chown=oracle:oinstall --from=db /u01/app/oraInventory  /u01/app/o          0.0s\n =\u003e [stage-1 6/9] COPY --chown=oracle:oinstall --from=db /u01/app/oracle /u01/app/oracle           18.6s\n =\u003e [stage-1 7/9] COPY --chown=oracle:oinstall --from=db /opt/oracle/oradata     /opt/orac          0.0s\n =\u003e [stage-1 8/9] RUN  /opt/scripts/manageOracle.sh -R                                              0.5s\n =\u003e [stage-1 9/9] WORKDIR /home/oracle                                                              0.0s\n =\u003e exporting to image                                                                             17.6s\n =\u003e =\u003e exporting layers                                                                            17.6s\n =\u003e =\u003e writing image sha256:4874efbbfe1cfb271e314ed8d6d0773e5a270d1a0b789861af76e59d4b6f82          0.0s\n =\u003e =\u003e naming to docker.io/oraclesean/db:19.19-EE                                                   0.0s\n```\n\nTotal build time was 245.4 seconds. After building the image:\n```\n# docker images\nREPOSITORY      TAG          IMAGE ID       CREATED             SIZE\noraclesean/db   19.19-EE     4874efbbfe1c   About an hour ago   5.87GB\noraclelinux     8-slim-19c   6cdb5ddeb9d8   About an hour ago   690MB\n```\n\nThe ARM image size is about 2GB smaller than its corresponding Intel-based image.\n\nHere's an example of running a network and container, with volumes defined for data, database logs, the audit directory, and a scripts directory.\n\n## Create a network (optional)\nThis creates a network called `oracle-db`. This step is optional; if you elect to not create a network here, be sure to remove the network assignment from the `docker run` command.\n```\ndocker network create oracle-db --attachable --driver bridge\n```\n\n## Set the container name and data path\nSet a name for the container and a path to mount bind volumes.\n```\nCONTAINER_NAME=ARM\nORADATA=~/oradata\n```\n\n## Create volumes\nI cannot overemphasize the value of volumes for Oracle databases. They persist data outside the container and make data independent of the container itself. Putting volatile directories outside the container's filesystem improves performance. And, volumes don't \"hide\" data in the `/var/lib/docker` directory of the virtual machine. You have better visibility into space use, and you're far less likely to fill the VM's disk.\n\n## Create a script directory (optional)\nThis creates a shared directory in the container for saving/sharing files between container and host. If you bypass this step, be sure to remove the corresponding definition from the `docker run` command later.\n```\nmkdir -p $ORADATA/scripts\n```\n\n## Create the audit, data, and diagnostic directories\nThis creates separate subdirectories for each file type and bind mounts them to Docker volumes. Assigning them to Docker volumes means they're visible in the Docker Desktop tool, as well as through the CLI via `docker volume ls` and other commands.\n```\n for dir in audit data diag reco\n  do mkdir -p $ORADATA/${CONTAINER_NAME}/${dir}\n     rm -fr $ORADATA/${CONTAINER_NAME}/${dir}/*\n     docker volume rm ${CONTAINER_NAME}_${dir} 2\u003e/dev/null\n     docker volume create --opt type=none --opt o=bind \\\n            --opt device=$ORADATA/${CONTAINER_NAME}/${dir} \\\n            ${CONTAINER_NAME}_${dir}\ndone\n```\n\n## Remove the container (if it already exists)\nIf you created a container by the same name, remove it before recreating it.\n```\ndocker rm -f $CONTAINER_NAME 2\u003e/dev/null\n```\n\n## Create the container\nIn the following command, I'm creating a container named `$CONTAINER_NAME`, then:\n- Mapping volumes for data (`/opt/oracle/oradata`), log data (`/u01/app/oracle/diag`), audit files (`/u01/app/oracle/admin`), and a shared directory for scripts (`/scripts`)\n- Assigning the container to a network called `oracle-db`\n- Setting the database SID\n- Setting the name of the PDB to ${CONTAINER_NAME}PDB1\n- Mapping port 8080 in the container to port 8080 on the host\n- Mapping port 1521 in the container to port 51521 on the host\n```\ndocker run -d \\\n       --name ${CONTAINER_NAME} \\\n       --volume ${CONTAINER_NAME}_data:/u02/app/oracle/oradata \\\n       --volume ${CONTAINER_NAME}_diag:/u01/app/oracle/diag \\\n       --volume ${CONTAINER_NAME}_audit:/u01/app/oracle/admin \\\n       --volume ${CONTAINER_NAME}_reco:/u03/app/oracle \\\n       --volume $ORADATA/scripts:/scripts \\\n       --network oracle-db \\\n       -e ORACLE_SID=${CONTAINER_NAME} \\\n       -e ORACLE_PDB=${CONTAINER_NAME}PDB1 \\\n       -p 8080:8080 \\\n       -p 51521:1521 \\\n       oracle/db:19.19-EE\n```\n\nAdd or remove options as you see fit.\n\n## Monitor the database creation and logs\nView the database activity:\n```\ndocker logs -f $CONTAINER_NAME\n```\n\nSample output from a database:\n```\n# docker logs -f $CONTAINER_NAME\n\n# ----------------------------------------------------------------------------------------------- #\n  Oracle password for SYS, SYSTEM and PDBADMIN: HB#K_xhkwM_O10\n# ----------------------------------------------------------------------------------------------- #\n\n# ----------------------------------------------------------------------------------------------- #\n  runDBCA: Running DBCA for database ARM at 2023-07-03 20:16:05\n# ----------------------------------------------------------------------------------------------- #\n\nLSNRCTL for Linux: Version 19.0.0.0.0 - Production on 03-JUL-2023 20:16:05\n\nCopyright (c) 1991, 2023, Oracle.  All rights reserved.\n\nStarting /u01/app/oracle/product/19c/dbhome_1/bin/tnslsnr: please wait...\n\nTNSLSNR for Linux: Version 19.0.0.0.0 - Production\nSystem parameter file is /u01/app/oracle/product/19c/dbhome_1/network/admin/listener.ora\nLog messages written to /u01/app/oracle/diag/tnslsnr/96bb65f2a1b7/listener/alert/log.xml\nListening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))\nListening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))\n\nConnecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))\nSTATUS of the LISTENER\n------------------------\nAlias                     LISTENER\nVersion                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production\nStart Date                03-JUL-2023 20:16:06\nUptime                    0 days 0 hr. 0 min. 0 sec\nTrace Level               off\nSecurity                  ON: Local OS Authentication\nSNMP                      OFF\nListener Parameter File   /u01/app/oracle/product/19c/dbhome_1/network/admin/listener.ora\nListener Log File         /u01/app/oracle/diag/tnslsnr/96bb65f2a1b7/listener/alert/log.xml\nListening Endpoints Summary...\n  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))\n  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))\nServices Summary...\nService \"ARM\" has 1 instance(s).\n  Instance \"ARM\", status UNKNOWN, has 1 handler(s) for this service...\nThe command completed successfully\n# ----------------------------------------------------------------------------------------------- #\n  runDBCA: Creating container database ARM and 3 pluggable database(s) with name ARMPDB at 2023-07-03 20:16:06\n# ----------------------------------------------------------------------------------------------- #\nPrepare for db operation\n8% complete\nCopying database files\n31% complete\nCreating and starting Oracle instance\n32% complete\n36% complete\n40% complete\n43% complete\n46% complete\nCompleting Database Creation\n51% complete\n54% complete\nCreating Pluggable Databases\n58% complete\n63% complete\n68% complete\n77% complete\nExecuting Post Configuration Actions\n100% complete\nDatabase creation complete. For details check the logfiles at:\n /u01/app/oracle/cfgtoollogs/dbca/ARM.\nDatabase Information:\nGlobal Database Name:ARM\nSystem Identifier(SID):ARM\nLook at the log file \"/u01/app/oracle/cfgtoollogs/dbca/ARM/ARM.log\" for further details.\n\nPluggable database altered.\n\nPluggable database altered.\n\n# ----------------------------------------------------------------------------------------------- #\n  runDBCA: DBCA complete at 2023-07-03 20:26:37\n# ----------------------------------------------------------------------------------------------- #\n\n# ----------------------------------------------------------------------------------------------- #\n  Database ARM with unique name ARM is open and available.\n# ----------------------------------------------------------------------------------------------- #\n\n# ----------------------------------------------------------------------------------------------- #\n  Tailing alert_ARM.log:\n2023-07-03T20:26:36.493063+00:00\nARMPDB3(5):CREATE SMALLFILE TABLESPACE \"USERS\" LOGGING  DATAFILE  '/opt/oracle/oradata/ARM/ARMPDB3/users01.dbf' SIZE 5M REUSE AUTOEXTEND ON NEXT  1280K MAXSIZE UNLIMITED  EXTENT MANAGEMENT LOCAL  SEGMENT SPACE MANAGEMENT  AUTO\nARMPDB3(5):Completed: CREATE SMALLFILE TABLESPACE \"USERS\" LOGGING  DATAFILE  '/opt/oracle/oradata/ARM/ARMPDB3/users01.dbf' SIZE 5M REUSE AUTOEXTEND ON NEXT  1280K MAXSIZE UNLIMITED  EXTENT MANAGEMENT LOCAL  SEGMENT SPACE MANAGEMENT  AUTO\nARMPDB3(5):ALTER DATABASE DEFAULT TABLESPACE \"USERS\"\nARMPDB3(5):Completed: ALTER DATABASE DEFAULT TABLESPACE \"USERS\"\n2023-07-03T20:26:37.882084+00:00\nalter pluggable database all open\nCompleted: alter pluggable database all open\nalter pluggable database all save state\nCompleted: alter pluggable database all save state\n```\n\nDatabase creation took about 10 minutes; note that this output is for a CDB with three Pluggable Databases (PDB).\n\n# Directory Structure\nThree subdirectories contain the majority of assets and configuration needed by images.\n\n## `./config`\nHere you'll find version-specific files and configuration, including:\n- `dbca.\u003cversion\u003e.rsp`: Every version of Oracle seems to introduce new options and features for Database Configuration Assistant (DBCA). Each version-specific file includes options with default and placeholder values. During database creation, the script replaces placeholders with values passed to the container at runtime via the `-e` option.\n- `inst.\u003cversion\u003e.rsp`: The database install response files, like the DBCA response files, include default and placeholder values for customizing database installation for any version of Oracle. The script updates the placeholder values with those present in the Dockerfile or given to the build operation through a `--build-arg` option.\n- `manifest`: The manifest file includes information for all database and/or patch versions:\n  ```\n  # md5sum                          File name                                Type      Version  Other\n  1858bd0d281c60f4ddabd87b1c214a4f  LINUX.X64_193000_db_home.zip             database  19       SE,EE\n  #1f86171d22137e31cc2086bf7af36e91  oracle-database-ee-19c-1.0-1.x86_64.rpm  database  19      SE,EE\n  b8e1367997544ab2790c5bcbe65ca805  p6880880_190000_Linux-x86-64.zip         opatch    19       6880880\n  2a06e8c7409b21de9be6d404d39febda  p30557433_190000_Linux-x86-64.zip        patch     19.6     30557433\n  0e0831a46cc3f8312a761212505ba5d1  p30565805_196000DBRU_Linux-x86-64.zip    patch     19.6     30565805\n  ...\n  5b2f369f6c1f0397c656a5554bc864e6  p33192793_190000_Linux-x86-64.zip        patch     19.13    33192793\n  680af566ae1ed41a9916dfb0a122565c  p33457235_1913000DBRU_Linux-x86-64.zip   patch     19.13    33457235\n  30eb702fe0c1bee393bb80ff8f10afe9  p33516456_190000_Linux-x86-64.zip        patch     19.13.1  33516456\n  de8c41d94676479b9aa35d66ca11c96a  p33457235_1913100DBRUR_Linux-x86-64.zip  patch     19.13.1  33457235\n  7bcfdcd0f3086531e232fd0237b7438f  p33515361_190000_Linux-x86-64.zip        patch     19.14    33515361\n  fd96f9db3c1873dfee00efe8088186a4  p33912872_190000_Linux-x86-64.zip        patch     19       33912872\n  ```  \n\n  Column layout:\n  - md5sum: The md5sum used for verification/check.\n  - File name: Asset file name.\n  - Type: Identifies the type of file. Possible values:\n    - `database`: A file for installing database software. May be a .zip or .rpm file.\n    - `opatch`: The OPatch file for this database version.\n    - `patch`: Individual (non-OPatch) patch files.\n  - Version: The database version the file applies to. Possible values:\n    - database, opatch: The \"base version\" (in this example, 19).\n    - patch: The patch version (eg 19.13 or 19.13.1). When a patch (or version) has multiple files, enter files in apply order, first to last.\n  - Other:\n    - database: Indicates Edition support.\n      - `SE`: Standard Edition, Standard Edition 2\n      - `EE`: Enterprise Edition\n      - `SE,EE`: All editions\n      - `XE`: Express Edition\n    - opatch, patch: The patch number.\n\n  Lines beginning with a `#` are ignored as comments.\n\n  In this example, the patch number `33457235` appears twice, once for 19.13 and agains for 19.13.1, but there are version-specific files/checksums.\n  Patch 33912872 appears once, with a generic version. This patch is applicable to any release but must be applied after the RU. The build process evaluates patches in order, so it will apply this general patch last.\n\nAdditional template files exist in this directory (I will eventually move them to the `template` directory for consistency). There are three categories:\n- TNS configurations. Templates for setting up listener and networking configurations. Customize as necessary. During initial database creation, the files are copied to their proper locations and variables interpreted from the environment.\n  - `listener.ora.tmpl` \n  - `sqlnet.ora.tmpl`\n  - `tnsnames.ora.tmpl`\n\n- Database configuration. Templates used for specialized database creation outside the \"normal\" automation, currently only used in upgrade images.\n  - `init.ora.tmpl`\n\n- Environment configurations. Used to set up the interactive environment in the container. Each has a specific function:\n  - `env.tmpl`: Used to build `~oracle/.bashrc`. Pay attention to escaping (`\\`) on variables, there to support multi-home and multi-SID environments.\n  - `login.sql.tmpl`: Used to create a `login.sql` file under `$SQLPATH` that formats and customizes SQLPlus output.\n  - `rlwrap.tmpl`: If `rlwrap` is present in the environment, adds aliases for `sqlplus`, `rman`, and dgmgrl` to the shell.\n\n- Credential files:\n  - `.netrc`: MOS login credentials. See the netrc.example file in this directory for format. Adding a `netrc` file allows the build process to download patches from MOS. See the FORCE_PATCH build arguement for more information.\n\n## `./database` and `./database/patches`\n**All** database and patch files go here. I redesigned the file structure of this repo in March 2022 to use a common directory for all software. Eliminating versioned subdirectories simplified file management and eliminated file duplication.\n\nI previously supported versioning at the directory and Dockerfile level. It required a 19.13 directory (or a 19c directory and a 19.13 subdirectory), a dedicated Dockerfile, `Dockerfile.19.13`, and a matching docker ignore file, `Dockerfile.19.13.dockerignore`. But all 19c versions use the same .zip/.rpm for installation. `docker build` reads everything in the current directory and its subdirectories into its context prior to performing the build. It doesn't support links. So, to build 19.13 meant I had to have a copy of the 19c base installation media in each subdirectory. Implementation of .dockerignore requires the Dockerfile and its ignore file to have matching names. So, to limit context (preventing `docker build` from reading _every_ file at/below the build directory) I had to have separate, identically-named Dockerfile/.dockerignore files for *every version* I wanted to build.\n\nThat duplication was something I set out to to avoid. I switched instead to a dynamic build process that reads context from a common directory, using .dockerignore to narrow its scope. The advantage is having one directory and one copy for all software.\n\nCombining this design with a manifest file means I no longer need to move patches in and out of subdirectories to control the patch level of image builds, nor worry about placing them in numbered folders to manage the apply order. Add the file to the appropriate directory (`database` or `database/patch`) and include an entry in the version manifest.\n\n## `./templates`\nDynamic builds run from the Dockerfile templates in this directory and create two images: a database image and a database-ready Oracle Linux image.\n\nThe Oracle Enterprise Linux image, tagged with the database version, includes all database version prerequisites (notably the database preinstall RPM). The same image works for any database version installed atop it, and installing the prereqs (at least on my system) takes longer than installing database software. Rather than duplicating that work, the build looks to see if the image is present and starts there. If not, it builds the OEL image.\n\nDo not be confused by output like this:\n```\nREPOSITORY    TAG          SIZE\noraclelinux   7-slim-19c   442MB\noraclelinux   7-slim       133MB\noracle/db     19.13.1-EE   7.58GB\n```\n\nThe total size of these images is not 442MB + 133MB + 7.58GB. Layers in the oraclelinux:7-slim are reused in the oraclelinux:7-slim-19c image, which are reused in the oracle/db:19.13.1-EE image.\n\nThe buildDBImage.sh script reads these templates and creates temporary Dockerfiles and dockerignore files, using information in the manifest according to the version (and other information) passed to the script.\n\n# Why this Repo\nI build and run many Oracle databases in containers. There were things I didn't like about Oracle's build scripts. My goals for this repository are:\n- Build any version and any patch level\n  - Code should be agnostic\n  - Migrate version-specific actions to templates\n  - Store versioned information as configurations and manifests\n  - Eliminate duplicate assets\n  - Flatten and simplify the directory tree\n- Streamline builds and reduce image build times\n- Allow build- and run-time customization\n- Avoid unnecessary environment settings\n- Follow Oracle recommendations and best practices\n- Support for archive and RPM-based installations\n- Leverage buildx/BuildKit capabilities\n- Support advanced features and customization:\n  - Read-Only Homes\n  - CDB and non-CDB database creation\n  - For CDB databases, control the number/naming of PDBs\n  - Data Guard, Sharding, RAC, GoldenGate, upgrades, etc.\n\nThere is one script to handle all operations, for all editions and versions. This adds some complexity to the script (it has to accommodate peculiarities of every version and edition) but:\n- _For the most part_ these operations are identical across the board\n- One script in the root directory does everything and only one script needs maintenance\n- Version differences are all in one place vs. hidden in multiple files in parallel directories\n\nThe `/opt/scripts/manageOracle.sh` script manages all Oracle/Docker operations, from build through installation:\n- Configures the environment\n- Installs RPM\n- Installs the database\n- Creates the database\n- Starts and stops the database\n- Performs health checks\n\n## Flexible Image Creation\nEach Dockerfile uses a set of common ARG values. Defaults are set in each Dockerfile but can be overridden by passing `--build-arg` values to `docker build`. This allows a single Dockerfile to accommodate a wide range of build options without changes to any files, including:\n- Removing specific components (APEX, SQL Developer, help files, etc) to minimize image size without editing scripts. It's easier to build images to include components that are normally be deleted. This is particularly useful for building images for testing 19c upgrades. APEX is included in the seed database but older APEX schemas have to be removed prior to a 19c upgrade. Where's the removal script? In the APEX directory, among those commonly removed to trim image size!\n- Add programs/binaries at build time as variables, rather than in a script. Hey, sometimes you want editors or `strace` or `git`, sometimes you don't. Set the defaults to your preferred set of binaries. Override them at build time as necessary, again without having to edit/revert any files.\n- Some database versions may require special RPM. Rather than maintaining that in scripts, it's in the Dockerfile (configuration).\n- Add supplemental RPMs. Some RPM have dependencies (such as `rlwrap`) that require a second execution of `rpm install`. All builds treat this the same way.\n  - The RPM list includes tools for interactive use of containers. \n  - Remove `git`, `less`, `strace`, `tree`, `vi`, `which`, and `bash-completion` for non-interactive environments\n  - `sudo` is used to run installations from the `manageOracle.sh` script\n- All builds are multi-stage with identical steps, users and operations. Differences are handled by the management script by reading configuration information from the Dockerfile, discovered in the file structure, or set in the environment.\n- Customizing the directories for `ORACLE_BASE`, `ORACLE_HOME`, `oraInventory`, and the `oradata` directory.\n- Specify Read-Only Oracle Home (ROOH). Set `ROOH=ENABLE` in the Dockerfile, or pass `--build-arg ROOH=ENABLE` during build.\n\n## Install Oracle from Archive (ZIP) or RPM\nRPM builds operate a little differently. They have a dependency on `root` because database configuration and startup is managed through `/etc/init.d`. The configuration is in `/etc/sysconfig`. If left at their default (I have a repo for building default RPM-based Oracle installations elsewhere) they need `root` and pose a security risk. I experimented with workarounds (adding `oracle` to `sudoers`, changing the `/etc/init.d` script group to `oinstall`, etc) but RPM-created databases still ran differently.   \n\nI use the RPM to create the Oracle software home, then discard what's in `/etc/init.d` and `/etc/sysconfig` and create and start the database \"normally\" using DBCA and SQLPlus.  \n\nThis allows additional options for RPM-based installations, including changing the directory structure (for non-18c XE installs—the 18c XE home does not include libraries needed to recompile) and managing configuration through the same mechanism as \"traditional\" installations, meaning anything that can be applied to a \"normal\" install can be set in a RPM-based installation, without editing a different set of files in `/etc/sysconfig` and `ORACLE_HOME`. Express Edition on 18c (18.4) can be extended to use:\n- Custom SID (not stuck with XE)\n- Container or non-container\n- Custom PDB name(s)\n- Multiple PDB\n\n## Flexible Container Creation\nI wanted images capable of running highly customizable database environments out of the gate, that mimic what's seen in real deployments. This includes running non-CDB databases, multiple pluggable databases, case-sensitive SID and PDB names, and custom PDB naming (to name a few). Database creation is controlled and customized by passing environment variables to `docker run` via `-e VARIABLE=VALUE`. Notable options include:\n- `PDB_COUNT`: Create non-container databases by setting this value to 0, or set the number of pluggable databases to be spawned.\n- `CREATE_CONTAINER`: Ture/false, an alternate method for creating a non-CDB database.\n- `ORACLE_PDB`: This is the prefix for the PDB's (when PDB_COUNT \u003e 1) or the PDB_NAME (when PDB_COUNT=1, the default).\n- `DB_UNQNAME`: Set the database Unique Name. Default is ORACLE_SID; used mainly for creating containers used for Data Guard where the database and unique names are different, and avoids generating multiple diagnostic directory trees.\n- `PDB_LIST`: A comma-delimited list of PDB names. When present, overrides the PDB_COUNT and ORACLE_PDB values.\n- `ORACLE_CHARACTERSET` and `ORACLE_NLS_CHARACTERSET`: Set database character sets.\n- `INIT_PARAMS`: A list of parameters to set in the database at creation time. The default sets the DB_CREATE_FILE_DEST, DB_CREATE_ONLINE_LOG_DEST_1, and DB_RECOVERY_FILE_DEST to $ORADATA (enabling OMF) and turns off auditing.\n\n## DEBUG mode\nDebug image builds, container creation, or container operation. \n- Use `--build-arg DEBUG=\"bash -x\"` to debug image builds\n- Use `-e DEBUG=\"bash -x\"` to debug container creation\n- Use `export DEBUG=\"bash -x\"` to turn on debugging output in a running container\n- Use `unset DEBUG` to turn debugging off in a running container\n\n# Examples\nCreate a non-container database:  \n`docker run -d -e PDB_COUNT=0 IMG_NAME`  \nCreate a container database with custom SID and PDB name:  \n`docker run -d -e ORACLE_SID=mysid -e ORACLE_PDB=mypdb IMG_NAME`  \nCreate a container database with a default SID and three PDB named mypdb[1,2,3]:  \n`docker run -d -e PDB_COUNT=3 -e ORACLE_PDB=mypdb IMG_NAME`  \nCreate a container database with custom SID and named PDB:  \n`docker run -d -e ORACLE_SID=mydb -e PDB_LIST=\"test,dev,prod\" IMG_NAME`\n\n# Errata\n\n## ORACLE_PDB Behavior in Containers\nThere are multiple mechanisms that set the ORACLE_PDB variable in a container. It is set explicitly by passing a value (e.g. `-e ORACLE_PDB=value`) during `docker run`. This is the preferred way of doing things since it correctly sets the environment.\nThe value may be set implicitly four ways:\n- If ORACLE_PDB is not set and the database version requires a PDB (20c and later), the value of ORACLE_PDB is inherited from the image.\n- If ORACLE_PDB is not set and PDB_COUNT is non-zero, PDB_COUNT PDBs are implied. The value of ORACLE_PDB is inherited from the image.\n- If both ORACLE_PDB and PDB_COUNT are set, ORACLE_PDB is assumed to be a prefix. PDB_COUNT pluggable databases are created as ${ORACLE_PDB}1 through ${ORACLE_PDB}${PDB_COUNT}. ORACLE_PDB in this case is not an actual pluggable database but a prefix.\n- If ORACLE_PDB is not set and PDB_LIST contains one or more values, ORACLE_PDB is inherited from the image.\nIn each case the ORACLE_PDB environment variable is added to the `oracle` user's login scripts. Run that request more than one PDB (PDB_LIST, PDB_COUNT \u003e 1) set the default value to the first PDB in the list/${ORACLE_PDB}1.\nIn these latter cases, the ORACLE_PDB for interactive sessions is set by login but non-interactive sessions *DO NOT* get the local value. They inherit the value from the container's native environment.\nTake the following examples:\n- `docker run ... -e ORACLE_PDB=PDB ...`: The interactive and non-interactive values of ORACLE_PDB match.\n- 'docker run ... -e PDB_COUNT=n ...`: The interactive value of ORACLE_PDB is ORCLPDB1. The non-interactive value is ORCLPDB. This happens because the inherited value, ORCLPDB is used for non-interactive sessions.\n- `docker run ... -e PDB_LIST=PDB1,MYPDB ...`: The interactive value of ORACLE_PDB is PDB1. The non-interactive value is ORCLPDB (see above).\n- `docker run ... ` a 21c database: The interactive value of ORACLE_PDB is set in the DBCA scripts as ORCLPDB. The non-interactive value equals whatever is set in the Dockerfile. \nThis can cause confusion when calling scripts. For example:\n```\ndocker exec -it CON_NAME bash\nenv | grep ORACLE_PDB\nexit\n```\n...will show the correct, expected value. However:\n```\ndocker exec -it CON_NAME bash -c \"env | grep ORACLE_PDB\"\n```\n...may show a different value. This is expected (and intended and desirable—it's necessary for statelessness and idempotency) but may lead to confusion.\nI recommend handling this as follows:\n- Set ORACLE_PDB explicitly in `docker run` even when using PDB_LIST. PDB_LIST is evaluated first so setting ORACLE_PDB sets the environment and PDB_LIST creates multiple pluggable databases. The default PDB should be first in the list and match ORACLE_PDB.\n- If you need multiple PDBs, use PDB_LIST instead of PDB_COUNT, and set ORACLE_PDB to the \"default\" PDB. Otherwise, the ORACLE_PDB value in non-interactive shells is the prefix and not a full/valid PDB name.\n\n# Glossary\n- APEX: Oracle Application Express, a low-code web development tool.\n- CDB: Container Database - Introduced in 12c, container databases introduce capacity and security enhancements. Each CDB consists of a root container plus one or more Pluggable Databases, or PDBs.\n- DBCA: Oracle Database Configuration Assistant - a tool for creating databases.\n- EE: Oracle Enterprise Edition - A licensed, more robust version of Oracle that can be extended through addition of add-ons like Advanced Compression, Partitioning, etc.\n- ORACLE_BASE: The base directory for Oracle software installation.\n- ORACLE_HOME: The directory path containing an Oracle database software installation.\n- ORACLE_INVENTORY, Oracle Inventory: Metadata of Oracle database installations on a host.\n- PDB: Pluggable Database - One or more PDBs \"plug in\" to a container database.\n- RPM: RedHat Package Manager - package files for installing software on Linux.\n- runInstall: Performs Oracle database software installation.\n- SE, SE2: Oracle Standard Edition/Oracle Standard Edition 2 - A licensed version of Oracle with limited features. Not all features are available, licensed, or extensive in SE/SE2. For example, partitioning is not available in SE/SE2, and RAC is limited to specific node/core counts.\n- XE: Oracle Express Edition - A limited version of the Oracle database that is free to use.\n\n## TODO:\n- Replace positional options with flags\n- Expand customizations\n- Add flexibility to pass `--build-arg`s to the script/image\n- Add a \"Create Dockerfile\" option (don't run the build)\n- Add Dockerfile naming capability\n- Add a help menu and error dialogs\n- Integrate secrets\n- More...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foraclesean%2Fcloud-native-oracle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foraclesean%2Fcloud-native-oracle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foraclesean%2Fcloud-native-oracle/lists"}