【问题标题】:Configure Dockerfile to use impdp command when the container is created将 Dockerfile 配置为在创建容器时使用 impdp 命令
【发布时间】:2016-11-05 14:41:38
【问题描述】:

我正在使用 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

【问题讨论】:

  • 您可能应该在问题中包含异常。
  • 每个 docker 文件只能有一个 CMD 或入口点,但除了任何例外情况外,它应该可以工作。
  • 嗨@ChristianWattengård 添加了异常/错误。
  • @Trying-to-learn 可以尝试使用docker exec -i -t &lt;image_id&gt; /bin/bash 附加到容器中,从/ 中找到 impdp 数据泵二进制文件的位置,例如find . -name "impdp" / 然后尝试在 CMD [] 区域中指定 impdp 的完整路径,而不仅仅是 "impdp"
  • @Trying-to-learn 忘了提及。让我知道这是否有效,谢谢。

标签: docker oracle11g dockerfile impdp


【解决方案1】:

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

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

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

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

所以这里是实现它的步骤

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

在我的情况下是

/usr/sbin/startup.sh

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

就在这里

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

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

第 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

【讨论】:

  • 太棒了!节省了我很多时间!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    我认为你被这里的“聪明”引号搞砸了:

    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"] 
    

    【讨论】:

    • 嗨@BMitch 试过了,但还是不行。容器存在,消息为UDI-00013: Message 13 not found; No message file for product=RDBMS, facility=UDIUDI-00019: You may need to set ORACLE_HOME to your Oracle software directory
    • 确切的错误是这样的,请忽略上面的评论。 docker: Error response from daemon: Container command 'impdp' not found or does not exist.. 之后我尝试了"/bin/bash" 甚至"/bin/sh" 并得到了以下错误。好像不行UDI-00013: Message 13 not found; No message file for product=RDBMS, facility=UDIUDI-00019: You may need to set ORACLE_HOME to your Oracle software directory
    • 这些错误消息与您第一次发布的错误消息不同。看起来您已经解决了 Dockerfile 问题,现在遇到了 Oracle 环境问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2015-04-15
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多