6

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

这是我的 Docker 文件

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.

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

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

但不起作用并引发异常。

所以我的问题是“这可能吗”?如果是,您能否提供如何实现这一目标的代码示例?

谢谢,

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

例如,如果我将此作为我的 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
4

3 回答 3

7

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

基本上 Docker 只运行一个CMD(来自文档)。wnameless/oracle-xe-11g所以如果我从as创建一个 dockerfile

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

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

所以这里是实现它的步骤

第 1 步:复制从父映像执行的 CMD(来自 Dockerfile)

在我的情况下,那将是

/usr/sbin/startup.sh

第 2 步:使用 && 操作将您自己的 CMD 附加到上述 CMD。

就在这里

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

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

第 3 步:如果父 Dockerfile 包含后台运行进程,请确保它进入最后一个

就在这里

/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 dockerfile 时,您需要为 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
于 2016-07-04T23:42:48.753 回答
1

创建一个简单的 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

按照原始图像https://hub.docker.com/r/wnameless/oracle-xe-11g-r2中的说明将此 shell 脚本添加到 /docker-entrypoint-initdb.d/

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

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

于 2022-01-28T16:12:50.133 回答
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"] 
于 2016-07-04T14:15:29.153 回答