Home > Blockchain >  How to COPY in Dockfiler after volume is mounted
How to COPY in Dockfiler after volume is mounted

Time:06-10

I have a docker-compose.yml file that mounts a couple of volumes. Here is a snippet:

version: '3'

services:
  gitlab-runner:
    build: '.'
    volumes:
      - gitlab-config-volume:/etc/gitlab-runner

volumes:
  gitlab-config-volume:
  external: false

However, my Dockerfile has a COPY action into /etc/gitlab-runner/certs

FROM gitlab/gitlab-runner:latest

COPY files/ca.crt /etc/gitlab-runner/certs/ca.crt

The problem is, that this COPY happens before the mount. Is there a way I can work around this issue?

CodePudding user response:

The easiest approach is to not mount a volume over content configured in your Dockerfile.

services:
  gitlab-runner:
    build: .
    # no volumes:

If the volume actually is configuration, and it includes environment-specific settings like TLS CA certificates, it might not make sense to include this in your image at all. It will usually be easier to inject these files from the host system than to try to copy them into a named Docker volume.

services:
  gitlab-runner:
    # (could still `build: .`, but don't copy config into the image)
    image: gitlab/gitlab-runner:latest
    volumes:
      # uses a host directory and not a named volume
      - ./gitlab-config:/etc/gitlab-runner
cp files/ca.crt gitlab-config/certs/ca.crt
docker-compose up -d

Finally, if you really want the file to be included in your image, but to be able to mount some other content into it, you need to run code in your container to copy the file into the volume. This happens at container startup, so it will happen after the volume mount. This is the most complex option, though.

The shell script is straightforward:

#!/bin/sh

# Copy the CA certificate into the configuration directory if required.
if [ -f /etc/gitlab-runner/ca.crt ]; then
  cp /opt/config/ca.crt /etc/gitlab-runner/certs
fi

# Run the main container command.
exec "$@"

In your Dockerfile, you need to make this script be the ENTRYPOINT (with JSON-array syntax); you need to repeat the CMD from the base image; and you need to copy the default file into the filesystem, somewhere other than the volume mount point. Doing this correctly involves knowing some details of the base image, and finding its Dockerfile is all but essential.

FROM gitlab/gitlab-runner:latest
COPY files/ca.crt /opt/config
COPY entrypoint.sh /opt/config
# These last two lines are derived from the base image and are not generic
ENTRYPOINT ["/dumb-init", "/opt/config/entrypoint.sh", "/entrypoint"]
CMD ["run", "--user=gitlab-runner", "--working-directory=/home/gitlab-runner"]
  • Related