7

I am using wnameless/oracle-xe-11g docker image to create a new image file. And when I create a container from the new image I want the impdp command to be executed. How can this be achieved via Dockerfile?

Here is my Docker file

Dockerfile

# Base Image
FROM wnameless/oracle-xe-11g

# Create database_dump folder at / -location
RUN mkdir ../database_dumps 

# Copy the dump file and put it into database_dumps created earlier
COPY dump_file ../database_dumps

# Give permission to user oracle on oracle folder to create tablespace
and related operations

RUN chown -R oracle /u01/app/oracle/oradata/XE

# RUN the database initial sql.(create tablespace, create user etc)
ADD init.sql /docker-entrypoint-initdb.d/

# Here is where I want to call the impdp command. when a container is
created from this image.

For now I am doing this manually by ssh-ing into the container and running the impdp. I tried to do it using the

CMD ["impdp", "system/oracle NOLOGFILE=Y DIRECTORY.."]

but does not work and throws exception.

So my question is "Is this possible"? If yes can you please provide the code example of how this can be achieved?

Thanks,

Update: The exception is not when creating the image but when trying to create a container from it.

So for example If I include this as the last line of my docker file

CMD [“impdp”, “system/oracle NOLOGFILE=Y DIRECTORY=expdp_dir
DUMPFILE=SAMPLE_MASTER.EXPDP SCHEMAS=c##sample transform=OID:n”] 

Then do a

docker build -t my/my_oracle .

and run it as

docker run -d -p 49160:22 -p 49161:1521 my/my_oracle

and check for

docker logs <container_id>

I see that

/bin/sh: 1: ["impdp", : not found
Trying-to-learn
  • 341
  • 1
  • 3
  • 9
  • You should probably include the exception in the question. – Christian Wattengård Jul 03 '16 at 22:57
  • You can have only one CMD or entry point per docker file, but besides any exceptions it should work. – Robert Moskal Jul 04 '16 at 00:09
  • Hi @ChristianWattengård added the exception/error. – Trying-to-learn Jul 04 '16 at 00:35
  • @Trying-to-learn maybe try attaching into the container using `docker exec -i -t /bin/bash`, find the location of the impdp data pump binary from `/` e.g. `find . -name "impdp" /` Then try specifying the full path of the impdp in the CMD [] area instead of just `"impdp"` – Samuel Toh Jul 04 '16 at 02:09
  • @Trying-to-learn forgot to mention. Let me know if this works thanks. – Samuel Toh Jul 04 '16 at 02:28
  • @SamuelToh I tried what you mentioned but the `docker exec` itself does not run. I got the following error. `/u01/app/oracle/product/11.2.0/xe/bin/impdp: cannot execute binary file` I also tried `docker exec -it /u01/..impdp` without the `/bin/bash` and that threw a complete different error `UDI-00013: Message 13 not found: No message file for product=RDBMS, facility=UDI UDI-00019: You may need to set oracle_home to your oracle software directory` But if I do `ssh root@192.168.99.100` and then run the `impdp` command everything works. – Trying-to-learn Jul 04 '16 at 10:41

3 Answers3

9

Ok, I have now figured how to make it happen, after much of experimenting,reading how the cmd works (finally) and the help/inputs provided by the above comments from other users.

Basically Docker runs only one CMD (from the docs). So if I create a dockerfile from wnameless/oracle-xe-11g as

From wnameless/oracle-xe-11g
...
...
CMD ["impdp", "...."]

then this will inherently override the CMD command described by the wnameless/oracle-xe-11g's docker file.

So here are the steps to be done to achieve it

Step 1: copy the CMD's executed from the parent image (from the Dockerfile)

In my case that would be

/usr/sbin/startup.sh

Step 2: append your own CMD to the above CMD using && operation.

here it would be

bin/bash  -c "/u01/app/oracle/product/11.2.0/xe/bin/impdp system/oracle NOLOGFILE=Y

Note that you need to include the entire path of the impdp and the whole operation inside blockquotes

Step 3: If the parent Dockerfile contains a background running process make sure that it goes in the last

Here it would be

/usr/sbin/sshd -D

The final output should be something like this

CMD /usr/sbin/startup.sh 
&& bin/bash  -c "/u01/app/oracle/product/11.2.0/xe/bin/impdp
system/oracle NOLOGFILE=Y ..." 
&& /usr/sbin/sshd -D

That's it. This should work

Other things to keep in mind especially when using the above oracle dockerfile is you need to set the ENV for oracle_home and also export it to the bash.bashrc as this is not done by default.

# Add env variables for oracle_home and related
ENV ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe \
ORACLE_SID=XE

#Export oracle_home and related
RUN echo 'export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe' >> etc/bash.bashrc
RUN echo 'export PATH=$ORACLE_HOME/bin:$PATH' >> /etc/bash.bashrc
RUN echo 'export ORACLE_SID=XE' >> /etc/bash.bashrc
Trying-to-learn
  • 341
  • 1
  • 3
  • 9
1

Create a simple shell script ur_script.sh which will run the impdp command.

#!/bin/bash
echo Load DDL and DML
export TIMESTAMP=`date +%a%d%b%Y`
$ORACLE_HOME/bin/impdp system/oracle full=Y directory=data_pump_dir dumpfile=sample_data.dmp logfile=expdp_log_${TIMESTAMP}.log
echo Complete

Add this shell script to /docker-entrypoint-initdb.d/ as instructed in the original image https://hub.docker.com/r/wnameless/oracle-xe-11g-r2

# Dockerfile
FROM wnameless/oracle-xe-11g-r2
ADD ur_script.sh /docker-entrypoint-initdb.d/

This script will be automatically executed when the container started for first time. And your db dump will be loaded

Vrishank
  • 302
  • 4
  • 22
0

I think you're getting messed up by the "smart" quotes here:

CMD [“impdp”, “system/oracle NOLOGFILE=Y DIRECTORY=expdp_dir DUMPFILE=SAMPLE_MASTER.EXPDP SCHEMAS=c##sample transform=OID:n”] 

Change that to (I've also separated each cli parameter):

CMD ["impdp", "system/oracle", "NOLOGFILE=Y", "DIRECTORY=expdp_dir", "DUMPFILE=SAMPLE_MASTER.EXPDP", "SCHEMAS=c##sample", "transform=OID:n"] 
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Hi @BMitch tried that but still does not work. the container exists with the message `UDI-00013: Message 13 not found; No message file for product=RDBMS, facility=UDI` `UDI-00019: You may need to set ORACLE_HOME to your Oracle software directory` – Trying-to-learn Jul 04 '16 at 17:37
  • The exact error was like this, please ignore the above comment. `docker: Error response from daemon: Container command 'impdp' not found or does not exist..` After that i tried it wilth `"/bin/bash"` and even with `"/bin/sh"` and got the following errors. it seems like it is not working `UDI-00013: Message 13 not found; No message file for product=RDBMS, facility=UDI` `UDI-00019: You may need to set ORACLE_HOME to your Oracle software directory` – Trying-to-learn Jul 04 '16 at 17:47
  • 1
    These are different error messages from the one you first posted. Looks like you've gotten past your Dockerfile issues and now have Oracle environment problems. – BMitch Jul 04 '16 at 20:38