4

I'm using sath89/oracle-12c for automated tests against a oracle db. This works fine, the only problem is that this container takes several minutes to start (~10-15 depending on the hardware). I tried to come up with a healthcheck for this container.

I managed to come up with

status=`su oracle -c "echo -e \"SELECT ACCOUNT_STATUS FROM DBA_USERS WHERE USERNAME = 'ANONYMOUS' AND ACCOUNT_STATUS = 'EXPIRED';\" | /u01/app/oracle/product/12.1.0/xe/bin/sqlplus -S / as sysdba | grep ACCOUNT_STATUS"`; if [ "$status" == "ACCOUNT_STATUS" ]; then true; else false; fi

which returns 0 when the ANONYMOUS account is unlocked, which is the last step in the entrypoint script of the image: entrypoint.sh. I tested this using docker exec -it <containername> bash.

I am now stuck with converting this horribly long line into a healthcheck command for docker (docker-compose):

version: "2"
services:
  db:
    image: sath89/oracle-12c:r1
    healthcheck:
      test: ["CMD", "<command goes here>"]
      interval: 10s
      timeout: 3s
      retries: 3

Any help is appreciated - if you can improve the command itself I'm happy to here. I am aware of "select 1 from dual" as a validation query for Oracle (source), but this reports an operational DB after ~8 minutes but it resets connections a little bit later. I don't want to modify the container itself - if there's an update I just want to be able to pull it from the hub.

Martin
  • 2,754
  • 1
  • 15
  • 35
  • Why don't you put the command into a bash script and add it to the image? Comming to your question, according to the [docu](https://docs.docker.com/engine/reference/builder/#healthcheck), the command is executed via `exec`, thus you have to invoke `bash` and give it your script: `test: ["CMD", "bash", "-c", ""]`. – fzgregor Aug 31 '17 at 14:12
  • I just realized you could also let `docker-compose` do the job of invoking the shell, though it uses `/bin/sh`: `test: ["CMD-SHELL", ""]` – fzgregor Aug 31 '17 at 14:17
  • @fzgregor thanks for the hint to "CMD-SHELL" again. I stumbled across it myself but somehow ignored it. I have given it another try and it looks promising, will post an answer if it actually works. – Martin Sep 05 '17 at 12:48

1 Answers1

4

Okay, so after quite some time I've come up with an solution for my problem. I could simplify the "" a bit:

version: '2.1'
services:
  db:
    image: sath89/oracle-12c:r1
    healthcheck:
      test: ["CMD-SHELL", "if [ \"`echo \\\"SELECT ACCOUNT_STATUS FROM DBA_USERS WHERE USERNAME = 'ANONYMOUS' AND ACCOUNT_STATUS = 'EXPIRED';\\\"|/u01/app/oracle/product/12.1.0/xe/bin/sqlplus -S sys/oracle as sysdba|grep ACCOUNT_STATUS`\" = \"ACCOUNT_STATUS\" ];then true;else false;fi"]
      interval: 30s
      timeout: 3s
      # start_period: 900s
      retries: 30

Right now "docker-compose" does not support the start_period option so the numbers of retries (and the interval) have to be quite high so the container isn't reported as "unhealthy". The Pull Request has already been merged so hopefully it will be in the next release.

Martin
  • 2,754
  • 1
  • 15
  • 35