sed inline replacement not working from Dockerfile

2019-05-23 03:01发布

问题:

I'm trying to create a Docker image for cups, and one of the steps I want to perform is to comment out the "Listen" directives. This output from a sample build demonstrates the issue:

Step 8 : RUN sed "s/^Listen /#Listen /" /etc/cups/cupsd.conf | grep Listen
 ---> Running in 6b9dfeeaec7a
#Listen localhost:631
#Listen /var/run/cups/cups.sock
 ---> 1737a534589d
Step 9 : RUN sed -i "s/^Listen /#Listen /" /etc/cups/cupsd.conf
 ---> Running in aacd768eb94c
 ---> dbe12c2073ef
Step 10 : RUN grep "Listen" /etc/cups/cupsd.conf
 ---> Running in 650b27ecf7c4
Listen localhost:631
Listen /var/run/cups/cups.sock
 ---> bf03b9f5de35
Successfully built bf03b9f5de35

Why does the first call to sed that gets piped to grep work perfectly, but the second with the -i flag not make any changes?

If I run the container interactively (docker run -it cups sh) and copy and paste the command (sed -i "s/^Listen /#Listen /" /etc/cups/cupsd.conf) then the change is made as expected.

Here's the full Dockerfile:

FROM ubuntu:16.04

RUN apt-get --quiet update && apt-get --quiet --assume-yes --allow-downgrades --allow-remove-essential --allow-change-held-packages dist-upgrade

# Install cups
RUN apt-get install --quiet --assume-yes --allow-downgrades --allow-remove-essential --allow-change-held-packages cups

VOLUME /etc/cups/

EXPOSE 631

RUN apt-get install --quiet --assume-yes --allow-downgrades --allow-remove-essential --allow-change-held-packages less vim

RUN sed -i "s/^Listen /#Listen /" /etc/cups/cupsd.conf

Build command is: docker build --tag cups:test .

Run command is: docker run -it cups:test bash

docker info output:

Containers: 9
 Running: 6
 Paused: 0
 Stopped: 3
Images: 61
Server Version: 1.12.1
Storage Driver: aufs
 Root Dir: /mnt/storage/var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 65
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host bridge null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor
Kernel Version: 4.4.0-31-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.555 GiB
Name: servy
ID: LJZV:A2VY:BZPY:HHQX:DWSP:IAMK:XI43:Q7BA:YKVU:ONQX:VBHJ:GXRT
Docker Root Dir: /mnt/storage/var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

Output from docker --version:

Docker version 1.12.1, build 23cf638

Thanks

回答1:

The problem is in the:

VOLUME /etc/cups/

After that line, any changes to /etc/cups may not be seen in the final container (some single file copy commands do apply, so it's not perfect).

Either move your volume line to the end, or preferably remove it from your image entirely. These entries block the ability to extend your image with changes to this folder later. And you can always make your own volume with the docker run -v ... where you want it (or in your docker-compose.yml). Creating volumes in the image means you'll get anonymous volumes listed in docker volume ls after running your image.