如何在Docker映像中替换conf文件中的文本

时间:2018-10-01 13:13:33

标签: shell docker sed

我正在尝试构建Docker映像,在该映像中,我需要在父目录下获取用逗号分隔的目录列表,并将其设置在复制到容器中的配置文件中,但是文本永远不会在conf文件中替换。下面是docker映像。或Github Link

FROM ubuntu:16.04
LABEL maintainer="TEST"

RUN apt-get update && apt-get install vim git -y

COPY odoo.conf /etc/odoo/odoo.cfg

RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world1
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world2
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world3
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world4

COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
CMD ["/setup.sh"]

搜索和替换发生在setup.sh中,但在shell中输入则永远不会显示替换。但是,如果我在容器外壳中执行命令/setup.sh,它将完成此工作。

有兴趣知道该怎么做以及我做错了什么?

setup.sh

# get addons path
addons_path=`ls -d /mnt/extra-addons/* | paste -d, -s`
# can't use / because directory name contains, using #
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg

/etc/odoo/odoo.conf

[options]
addons_path = __addons__path__
data_dir = /var/lib/odoo
.......

预期 /etc/odoo/odoo.conf

[options]
addons_path = /mnt/extra-addons/hellow-world1,/mnt/extra-addons/hellow-world2,/mnt/extra-addons/hellow-world3,/mnt/extra-addons/hellow-world4
data_dir = /var/lib/odoo

##更新 我删除了中间setup.sh并在Dockerfile中完成了整个工作

FROM ubuntu:16.04
LABEL maintainer="TEST"

RUN apt-get update && apt-get install vim git -y

COPY odoo.conf /etc/odoo/odoo.cfg

RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world1
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world2
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world3
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world4
ENV addons_path=$(ls -d /mnt/extra-addons/* | paste -d, -s)  ## Fails here it sets blank so sed command works but the variable addons_path doesn't have the value probably I am defining variable wrongly?
RUN sed -i -e "s#__addons__path__#$addons_path#" /etc/odoo/odoo.cfg

3 个答案:

答案 0 :(得分:0)

尝试一下:

addons_path=$(find /mnt/extra-addons/ -type d -maxdepth 1 | tr '\n' ',')
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg
  1. 如果文件名包含#或换行符,则此方法将无效。
  2. paste将两个流合并为一个。您只有一个流。例如,使用tr将换行符替换为另一个字符。
  3. 不解析ls输出。
  4. 不建议使用``语法,请使用$( ... )

答案 1 :(得分:0)

我认为诀窍是执行.sh文件

不起作用

CMD ["/setup.sh"]

工作

RUN /bin/bash -c "/setup.sh"

最终结果

FROM ubuntu:16.04
LABEL maintainer="TEST"

RUN apt-get update && apt-get install vim git -y

COPY odoo.conf /etc/odoo/odoo.cfg

RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world1
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world2
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world3
RUN git clone https://github.com/kelseyhightower/helloworld.git /mnt/extra-addons/hellow-world4
#ENV addons_path=$(ls -d /mnt/extra-addons/* | paste -d, -s)
#RUN sed -i -e "s#__addons__path__#NEW_PATH#" /etc/odoo/odoo.cfg

COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
RUN /bin/bash -c "/setup.sh"

答案 2 :(得分:0)

容器是运行进程的包装器(该包装器是名称空间和cgroup)。正在运行的进程由Dockerfile的ENTRYPOINT和CMD行定义。您可以覆盖运行容器时运行的图像默认过程,对于CMD的值,覆盖涉及在图像名称后传递另一个命令。

因此,当您使用Dockerfile时,结尾为:

COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
CMD ["/setup.sh"]

您已在图像中定义了CMD的默认值。但是当您运行时:

docker build -t docker-test .; docker run -it docker-test bash

./setup.sh的CMD值替换为bash。这意味着setup.sh永远不会运行。


您可以通过几种方法解决此问题。

  1. 您可以在图像构建过程中运行setup.sh。如果脚本不依赖于容器的运行方式(例如外部卷,传入的环境变量等),那么这是更好的选择。

  2. 将脚本移动到入口点,并通过运行提供的命令完成脚本。当您同时定义入口点和cmd时,容器只会运行一个进程,因此docker的行为是将cmd作为参数传递给入口点。要运行cmd,您需要将其作为入口点脚本的一部分。


选项1看起来像您已经完成的解决方案,以及我建议的答案:

COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
RUN ["/setup.sh"]
CMD bash

您将要在脚本顶部包含外壳程序,以便linux知道如何运行它:

#!/bin/sh
# The #!/bin/sh above is important, you can also replace that with the path to bash
# get addons path
addons_path=`ls -d /mnt/extra-addons/* | paste -d, -s`
# can't use / because directory name contains, using #
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg

如果每次运行容器时/ mnt / extra-addons /都更改,则选项#2很有用。看起来像:

COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
ENTRYPOINT ["/setup.sh"]
CMD ["bash"]

在安装脚本中添加了一行:

#!/bin/sh
# get addons path
addons_path=`ls -d /mnt/extra-addons/* | paste -d, -s`
# can't use / because directory name contains, using #
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg

# this next line runs the passed arguments as pid 1, replacing this script
# this is how you run an entrypoint and fall through to a cmd
exec "$@"