Monday, January 17, 2022

Installing Oracle Database and Tomcat on WSL-2/Docker

What are we installing?
  • Windows Subsystem for Linux (WSL2)
  • Docker Desktop for Windows
  • Oracle Database
  • Tomcat Web Server
What do we need?
  • Computer/Laptop
  • Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11
  • 16 Gb Memory Recommended
Overview:
  • Setup Windows Subsystem for Linux (WSL2).
  • Setup Docker for Windows.
  • Load and Run a Docker Image that has an Oracle Database.
  • Load and Run a Docker Image that has a Tomcat WebApp Server.
  • Failed ORDS Docker Image with Failure Source Identified.

Windows Subsystem for Linux (WSL2)

This procedure was sourced from Microsoft.com: Install WSL:
  • Run CMD as Administrator
    • wsl -l -v
      • Should show "NAME STATE VERSION" heading with a line underneath showing "Ubuntu Running 2".  If not, run the "wsl --install" in the next step.
    • wsl --install -d Ubuntu
      • A reboot will be required to activate the installation.
      • The Ubuntu App will run automatically after reboot.
      • The Ubuntu App will create a new username and password. - The username and password created in the Ubuntu App is specific to each separate Linux distribution that you install under WSL and has no relationship to your Windows user name.
      • If any problems, see Microsoft.com: installation-issues
    • wsl --shutdown - Run this if you need to shutdown WSL.
  • Start the Ubuntu App and Run These Commands
    • sudo apt update - Updates the list of packages available for Ubuntu.
    • sudo apt upgrade - Upgrades Ubuntu packages.
  • Review and Set advanced options as needed.  See Microsoft.com: Advanced settings configuration in WSL
See also: Microsoft.com: Setup WSL for Development


Docker Desktop for Windows

  • Go to Docker.com: Docker Desktop
  • Click on "Download for Windows"
  • Run "Docker Desktop Installer.exe"
  • Open Docker Desktop
    • "Settings" --> "Resources" --> "WSL Integration"
    • Turn on "ubuntu" for "enable integration with additional distros:"
    • Apply & Restart
  • Run Ubuntu App
    • (Optional) docker run hello-world

Oracle Database

This procedure will persist the database files outside of the Docker container at "/opt/OraEE213/oradata" in WSL2/Ubuntu.  After the database is created, it will re-open with all saved changes if the Docker container is restarted.
  • Open the Ubuntu App and Run These Commands:
sudo mkdir /opt/OraEE213/oradata

sudo chown 54321 /opt/OraEE213/oradata

docker network create oranet

docker login container-registry.oracle.com

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

docker run -d --restart unless-stopped --network=oranet -p 1521:1521 -p 5500:5500 -e ORACLE_SID=EE213CDB -e ORACLE_PDB=TESTPDB -e 'ORACLE_PWD=OraEE213#!' -v /opt/OraEE213/oradata:/opt/oracle/oradata -v /opt/install_files:/opt/install_files --name OraEE213 container-registry.oracle.com/database/enterprise:21.3.0.0
  • Run Docker Desktop
    • Select "Containers/Apps" in the menu list on the left.
    • Click on the "Logs" Icon in the "OraEE213" container line.
    • The log of the database installation will appear.
    • Wait for this banner before attempting to use the database:

#########################

DATABASE IS READY TO USE!

#########################

    • (Optional) Click the ">_" Icon (CLI) on the "OraEE213" container line and run "sqlplus / as sysdba" to login to the container database as "SYS".
    • (Optional) Connect to the container database from an Oracle client using the connect string "//localhost:1521/EE213CDB" and "system/OraEE213#!" login.
    • (Optional) Connect to the pluggable database from an Oracle client using the connect string "//localhost:1521/TESTPDB" and "system/OraEE213#!" login.
    • (Optional) Check OEM DB Express at url https://localhost:5500/em/login, Username: SYSTEM, Password: OraEE213#!, Container Name: (Blank)

Tomcat Web Server

  • Open the Ubuntu App and Run This Command
    • docker run -d --restart unless-stopped --network=oranet -p 8080:8080 -v /opt/TomCat9r0/webapps:/usr/local/tomcat/webapps -v /opt/install_files:/opt/install_files --name TomCat9r0 tomcat:9.0
  • Run Docker Desktop
    • Select "Containers/Apps" in the menu list on the left.
    • Click the ">_" Icon (CLI) on the "TomCat9r0" container line.
    • Run these commands:
cp -rf "/usr/local/tomcat/webapps.dist"/* "/usr/local/tomcat/webapps"

sed "-i_bak" -e '$s?^</tomcat-users>$?<role rolename="manager-gui"/><user username="manager" password="tomcat" roles="manager-gui"/></tomcat-users>?1' "/usr/local/tomcat/conf/tomcat-users.xml"

sed "-i_bak" -e '/RemoteAddrValve/d' -e '/0:0:0:0:0:0:0:1/d' "/usr/local/tomcat/webapps/manager/META-INF/context.xml"

sed "-i_bak" -e '/RemoteAddrValve/d' -e '/0:0:0:0:0:0:0:1/d' "/usr/local/tomcat/webapps/host-manager/META-INF/context.xml"
  • (Optional) Go to "http://localhost:8080/"
    • Click on "Manager App" button
    • Login with Username "manager" and password "tomcat"
    • Confirm Tomcat Web Applications are available and working.

Next Post: Installing ORDS and Oracle APEX

In the next post "Installing ORDS and Oracle APEX on WSL-2/Docker", we look at installing ORDS and Oracle APEX

Addendum: Failed ORDS Docker image

An alternative to the Tomcat installation is using Oracle's ORDS Dockerfile to create a Docker Container with ORDS.  However, there are 2 problems with this alternative:
  1. There is a bug in Oracle's Dockerfile (shown below).
  2. Multiple Docker Containers are required for each ORDS deployment.  Each deployment of ORDS requires a different HTTP Port Number.  With Tomcat, all ORDS servers share the same HTTP Port Number.
For the source of this section, see Oracle.com: Container Registry: "Database" --> "ords" --> "Oracle REST Data Services (ORDS) with Application Express"
  • Open the Ubuntu App and Run These Commands:
sudo mkdir "/opt/ords21.4.0"

echo 'CONN_STRING=SYS/OraEE213#!@//OraEE213:1521/TESTPDB' > "/tmp/conn_string.txt"

sudo mv "/tmp/conn_string.txt" "/opt/ords21.4.0"

docker run --rm --network=oranet -p 8181:8181 -v /opt/ords21.4.0:/opt/oracle/variables --name ords21.4.0 container-registry.oracle.com/database/ords:21.4.0
  • FAILS with this message:
INFO : This container will start a service running ORDS 21.4.0 and APEX 21.2.0.
INFO : CONN_STRING has been set as variable on container.
INFO : Database connection established.
INFO : Apex is not installed on your database.
INFO : Installing APEX on your DB please be patient.
INFO : If you need more verbosity run below command:
docker exec -it b402760c75a3 tail -f /tmp/install_container.log
INFO : APEX has been installed.
INFO : Configuring APEX.
INFO : APEX_PUBLIC_USER has been configured as oracle.
INFO : APEX ADMIN password has configured as 'Welcome_1'.
INFO : Use below login credentials to first time login to APEX service:
Workspace: internal
User: ADMIN
Password: Welcome_1
INFO : Preparing ORDS.
INFO : Installing ORDS on you database.
Requires to login with administrator privileges to verify Oracle REST Data Services schema.

Connecting to database user: SYS as sysdba url: jdbc:oracle:thin:@////OraEE213:1521/TESTPDB
2022-01-18T00:14:23.731Z WARNING Failed to connect to user: SYS as sysdba url: jdbc:oracle:thin:@////OraEE213:1521/TESTPDB
IO Error: Invalid connection string format, a valid format is: "//host[:port][/service_name]" (CONNECTION_ID=DUId2GdqTiaf5/93oFpqsw==)

java.sql.SQLRecoverableException: IO Error: Invalid connection string format, a valid format is: "//host[:port][/service_name]"  (CONNECTION_ID=DUId2GdqTiaf5/93oFpqsw==)
INFO : Starting ORDS....
2022-01-18T00:14:27.622Z WARNING     Failed to connect to user: ORDS_PUBLIC_USER url: jdbc:oracle:thin:@////OraEE213:1521/TESTPDB
IO Error: Invalid connection string format, a valid format is: "//host[:port][/service_name]"  (CONNECTION_ID=Z2b/FsUxR1C7IzNDt5+RTQ==)

Problem: The "/opt/oracle/ords/startService.sh" script in the container splits the $CONN_STRING value into DB_USER, DB_PASS, DB_HOST, DB_PORT, and DB_NAME variables.  The DB_HOST value retains the leading "//" in front of the hostname in the $CONN_STRING value.  The "//" is required for the database connection, but fails when used by ORDS.

update: Changed "\" to "/" on database connect strings.