DEV Community

Cover image for How to run Oracle Database in a Docker Container using Docker Compose
Ajeet Singh Raina for Docker

Posted on • Edited on

How to run Oracle Database in a Docker Container using Docker Compose

Oracle Container Registry (OCR) is a private container registry provided by Oracle Corporation that allows users to store, distribute, and manage container images. OCR is built on the Oracle Cloud Infrastructure and enables users to store, manage and distribute container images in a secure, reliable and scalable way. It is designed to work with the Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE), Oracle Cloud Infrastructure Registry (OCIR), and other Oracle Cloud Infrastructure services.

Oracle Container Registry (OCR) is a fully-managed, enterprise-grade registry for storing and distributing container images on Oracle. Users can use OCR to store their own custom images, as well as pull down official images provided by Oracle. OCR supports both the Docker and OCI image formats and also provides features such as image scanning, image promotion and versioning, and image access control. Users can use the Oracle Cloud Infrastructure Console, Oracle Cloud Infrastructure CLI, or the Oracle Cloud Infrastructure SDK to interact with OCR.

Why to run Oracle database in a Docker Container?

There are several reasons why one might choose to run an Oracle database in a Docker container:

  • Portability: Docker containers can be easily moved between environments, making it easy to deploy the database in different environments such as development, testing, and production.

  • Isolation: Running the database in a container can help to isolate it from the host system, reducing the risk of conflicts with other software running on the same machine.

  • Consistency: By packaging the database and its dependencies in a container, it ensures that the database will always run the same way, regardless of the environment in which it is deployed.

  • Scalability: Containers can be easily scaled up or down as needed, making it easy to handle changes in load.

  • Cost Savings: Docker containers can be run on-premises or in the cloud, allowing you to take advantage of cloud-based services while avoiding the costs of virtualization.

In this blog, you will see how you can use Docker to run Oracle Database in a Docker container

  1. Visit https://container-registry.oracle.com/ and create your new account

Image11

  1. Select Enterprise.

Image12

  1. Click "Sign In"

Image13

  1. Sign-in

Image14

  1. Accept the License and test the docker login


docker login container-registry.oracle.com
Username: ajeetraina@gmail.com
Password: 
Login Succeeded


Enter fullscreen mode Exit fullscreen mode

Oracle Database can be run in a Docker container, using the official Oracle Database Docker image. To deploy an Oracle Database using Docker, you will need to:

  • Install Docker on your machine.
  • Pull the Oracle Database Docker image using the command:


docker pull container-registry.oracle.com/database/enterprise:latest


Enter fullscreen mode Exit fullscreen mode
  • Create a new container using the command:


 docker run -d --name oracle-db -p 1521:1521 container-registry.oracle.com/database/enterprise:latest


Enter fullscreen mode Exit fullscreen mode

Once the container is up and running, you can connect to the Oracle Database using any SQL client, such as SQL*Plus, with the connection string "hostname:1521/orclpdb1"

The above command creates a new container with the name "oracle-db" and maps the host's port 1521 to the container's port 1521. The orclpdb1 is the default service name for the Oracle Database.

You can also customize the container by providing environment variables and volumes. For example, to set the SYS and SYSTEM password, you can use the following command



 docker run -d --name oracle-db -p 1521:1521 -e ORACLE_PWD=<password> container-registry.oracle.com/database/enterprise:latest


Enter fullscreen mode Exit fullscreen mode

You can also use a docker-compose.yml file to set the environment variables, mount the volumes and provide additional configurations.

Note: The above command will start the Oracle Database with default settings and configurations. It is recommended to refer to the official Oracle Database documentation and also to Oracle's licensing policy before deploying in production.

Using Docker Compose

Here is an example of a docker-compose.yml file that can be used to deploy an Oracle database in a Docker container:



version: '3.1'
services:
  oracle-db:
    image: container-registry.oracle.com/database/enterprise:latest
    environment:
      - ORACLE_SID=ORCLCDB
      - ORACLE_PDB=ORCLPDB1
      - ORACLE_PWD=Oracle_123
    ports:
      - 1521:1521
    volumes:
      - oracle-data:/opt/oracle/oradata
      - oracle-backup:/opt/oracle/backup
    healthcheck:
      test: ["CMD", "sqlplus", "-L", "sys/Oracle_123@//localhost:1521/ORCLCDB as sysdba", "@healthcheck.sql"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  oracle-data:
  oracle-backup:


Enter fullscreen mode Exit fullscreen mode

This docker-compose.yml file uses the official Oracle database image from the Oracle Container registry and sets several environment variables for the container, including the ORACLE_SID, ORACLE_PDB, and ORACLE_PWD.

It also maps port 1521 on the host to port 1521 in the container, so that the database can be accessed from outside of the container.
It also creates two volumes oracle-data and oracle-backup to store the data and backup files respectively.
It also has a health check to check for the availability of the DB.

Don't forget to replace the values of ORACLE_PWD with your desired password. Also, you should adjust the volumes and ports to match your specific requirements. The above example uses SQLPlus to check the health of the database, you can customise it accordingly.

Top comments (2)

Collapse
 
renatospaka profile image
Renato Spakauskas

Ajeet,

Awesome article!

I made your recipe exactly. Basicaly I copied your docker-compose.yaml and ran docker compose up.

However, I got a lot of error messages:
Attaching to transact_oracle_db
transact_oracle_db | Traceback (most recent call last):
transact_oracle_db | File "/opt/oracle/lock.py", line 178, in <module>
transact_oracle_db | main()
transact_oracle_db | File "/opt/oracle/lock.py", line 169, in main
transact_oracle_db | sys.exit(acquire_lock(args.lock_file, sock_file, args.block, args.heartbeat))
transact_oracle_db | File "/opt/oracle/lock.py", line 41, in acquire_lock
transact_oracle_db | lock_handle = open(lock_file, 'a')
transact_oracle_db | IOError: [Errno 13] Permission denied: '/opt/oracle/oradata/.ORCLCDB.create_lck'
transact_oracle_db | ORACLE EDITION: ENTERPRISE
transact_oracle_db |
transact_oracle_db | LSNRCTL for Linux: Version 21.0.0.0.0 - Production on 22-JUL-2023 00:40:49
transact_oracle_db |
transact_oracle_db | Copyright (c) 1991, 2021, Oracle. All rights reserved.
transact_oracle_db |
transact_oracle_db | Starting /opt/oracle/product/21c/dbhome_1/bin/tnslsnr: please wait...
transact_oracle_db |
transact_oracle_db | TNSLSNR for Linux: Version 21.0.0.0.0 - Production
transact_oracle_db | System parameter file is /opt/oracle/homes/OraDB21Home1/network/admin/listener.ora
transact_oracle_db | Log messages written to /opt/oracle/diag/tnslsnr/087c11bf06d0/listener/alert/log.xml
transact_oracle_db | Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
transact_oracle_db | Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
transact_oracle_db |
transact_oracle_db | Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
transact_oracle_db | STATUS of the LISTENER
transact_oracle_db | ------------------------
transact_oracle_db | Alias LISTENER
transact_oracle_db | Version TNSLSNR for Linux: Version 21.0.0.0.0 - Production
transact_oracle_db | Start Date 22-JUL-2023 00:40:51
transact_oracle_db | Uptime 0 days 0 hr. 0 min. 0 sec
transact_oracle_db | Trace Level off
transact_oracle_db | Security ON: Local OS Authentication
transact_oracle_db | SNMP OFF
transact_oracle_db | Listener Parameter File /opt/oracle/homes/OraDB21Home1/network/admin/listener.ora
transact_oracle_db | Listener Log File /opt/oracle/diag/tnslsnr/087c11bf06d0/listener/alert/log.xml
transact_oracle_db | Listening Endpoints Summary...
transact_oracle_db | (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
transact_oracle_db | (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
transact_oracle_db | The listener supports no services
transact_oracle_db | The command completed successfully
transact_oracle_db | Prepare for db operation
transact_oracle_db | Cannot create directory "/opt/oracle/oradata/ORCLCDB".
transact_oracle_db | 8% complete
transact_oracle_db | 100% complete
transact_oracle_db | [FATAL] Prepare Operation has failed.
transact_oracle_db | 0% complete
transact_oracle_db | Look at the log file "/opt/oracle/cfgtoollogs/dbca/ORCLCDB/ORCLCDB.log" for further details.
transact_oracle_db | [ 2023-07-22 00:40:59.453 UTC ] Prepare for db operation
transact_oracle_db | [ 2023-07-22 00:40:59.492 UTC ] Cannot create directory "/opt/oracle/oradata/ORCLCDB".
transact_oracle_db | DBCA_PROGRESS : 8%
transact_oracle_db | DBCA_PROGRESS : 100%
transact_oracle_db | [ 2023-07-22 00:40:59.500 UTC ] [FATAL] Prepare Operation has failed.
transact_oracle_db | DBCA_PROGRESS : 0%
transact_oracle_db |
transact_oracle_db | SQL*Plus: Release 21.0.0.0.0 - Production on Sat Jul 22 00:40:59 2023
transact_oracle_db | Version 21.3.0.0.0
transact_oracle_db |
transact_oracle_db | Copyright (c) 1982, 2021, Oracle. All rights reserved.
transact_oracle_db |
transact_oracle_db | Connected to an idle instance.
transact_oracle_db |
transact_oracle_db | SQL> ALTER SYSTEM SET control_files='/opt/oracle/oradata/ORCLCDB/control01.ctl' scope=spfile
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> ALTER SYSTEM SET local_listener=''
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> ALTER PLUGGABLE DATABASE ORCLPDB1 SAVE STATE
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> BEGIN DBMS_XDB_CONFIG.SETGLOBALPORTENABLED (TRUE); END;
transact_oracle_db |
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> SQL> ALTER SESSION SET "_oracle_script" = true
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> CREATE USER OPS$oracle IDENTIFIED EXTERNALLY
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> GRANT CREATE SESSION TO OPS$oracle
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> GRANT SELECT ON sys.v_$pdbs TO OPS$oracle
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> GRANT SELECT ON sys.v_$database TO OPS$oracle
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> ALTER USER OPS$oracle SET container_data=all for sys.v_$pdbs container = current
transact_oracle_db | *
transact_oracle_db | ERROR at line 1:
transact_oracle_db | ORA-01034: ORACLE not available
transact_oracle_db | Process ID: 0
transact_oracle_db | Session ID: 0 Serial number: 0
transact_oracle_db |
transact_oracle_db | SQL> SQL> Disconnected
transact_oracle_db | ORACLE_HOME = [/home/oracle] ? ORACLE_BASE environment variable is not being set since this
transact_oracle_db | information is not available for the current user ID .
transact_oracle_db | You can set ORACLE_BASE manually if it is required.
transact_oracle_db | Resetting ORACLE_BASE to its previous value or ORACLE_HOME
transact_oracle_db | The Oracle base remains unchanged with value /opt/oracle
transact_oracle_db | /opt/oracle/checkDBStatus.sh: line 26: sqlplus: command not found
transact_oracle_db | mkdir: cannot create directory '/opt/oracle/oradata/dbconfig': Permission denied
transact_oracle_db | mv: cannot stat '/opt/oracle/dbs/spfileORCLCDB.ora': No such file or directory
transact_oracle_db | mv: cannot stat '/opt/oracle/dbs/orapwORCLCDB': No such file or directory
transact_oracle_db | mv: cannot move '/opt/oracle/homes/OraDB21Home1/network/admin/sqlnet.ora' to '/opt/oracle/oradata/dbconfig/ORCLCDB/': No such file or directory
transact_oracle_db | mv: cannot move '/opt/oracle/homes/OraDB21Home1/network/admin/listener.ora' to '/opt/oracle/oradata/dbconfig/ORCLCDB/': No such file or directory
transact_oracle_db | mv: cannot move '/opt/oracle/homes/OraDB21Home1/network/admin/tnsnames.ora' to '/opt/oracle/oradata/dbconfig/ORCLCDB/': No such file or directory
transact_oracle_db | mv: cannot move '/opt/oracle/product/21c/dbhome_1/install/.docker_enterprise' to '/opt/oracle/oradata/dbconfig/ORCLCDB/': No such file or directory
transact_oracle_db | cp: cannot create regular file '/opt/oracle/oradata/dbconfig/ORCLCDB/': No such file or directory
transact_oracle_db | ln: failed to create symbolic link '/opt/oracle/homes/OraDB21Home1/network/admin/sqlnet.ora': File exists
transact_oracle_db | ln: failed to create symbolic link '/opt/oracle/homes/OraDB21Home1/network/admin/listener.ora': File exists
transact_oracle_db | ln: failed to create symbolic link '/opt/oracle/homes/OraDB21Home1/network/admin/tnsnames.ora': File exists
transact_oracle_db | cp: cannot stat '/opt/oracle/oradata/dbconfig/ORCLCDB/oratab': No such file or directory
transact_oracle_db |
transact_oracle_db | Executing user defined scripts
transact_oracle_db | /opt/oracle/runUserScripts.sh: running /opt/oracle/scripts/extensions/setup/swapLocks.sh
transact_oracle_db | Traceback (most recent call last):
transact_oracle_db | File "/opt/oracle/lock.py", line 178, in <module>
transact_oracle_db | main()
transact_oracle_db | File "/opt/oracle/lock.py", line 169, in main
transact_oracle_db | sys.exit(acquire_lock(args.lock_file, sock_file, args.block, args.heartbeat))
transact_oracle_db | File "/opt/oracle/lock.py", line 41, in acquire_lock
transact_oracle_db | lock_handle = open(lock_file, 'a')
transact_oracle_db | IOError: [Errno 13] Permission denied: '/opt/oracle/oradata/.ORCLCDB.exist_lck'
transact_oracle_db |
transact_oracle_db | DONE: Executing user defined scripts
transact_oracle_db |
transact_oracle_db | ORACLE_HOME = [/home/oracle] ? ORACLE_BASE environment variable is not being set since this
transact_oracle_db | information is not available for the current user ID .
transact_oracle_db | You can set ORACLE_BASE manually if it is required.
transact_oracle_db | Resetting ORACLE_BASE to its previous value or ORACLE_HOME
transact_oracle_db | The Oracle base remains unchanged with value /opt/oracle
transact_oracle_db | /opt/oracle/checkDBStatus.sh: line 26: sqlplus: command not found
transact_oracle_db | #####################################
transact_oracle_db | ########### E R R O R ###############
transact_oracle_db | DATABASE SETUP WAS NOT SUCCESSFUL!
transact_oracle_db | Please check output for further info!
transact_oracle_db | ########### E R R O R ###############
transact_oracle_db | #####################################
transact_oracle_db | The following output is now a tail of the alert.log:
transact_oracle_db | tail: cannot open '/opt/oracle/diag/rdbms/*/*/trace/alert*.log' for reading: No such file or directory
transact_oracle_db | tail: no files remaining
transact_oracle_db exited with code 1

I have no idea what might be going on here (I am not a DBA) and would appreciate if you point in the right direction.

BTW, I'm using Windows 11 with WSL with Ubuntu. Everything is running in Linux.

Thank you very much.

Collapse
 
ajeetraina profile image
Ajeet Singh Raina

Hello,

Thanks for finding it useful.

Looks to be a permission issue.

Go to Settings > General > File Sharing > Add require directory to grant it permission to mount the directory.
Image1

-