Skip to main content

Dockerize your APEX development environment

Nowadays Docker is everywhere. It is one of the main components of Continuous Integration / Continuous Development environments. That alone indicates Docker has to be seen more as a Software Delivery Platform than as a replacement of a virtual machine.

However ...

If you are running an Oracle database using Docker on your local machine to develop some APEX application, you will probably not move that container is a whole to test and production environments. Because in that case you would not only deliver a new APEX application to the production environment - which is a good thing - but also overwrite the data in production with the data from your development environment. And that won't make your users very excited.
So in this set up you will be using Docker as a replacement of a Virtual Machine and not as a Delivery Platform.
And that's exactly the way Martin is using it as he described in this recent blog post. It is an ideal way to get up and running with an Oracle database in a Docker container in a very short time (you have to download 3.5 Gb, so dependent on your connection that might take some time). This works fine for a short PoC. But what if you want to be sure your container lives a bit longer than a week or two? Because, if your container gets blown away for some sort of reason, you will lose all your data. The original image is still there, but that contains just the starting situation. A.k.a. an empty database. And - from recent experience - I can tell you that containers can get destroyed (in this case by an upgrade of the Docker software). The whole concept of containers is that they are ephemeral, lasting for a short period of time.

But luckily we can set up a Docker container in a way we are sure our data is safe, even when the container is destroyed. We can use volume mapping for that. So we don't need to download the complete installed database from the link Martin mentioned in his blog, but we need the Docker build files and the required Oracle database software and build the image ourselves. Exactly as Maria describes in her blogpost.
In my setup, once the image was created, I started the container by issuing this command:
docker run --name oracle -p 1521:1521 -p 5500:5500 \ -v /Users/Roel/docker/database:/opt/oracle/oradata \ oracle/database:12.2.0.1-ee
The advantage is all my data is stored outside my container, on my local machine. The container itself is static - there will be no changes there. So if the container blows up, I can just spin up a new one using the same data that is still stored on my disk. And it seems a bit faster as well ....

But if we want to develop APEX applications, we need to have ORDS installed somewhere as well. Of course we could just run ORDS locally connecting to the (forwarded) port 1521. But it would be way nicer if ORDS would run in a Docker container as well!
Before we start that second container, we have to make sure both containers are able to connect to each other. It is possible using the --link switch, but that is deprecated. The new way of connecting containers together, is to create a Docker network:
docker network create my_network
Then we add our running database container, named "oracle", to that network:
docker network connect my_network oracle
And now we can go looking for a Docker image for our ORDS. If you issue the command:
docker search ords
you'll get a few hits. As we already have a database running, we need an image just containing ORDS and fire that up - in this case the image lucassampsouza/ords_apex:3.0.9.
docker run -t -i \ --name ords \ --network=my_network \ -e DATABASE_HOSTNAME="oracle" \ -e DATABASE_PORT="1521" \ -e DATABASE_SERVICENAME="ORCLPDB1" \ -e DATABASE_PUBLIC_USER_PASS=oracle \ -e APEX_LISTENER_PASS=oracle \ -e APEX_REST_PASS=oracle \ -e ORDS_PASS=oracle \ --volume /Users/Roel/docker/apex/images:/usr/local/tomcat/webapps/i \ -p 8080:8080 \ lucassampsouza/ords_apex:3.0.9
It is version 3.0.9, but of course you can upgrade it yourself - or just wait for a newer version.
Some remarks about this command:
  • The --network switch adds this new container to the network immediately. 
  • I can reference the hostname of the database - normally the name or IP-address of the machine where the database is running on - by the name of the container, "oracle".
  • I defined (another) volume mapping for this container in a way my APEX images directory is located on my local machine. Thus I can easily patch or update APEX without touching the container. If this container gets blown away ... I just fire up a new one with this same command and I am ready to go.
So now we have two containers running next to each other. Nice. But now I need a solution for printing as well. So I asked Dimitri whether he has a Docker image of his APEX Office Print (AOP) solution. And he was kind enough to make one available for me. So very similar to the ORDS one, I started this one up, attached to that same network - and also with another volume mapping to a directory that holds my license key:
docker run -d \ --name apexofficeprint \ --network=my_network \ -p 8010:8010 \ -v /Users/Roel/docker/apexofficeprint/:/apexofficeprintstartup/ \ apexrnd/apexofficeprint \ -s /apexofficeprintstartup/
So now I only needed two more steps to make it working. First define the AOP URL in the component settings of AOP in APEX: http://apexofficeprint:8010/.(again notice the use of the container name in that URL). And finally open up the ACL for the APEX owner, so it is possible to connect from within the database to the AOP container:
begin dbms_network_acl_admin.append_host_ace ( host => 'apexofficeprint', lower_port => 8010, upper_port => 8010, ace => xs$ace_type(privilege_list => xs$name_list('http'), principal_name => 'APEX_050100', principal_type => xs_acl.ptype_db)); end;
So this complete configuration is totally ephemeral (love using that word again) as all important data is stored on my local disk. And I can easily burn or replace containers - for instance when a new version of the ORDS or AOP image comes available.
To end up, this is how it looks as a picture:
Now go and try it yourself!

Post a Comment

Popular posts from this blog

Showing a success message after closing a modal dialog

APEX 5 comes with Modal Dialogs out of the box. Very neat. Especially for adding and changing data. And to minimise the number of time a user has to click, it could be useful to add a "Close Dialog" process after the actual data processing. When the data processing fails, the Dialog stays on top showing the error. When data processing runs fine, the Dialog is closed ... without any confirmation. And this might be scary for a shaky user.

So how can we provide the user some feedback? On Page 4 of the Sample Dialog Application you can see one solution: up on a Dialog Closed Event on the parent page it does a redirect to refresh the parent page appending the success message of the "Close Dialog" process. This has two drawbacks. First, it probably refreshes more than necessary. And second, if you're using multiple layers of dialogs (dialogs that open other dialogs) the message appears in the "parent dialog".
As an alternative you could follow these steps: 1…

A review of APEX World 2017 - Day 1

Last week the SS Rotterdam was the beautiful location of the largest gathering of APEX Developers worldwide. With around 380 (!) attendees a new high was set. And they came from all over the world : I spotted people from The Netherlands, Belgium, Switzerland, Austria, Croatia, Germany, Denmark, Norway, UK, Ireland and the USA. And I even might have missed one or two ….

The event started with a presentation by the “father of APEX”, Mike Hichwa, talking about "Oracle APEX Past, Present and Future”. Of course everyone is curious what the APEX future might bring: Friendly URL’s, automated testing, more JSON, concurrent APEX versions, third party Oauth 2 authentication (think Facebook, Google), APEX app diff and more, a lot more, REST capabilities. And now we have to wait for APEX 5.2 … and that might take a while! 
After this keynote, the conference split up in three tracks. After the coffee break I returned to to big theatre where Geertjan Wielenga talked about "Finally Javas…

It's happening again ... running for the ODTUG Board of Directors 😉

For the third time in a row I'll be running for ODTUG's Board of Directors. But after ending as a runner up twice, I am sure I'm going to make it this time! But not without your help!

My campaign statement this year is:
I have been attending and presenting at Kscope conferences since 2007. This not only resulted in a vast amount of knowledge, but also - and even more important - a huge number of friends from all over the globe.  I want to see ODTUG grow and spread this community feeling even more! 
My experience as an attendee, presenter and content lead has provided the basic foundation to be a director. Next to that, my personality and (global) network will be beneficial to the whole board and organization. 
Since March I have served on the Board of Directors in a limited term for a Director who stepped down due to a career change. This has allowed me to have unique insight of all the things that are going on in and around the ODTUG organization. As the train was already ro…