Oracle APEX CI/CD: Initial Setup

Oracle APEX CI/CD: Initial Setup

This blog involves several initial setup steps to get going... once it's up and running you can CI/CD in peace and not have to run these steps again.

It should take you one to two hours to configure everything. Be aware, that some steps involve completing steps in some of my other blogs.

The steps are:

  1. Setup a Compute Box running Jenkins on Oracle Cloud

  2. Configure some Firewall rules

  3. Build a APEX+ORDS Docker Image required for CI/CD

Once you are complete with all these steps, you'll need to go back to the Oracle APEX CI/CD: Step-by-step guide aligned to the Application Lifecycle Technical Paper blog, where you'll deploy & test the APEX Sample Customers Application.

Once you are familiar with deploying that APEX Sample Customers Application, you can adapt your repository to deploy & test it with this method.

Let's begin.

Setup a Compute

In this section, we'll install and configure Jenkins and some other tools we need.

Install Jenkins & Associated tools

  1. Set up a new Jenkins compute box on OCI using this guide.

  2. We are going to need more storage as we will be dealing with several large docker images. Follow this guide to add 50GB more storage to your machine.

  3. When complete, on your Jenkins machine install Docker (it's actually podman - this is fine, I'll use the docker commands in case of other O/S's)

     sudo yum install docker -y
    
  4. Install git

     sudo yum install git -y
    
  5. Install NodeJS + dependencies required for Cypress

     cd /home/opc
     sudo dnf module install nodejs:18/common -y
     npm install cypress
    

    Then run the dependencies

     sudo yum install -y xorg-x11-server-Xvfb gtk2-devel gtk3-devel libnotify-devel GConf2 nss libXScrnSaver alsa-lib
    
  6. Install SQLcl

     sudo yum install sqlcl -y
    
  7. Set the JAVA_HOME for SQLcl to work correctly

     export JAVA_HOME=$(readlink -f $(which java) | sed "s:bin/java::")
    
  8. Install the pretius-apex-lifecycle-aligned-utils

     cd /home/opc
     curl -L -o pretius-apex-lifecycle-aligned-utils.zip https://github.com/Pretius/pretius-apex-lifecycle-aligned-utils/archive/refs/heads/main.zip
     unzip pretius-apex-lifecycle-aligned-utils.zip
     mv pretius-apex-lifecycle-aligned-utils-main pretius-apex-lifecycle-aligned-utils
     rm pretius-apex-lifecycle-aligned-utils.zip
    
  9. Optional: Install the lifecycle scripts from the Oracle APEX Application Development Lifecycle Technical Paper

     cd /home/opc
     curl -L -o lifecycle-technical-paper-files.zip https://apex.oracle.com/go/lifecycle-technical-paper-files
     unzip lifecycle-technical-paper-files.zip -x "__MACOSX/*"
     rm lifecycle-technical-paper-files.zip
    

Create a Jenkins Agent

This blog will create a new agent running on the same machine as Jenkins. If you plan to have docker 23c on another machine, you can run these commands there instead.

  1. Log in to Jenkins Dashboard via your Web Browser

  2. Disable the Built-in Node by following these steps:

    Dashboard > Manage Jenkins > Manage Nodes and Clouds > Built in Node > Configure > Number of executors > 0 > Save

  3. Add a new Permanent Agent:

    Dashboard > Manage Jenkins > Manage Nodes and Clouds > New Node > Node Name > jenkinsnodecicd

  4. Select Permanent Agent and click Create

  5. Set Remote root directory to:

     /home/opc/jenkinsnodecicd
    
  6. Set Use WebSocket to Checked

  7. Save

  8. Click on the jenkinsnodecicd,
    IMPORTANT: There are two code boxes here... We'll only use the first one.

  9. in Terminal, make a folder and then change the directory to /home/opc

     mkdir /home/opc/jenkinsnodecicd
     cd /home/opc
    
  10. Run the first line from the first code box (i.e starts with curl) in the terminal e.g.
    curl -sO http://xxx.xxx.xxx.xxx:8080/jnlpJars/agent.jar

  11. We are going to make this agent auto-load on a reboot of the UNIX box. Create a new file like this:

    sudo nano /etc/systemd/system/jenkins-cicd-node.service
    
  12. Paste in the following... IMPORTANT: Remember to change the line stated after you paste it in. Tip: Paste the below into a text editor, change the values and then paste it into nano.

    [Unit]
    Description=Jenkins CICD Node agent
    After=syslog.target
    
    [Service]
    Type=simple
    User=opc
    ExecStart=/usr/bin/java -jar /home/opc/agent.jar -jnlpUrl [PASTE IN FROM LINE TWO STARTING WITH http:// AND ENDING WITH THE END OF THE CODE BOX]
    Restart=always
    RestartSec=30
    
    [Install]
    WantedBy=multi-user.target
    
  13. Enable, start and check the service.

    sudo systemctl enable jenkins-cicd-node.service
    sudo systemctl start jenkins-cicd-node.service
    sudo systemctl status jenkins-cicd-node.service
    
  14. Press Ctrl + C once to exit viewing the end of the file.

  15. Refresh your browser and the agent will be connected

Firewall Rules

  1. Add firewall rules so we can see the docker externally.

    IMPORTANT: make sure the last line runs

     YOURPORT=8023
     PERM="--permanent"
     SERV="$PERM --service=apex23cfree"
    
     sudo firewall-cmd $PERM --new-service=apex23cfree
     sudo firewall-cmd $SERV --set-short="APEX23cFree ports"
     sudo firewall-cmd $SERV --set-description="APEX23cFree port exceptions"
     sudo firewall-cmd $SERV --add-port=$YOURPORT/tcp
     sudo firewall-cmd $PERM --add-service=apex23cfree
     sudo firewall-cmd --zone=public --add-service=http --permanent
     sudo firewall-cmd --reload
    
  2. Optional/Recommended: expose the docker external port to view APEX externally - see next steps

  3. In your Compute Instance, Right-click the VCN hyperlink and open the link in a new tab

  4. Click on Security Lists

  5. Click on Default Security List

  6. Click Add Ingress Rule using the following details:

  7. Click Add Ingress Rule at the bottom

Build the APEX+ORDS Docker Image

Almost there.

In this section, we are going to pull the Official Oracle 23cFree docker image, we'll add APEX and ORDS to a new container. Then (returning to this guide) we are going to prepare the container for imaging, image it and then test it out to see if it's ready to use for CICD.

  1. Construct your docker image using this guide. However, when it comes to testing, switch localhost for the IP address of your Unix box.

  2. Enter the docker container

      docker exec -it 23cfree /bin/bash
    
  3. We are going to do a bit of preparation next. All these changes are temporary and will reactivate again the next time the container is started.

    First, stop ORDS

     sudo sh /home/oracle/scripts/stop_ords.sh
    

    Connect to the DB

     sqlplus / as sysdba
    

    now shut down the DB

     shutdown
    

    then exit SQLPlus

     exit
    
  4. Exit out of docker bash.

     exit
    
  5. Commit this container as an image so that we can use it for CI/CD. Drop to the terminal and type

     docker ps
    

    you should see your container reference - e.g 5696fabdd5d7

    Now run the following to make an image of this container (25mins)

    FUN FACT: This step took so long that I spent most of the time waiting for it to complete by writing this blog.

    IMPORTANT: Do not interrupt the terminal/press random keys until it finishes or you'll have to re-run this lengthy step (this happened to me once).

     docker commit 5696fabdd5d7 23cfreeapeximg
    

    You can ignore the WARN messages

    When finished entire output would look like this...

     [opc@jenkins-2 ~]$ docker commit 67c538ec7fca 23cfreeapeximg
     WARN skipping since it is a socket
     Getting image source signatures
     Copying blob 02b6badf6ca4 skipped: already exists
     Copying blob 31e3dab70331 skipped: already exists
     Copying blob 64a8d294e45f skipped: already exists
     Copying blob 49d330f0ae32 skipped: already exists
     Copying blob 3f8984bc5a38 done
     Copying config 65d5c6963c done
     Writing manifest to image destination
     Storing signatures
     65d5c6963ca1bbc35694a36c38d1c5824f32157a4355e85edf80ce86cd41a8ab
    
  6. stop the 23cfree container as it's hogging our ports. We won't remove it completely as the idea is that this will be used for upgrades & this blog will be updated accordingly

     docker stop 23cfree
    
  7. Create a new container with the new image to test it

     docker run -d -it --name 23claunch -p 8521:1521 -p 8500:5500 -p 8023:8080 -p 9043:8443 -e ORACLE_PWD=E localhost/23cfreeapeximg
    

    Information only - don't run this step: If you need to bash to it, you can use

     docker exec -it 23claunch /bin/bash
    
  8. Give it 60 seconds, then test that APEX can be reached:

     wget -O - http://localhost:8023/ords
    

    A Success looks like this (what you are seeing here is part of the HTML from the APEX sign-in page)

     apex.item( 'F4550_P1_COMPANY' ).setFocus();
     } finally {
     apex.event.trigger(apex.gPageContext$,'apexreadyend');
     };
     });
     });
     });apex.pwa.cleanup( { serviceWorkerPath:'\u002Fords\u002Fr\u002F\u002Flogin\u002Fsw.js?v=22.2.0-3142018\u0026lang=en' } );
     </script>
    
     -                       [ <=>                ]  21.95K  --.-KB/s    in 0.001s
    
     2023-04-13 20:35:50 (25.1 MB/s) - written to stdout [22476]
    

    If you see infinite connection retries, then sadly this step failed. You'll have to remove your container and image and repeat the docker commit step above. To remove the container and image, follow this step

     # DO NOT RUN THIS STEP IF YOU SAW A SUCCESS ABOVE
     docker rm 23claunch
     docker rmi localhost/23cfreeapeximg
    
  9. Enable linger (source #17) - you may have already run this. But it can be run again.

     loginctl enable-linger $UID
    
  10. Testing is over now: so stop and remove the container

    docker stop 23claunch
    docker rm 23claunch
    

Success

Now return to the Oracle APEX CI/CD: Step-by-step guide aligned to the Application Lifecycle Technical Paper blog