Saturday, June 11, 2022

Docker-compose for Oracle APEX

 
Hello everyone and welcome back to our blog...


In the previous post, we showed you how to run an Oracle XE instance in a docker container and then run ORDS in another container to use it to connect to APEX. 

We first downloaded the Images we needed, then we had to write some codes in the console/Terminal to configure the networks and volumes and for each time we wanted to spin up a DB container or an ORDS container, we had to write a docker-console command and pass all the parameters. 

There is an easier way that we can use to run all the containers with the configurations in just one command, and that tool is docker-compose. In this post, we will show you how to use docker-compose and how to run APEX in docker just as we did last time.

In docker-compose, we use a YAML file to define the services we want to run. By services we mean containers, so each container is represented as a service in docker-compose. Under each service, we can list all the configurations that are related to that service. One advantage of using docker-compose is to make your commands structured, easy to read, and maintain or change. For example, see how the command for running a docker container looks like we you want to write it in the terminal:

    1
    2
    3
    4
    5
    6
    docker run -d --name db-container\
    >          -p 1521:1521\
    >          -e ORACLE_PWD=1230123\
    >          -v db-demo-volume:/opt/oracle/oradata\
    >          --network=demo-network\
    >          --hostname database
    >          oracle-xe-21.3

    It is not easy to read right :). Now let's see how docker-compose will help us make this more efficient. 

    For using docker-compose we just need to create a YAML file wherever we want, so let's create a folder on the desktop and name it demo. In that folder create a file with the name docker-compose.yml

    Oracle XE Service

    We will first define the Oracle XE service with its related configurations in our compose file:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    version: '3.9'
    
    services:
      devdb:
        container_name: devdb
        image: container-registry.oracle.com/database/express:latest
        ports: 
          - 1521:1521
        environment:
          - ORACLE_PWD=1230123
        volumes:
          - dev-vol:/opt/oracle/oradata
        hostname: oracledev
    

    Keep in mind that the first line of every docker-compose file is for specifying the Compose file format version. In our example, we are using version 3.9.

    • The third line is the services we want this file to run, by services we mean containers. Under the services, we will list the containers we want to run. 
    • devdb is the name for our first service (container), the name can be anything but you better give meaningful names. Under this service, we will list the configurations related to it.
    • container_name This is equivalent to the --name tag when using the terminal. 
    • image is the image to be used for spinning up the container 
    • ports to map the ports between the container and the host. The first port is the host port and the second specifies the container port. This is equivalent to -p.
    • environment under this we pass the environment variable to the container, in our example, we are passing the oracle_pwd. This is equivalent to -e (You can create an env file and save all environment variables in it).
    • volumes to specify the paths to mount on the host and the container. The first path is the host and the second is the containers' path. This is equivalent to -v (At the end of the file we will define our volumes). 
    • hostname giving a name to the DB host machine. This is equivalent to --hostname.
    As you see this looks much cleaner than before :). 

    ORDS Service

    We will continue by defining the next service in the document. But before we do that, we need the connection string to tell ORDS how to connect to the database. So, we will create a new folder where the compose file is located, name the folder variables and inside the folder create text file conn_string and write the following in it.
    CONN_STRING=sys/1230123@oracledev:1521/XEPDB1
    Now back to the compose file, under the services we continue by adding the following:

    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    ords:
        container_name: ords
        restart: always
        depends_on:
          - devdb
        volumes:
          - ./variables:/opt/oracle/variables
        ports:
          - 8181:8181
        image: container-registry.oracle.com/database/ords:latest
    

    As you see, it is almost the same as the first service, we have changed the name of the service and container, ports, volume, and the image to use. We just added three lines 16, 17, and 18.

    • restart this will restart the service every time it fails. The database will take some time to be ready to use, in this time ORDS will try to connect to the database and it will fail, so we are retrying to connect every time until the connection is established.
    • depends_on we don't want ORDS service to start before the database service starts. So we are telling the compose that this service has to start after the devdb service. 

    Network and Volumes

    Now we will define the Networks and Volumes that we want to use. As we saw in line 12 of the compose file, we are mounting dev-vol volume to the path in the database container where the data are saved. In this way, we are saving the data on the host machine to prevent losing it when the container gets deleted. We will define this volume and give it a meaningful name, so we don't delete it later by mistake. Then we will define the network where the services will live, this is to make the communication between the services possible. Please note, if you use docker-compose, it will take care of the network configuration but it will give a random name, what we are doing is just giving a name to the network.
    In the same compose file add the following:

    24
    25
    26
    27
    28
    29
    30
    volumes:
      dev-vol:
        name: db-vol
        external: false
    networks:
      default:
        name: demo-network
    

    Final Compose file

    In the end, you should have a docker-compose file that looks like this:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    version: '3.9'
    
    services:
      devdb:
        container_name: devdb
        image: container-registry.oracle.com/database/express:latest
        ports: 
          - 1521:1521
        environment:
          - ORACLE_PWD=1230123
        volumes:
          - dev-vol:/opt/oracle/oradata
        hostname: oracledev
      ords:
        container_name: ords
        restart: always
        depends_on:
          - devdb
        volumes:
          - ./variables:/opt/oracle/variables
    ports: - 8282:8181 image: container-registry.oracle.com/database/ords:latest volumes: dev-vol: name: db-vol external: false networks: default: name: demo-network

    Keep in mind, that the indentation in the docker-compose file is important.

    Docker-compose commands

    Up

    After we have done with the compose file, it is time to run it. Open a command line in the same folder where the compose file is located and write the following:

    1
    docker-compose up  
    

    This command will take care of running the containers, mapping the ports, and configuring the volumes and networks. You will use this command every time you want to run the containers.

    Down

    This command will stop the running containers, removing them and remove the networks associated, but it will keep the volumes:

    1
    docker-compose down       

    Stop

    This command will stop the running containers without removing anything:

    1
    docker-compose stop       

    P.s: If you don't have the images locally, you have to log in to the oracle container registry before running the Up command. Execute the following command in the Terminal and give your credentials

    1
    docker login container-registry.oracle.com       


    So that's it for docker-compose, we hope you found this useful :).

    References:
    • https://docs.docker.com/compose/

    Labels: , , , ,

    4 Comments:

    At June 14, 2022 at 6:07 PM , Anonymous Anonymous said...

    Sad that tutorial is was not tested :(

    ERROR: Named volume "ords-vol:/opt/oracle/variables:rw" is used in service "ords" but no declaration was found in the volumes section.

     
    At June 15, 2022 at 9:19 AM , Blogger Mohamad Bouchi said...

    thank you for mentioning, I have updated the code :)

     
    At September 17, 2022 at 10:52 AM , Anonymous haarehunde said...

    Thanks for the informations;)

     
    At October 2, 2022 at 10:36 AM , Anonymous Carbonit said...

    Thanks for the article;)

     

    Post a Comment

    Note: Only a member of this blog may post a comment.

    Subscribe to Post Comments [Atom]

    << Home