配置 Dockerfile 以在创建容器时使用 impdp 命令

Configure Dockerfile to use impdp command when the container is created

我正在使用 wnameless/oracle-xe-11g docker 图像创建新图像文件。当我从新图像创建容器时,我希望执行 impdp 命令。如何通过 Dockerfile?

实现

这是我的 Docker 文件

Docker文件

# 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.

现在我通过 ssh 进入容器并 运行ning impdp 手动执行此操作。我尝试使用

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

但不起作用并抛出异常。

所以我的问题是"Is this possible"?如果是,请提供如何实现的代码示例?

谢谢,

更新:异常不是在创建图像时而是在尝试从中创建容器时。

例如,如果我将此作为我的 docker 文件的最后一行

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

然后做一个

docker build -t my/my_oracle .

和运行它作为

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

并检查

docker logs <container_id>

我明白了

/bin/sh: 1: ["impdp", : not found

我认为您被此处的 "smart" 引号搞砸了:

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

将其更改为(我也将每个 cli 参数分开):

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

好的,经过大量试验,阅读 cmd 的工作原理(最终)和其他用户的上述评论提供的 help/inputs,我现在已经想出了如何实现它。

基本上 Docker 只运行一个 CMD(来自文档)。因此,如果我从 wnameless/oracle-xe-11g 创建一个 docker 文件作为

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

那么这将固有地覆盖 wnameless/oracle-xe-11g 的 docker 文件描述的 CMD 命令。

下面是实现它的步骤

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

在我的情况下是

/usr/sbin/startup.sh

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

这里是

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

请注意,您需要在 blockquotes 中包含 impdp 的整个路径和整个操作

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

这里是

/usr/sbin/sshd -D

最终输出应该是这样的

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

就是这样。这应该有效

其他要记住的事情,尤其是在使用上述 oracle docker 文件时,您需要为 oracle_home 设置 ENV 并将其导出到 bash.bashrc,因为这是默认情况下不完成。

# 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

创建一个简单的 shell 脚本 ur_script.sh,它将 运行 impdp 命令。

#!/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

按照原始图像中的说明将此 shell 脚本添加到 /docker-entrypoint-initdb.d/ 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/

该脚本会在容器第一次启动时自动执行。你的数据库转储将被加载