Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

docker-compose named volume with one file: ERROR: Cannot create container for service, source is not directory

I am trying to make the binary file /bin/wkhtmltopdf from the container wkhtmltopdf available in the web container. I try to achieve this with a named volume.

I have the following docker container setup in my docker-compose.yml:

services:
    web:
        image: php:7.4-apache
        command: sh -c "mkdir -p /usr/local/bin && touch /usr/local/bin/wkhtmltopdf"
        entrypoint: sh -c "exec 'apache2-foreground'"
        volumes:
            - wkhtmltopdfvol:/usr/local/bin/wkhtmltopdf
            
    wkhtmltopdf:
        image: madnight/docker-alpine-wkhtmltopdf
        command: sh -c "touch /bin/wkhtmltopdf"
        entrypoint: sh -c "tail -f /dev/null"  # workaround to keep container running
        volumes: 
            - wkhtmltopdfvol:/bin/wkhtmltopdf

volumes:
    wkhtmltopdfvol:

However, I get the following error when running docker-compose up:

ERROR: for wkhtmltopdf  Cannot create container for service wkhtmltopdf:
source /var/lib/docker/overlay2/42e7082b8024ae4ebb13a4f0003a9e17bc18b33ef0677431dd002da3c21dde88/merged/bin/wkhtmltopdf is not directory

.../bin/wkhtmltopdf is not directory

Does that mean that I can't share one file between containers but only directories through a named volume? How do I achieve this?

Edit: I also noticed that /usr/local/bin/wkhtmltopdf inside the web container is a directory and not a file as I expected.

question from:https://stackoverflow.com/questions/66063206/docker-compose-named-volume-with-one-file-error-cannot-create-container-for-se

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It can be tricky to share binaries between containers like this. Volumes probably aren't the mechanism you're looking for.

If you look at the Docker Hub page for the php image you can see that php:7.4-apache is an alias for (currently) php:7.4.15-apache-buster, where "Buster" is the name of a Debian release. You can then search on https://packages.debian.org/ to discover that Debian has a prepackaged wkhtmltopdf package. You can install this using a custom Dockerfile:

FROM php:7.4-apache
RUN apt-get update 
 && DEBIAN_FRONTEND=noninteractive 
    apt-get install --assume-yes --no-install-recommends 
      wkhtmltopdf
# COPY ...
# Base image provides EXPOSE, CMD

Then your docker-compose.yml file needs to build this image:

version: '3.8'
services:
  web:
    build: .
    # no image:, volumes:, or command: override

Just in terms of the mechanics of sharing binaries like this, you can run into trouble where a binary needs a shared library that's not present in the target container. The apt-get install mechanism handles this for you. There are also potential troubles if a container has a different shared-library ecosystem (especially Alpine-based containers), or using host binaries from a different operating system.


The Compose file you show mixes several concepts in a way that doesn't really work. A named volume is always a directory, so trying to mount that over the /bin/wkhtmltopdf file in the second container causes the error you see. There's a dependency issue for which container starts up first and gets to create the volume. A container only runs a single command, and if you have both entrypoint: and command: then the command gets passed as extra arguments to the entrypoint (and if the entrypoint is an sh -c ... invocation, effectively ignored).

If you really wanted to try this approach, you should make web: {depends_on: [wkhtmltopdf]} to force the dependency order. The second container should mount the volume somewhere else, it probably shouldn't have an entrypoint:, and it should do something like command: cp -a /bin/wkhtmltopdf /export. (It will exit immediately once this cp finishes, but that shouldn't matter.) The first container can then mount the volume on, say, /usr/local/bin, and not specially set command: or entrypoint:. There will still be a minor race condition (you're not guaranteed the cp command will complete before Apache starts) but it probably wouldn't be a practical problem.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...