Reputation: 149
I am trying to build a Docker image, where I need to get list of directories separated by comma under a parent directory and set that in a configuration file copied in the container but the text is never replaced in conf file. below is the docker image. or 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"]
the search and replace thing happens in setup.sh but entering in shell never shows the replacement. however, if I execute the command /setup.sh in container shell it does the job.
Interested to know, how to do that and what I am doing wrong?
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
.......
Expected /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
## Update I removed intermediate setup.sh and doing whole thing in Dockerfile which looks like
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
Upvotes: 2
Views: 9064
Reputation: 263469
Containers are a wrapper around running a process (that wrapper being namespaces and cgroups). The process being run is defined by the ENTRYPOINT and CMD lines of a Dockerfile. You can override the image's default process to run when you run the container, and for the value of CMD, overriding involves passing a different command after the image name.
So when you're Dockerfile ends with:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
CMD ["/setup.sh"]
You have defined the default value for CMD in your image. But when you run:
docker build -t docker-test .; docker run -it docker-test bash
The ./setup.sh
CMD value is replaced by bash
. This means setup.sh
is never run.
You can solve this several ways.
You can run your setup.sh
as part of the image build. If the script has no dependencies on how the container is being run (e.g. external volumes, environment variables passed in, etc), then this is the better choice.
Move your script to an entrypoint and have it finish by running the command provided. When you define both an entrypoint and a cmd, a container is only going to run a single process, so the behavior of docker is to pass the cmd as arguments to the entrypoint. To run the cmd, you need to do that as part of your entrypoint script.
Option #1 looks like the solution you have done, and the answer I'd recommend:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
RUN ["/setup.sh"]
CMD bash
You'll want to include the shell at the top of the script so linux knows how to run it:
#!/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
Option #2 is useful if /mnt/extra-addons/ changes every time you run the container. This looks like:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
ENTRYPOINT ["/setup.sh"]
CMD ["bash"]
With an additional line added to the setup script:
#!/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 "$@"
Upvotes: 0
Reputation: 149
I think the trick was to execute .sh file
Not working
CMD ["/setup.sh"]
Working
RUN /bin/bash -c "/setup.sh"
Final Result
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"
Upvotes: 0
Reputation: 140880
Try this:
addons_path=$(find /mnt/extra-addons/ -type d -maxdepth 1 | tr '\n' ',')
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg
#
or newlines.paste
joins two streams into one. You have just one stream. Use tr
for example to substitute newline for another character.$( ... )
.Upvotes: 3