Configure Dockerfile to use impdp command when the container is created

Trying-to-learn picture Trying-to-learn · Jul 4, 2016 · Viewed 9.2k times · Source

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

Answer

Trying-to-learn picture Trying-to-learn · Jul 5, 2016

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