最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to access bound mounts during docker build - Stack Overflow

programmeradmin3浏览0评论

I've defined a docker-compose.yml like this:

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    image: test-api-local
    environment:
      STORAGE_TYPE: local
      DATA_DIR: /data
      CACHE_DIR: /cache
      DEBUG: "true"
    ports:
      - "8000:8000"
    volumes:
      - type: bind
        source: /home/user/.ssh
        target: /root/.ssh
        read_only: true

and a dockerfile like this:

# Use Python 3.10 slim image as base
FROM python:3.10-slim


WORKDIR /app
RUN echo "$(ls -la /root/)" && echo "$(ls -la /root/.ssh/)"    


and the output of the ls commands is:

#6 [3/3] RUN echo "$(ls -la /root/)" && echo "$(ls -la /root/.ssh/)"
#6 0.254 total 20
#6 0.254 drwx------ 1 root root 4096 Feb  4 04:30 .
#6 0.254 drwxr-xr-x 1 root root 4096 Feb  5 10:21 ..
#6 0.254 -rw-r--r-- 1 root root  571 Apr 10  2021 .bashrc
#6 0.254 -rw-r--r-- 1 root root  161 Jul  9  2019 .profile
#6 0.254 -rw------- 1 root root    0 Feb  4 04:30 .python_history
#6 0.254 -rw-r--r-- 1 root root  169 Feb  4 04:26 .wget-hsts
#6 0.256 ls: cannot access '/root/.ssh/': No such file or directory
#6 0.256 
#6 DONE 0.3s

Shouldn't the /root have an .ssh folder as defined by the target of the bind mount?

Docker's bind mounts docs state as use case: "Sharing .. files from the host machine to containers."

It also states: "Bind mounts are also available for builds:" Consequently, I believe that I'm implementing it incorrectly.

Bind mounts are appropriate for the following types of use case:

Sharing source code or build artifacts between a development environment on the Docker host and a container.

When you want to create or generate files in a container and persist the files onto the host's filesystem.

Sharing configuration files from the host machine to containers. This is how Docker provides DNS resolution to containers by default, by mounting /etc/resolv.conf from the host machine into each container.

Bind mounts are also available for builds: you can bind mount source code from the host into the build container to test, lint, or compile a project.

Following the answer by boyvinall in this question doesn't work. My question is why doesn't it work.

What am I missing here?

I'm using:

docker-buildx-plugin (0.20.0-1~ubuntu.22.04~jammy) containerd.io (1.7.25-1) docker-ce-cli (5:27.5.1-1~ubuntu.22.04~jammy) docker-ce (5:27.5.1-1~ubuntu.22.04~jammy)

This ended up working:

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    image: test-api-local
    environment:
      STORAGE_TYPE: local
      DATA_DIR: /data
      CACHE_DIR: /cache
      DEBUG: "true"
    ports:
      - "8000:8000"
    volumes:
      - type: bind
        source: ${SSH_AUTH_SOCK}
        target: /ssh-agent

with this command:

DOCKER_BUILDKIT=1 docker build \
  --ssh default \
  -f Dockerfile.local \
  -t test-api-local .

This command also works:

docker compose -f docker-compose.local.yml --ssh default

Which indicates to me that the issue is likely due to:

  1. the differences between docker-compose and docker build or docker compose, as previously I was using docker-compose and none of the configurations work with docker-compose
  2. mounting the ssh-agent vs mounting the ssh keys and then trying to start the agent and add keys within the build.

I've defined a docker-compose.yml like this:

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    image: test-api-local
    environment:
      STORAGE_TYPE: local
      DATA_DIR: /data
      CACHE_DIR: /cache
      DEBUG: "true"
    ports:
      - "8000:8000"
    volumes:
      - type: bind
        source: /home/user/.ssh
        target: /root/.ssh
        read_only: true

and a dockerfile like this:

# Use Python 3.10 slim image as base
FROM python:3.10-slim


WORKDIR /app
RUN echo "$(ls -la /root/)" && echo "$(ls -la /root/.ssh/)"    


and the output of the ls commands is:

#6 [3/3] RUN echo "$(ls -la /root/)" && echo "$(ls -la /root/.ssh/)"
#6 0.254 total 20
#6 0.254 drwx------ 1 root root 4096 Feb  4 04:30 .
#6 0.254 drwxr-xr-x 1 root root 4096 Feb  5 10:21 ..
#6 0.254 -rw-r--r-- 1 root root  571 Apr 10  2021 .bashrc
#6 0.254 -rw-r--r-- 1 root root  161 Jul  9  2019 .profile
#6 0.254 -rw------- 1 root root    0 Feb  4 04:30 .python_history
#6 0.254 -rw-r--r-- 1 root root  169 Feb  4 04:26 .wget-hsts
#6 0.256 ls: cannot access '/root/.ssh/': No such file or directory
#6 0.256 
#6 DONE 0.3s

Shouldn't the /root have an .ssh folder as defined by the target of the bind mount?

Docker's bind mounts docs state as use case: "Sharing .. files from the host machine to containers."

It also states: "Bind mounts are also available for builds:" Consequently, I believe that I'm implementing it incorrectly.

Bind mounts are appropriate for the following types of use case:

Sharing source code or build artifacts between a development environment on the Docker host and a container.

When you want to create or generate files in a container and persist the files onto the host's filesystem.

Sharing configuration files from the host machine to containers. This is how Docker provides DNS resolution to containers by default, by mounting /etc/resolv.conf from the host machine into each container.

Bind mounts are also available for builds: you can bind mount source code from the host into the build container to test, lint, or compile a project.

Following the answer by boyvinall in this question doesn't work. My question is why doesn't it work.

What am I missing here?

I'm using:

docker-buildx-plugin (0.20.0-1~ubuntu.22.04~jammy) containerd.io (1.7.25-1) docker-ce-cli (5:27.5.1-1~ubuntu.22.04~jammy) docker-ce (5:27.5.1-1~ubuntu.22.04~jammy)

This ended up working:

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    image: test-api-local
    environment:
      STORAGE_TYPE: local
      DATA_DIR: /data
      CACHE_DIR: /cache
      DEBUG: "true"
    ports:
      - "8000:8000"
    volumes:
      - type: bind
        source: ${SSH_AUTH_SOCK}
        target: /ssh-agent

with this command:

DOCKER_BUILDKIT=1 docker build \
  --ssh default \
  -f Dockerfile.local \
  -t test-api-local .

This command also works:

docker compose -f docker-compose.local.yml --ssh default

Which indicates to me that the issue is likely due to:

  1. the differences between docker-compose and docker build or docker compose, as previously I was using docker-compose and none of the configurations work with docker-compose
  2. mounting the ssh-agent vs mounting the ssh keys and then trying to start the agent and add keys within the build.
Share Improve this question edited Feb 6 at 9:18 Jed asked Feb 5 at 10:27 JedJed 6781 gold badge8 silver badges18 bronze badges 7
  • This question is similar to: Add bind mount to Dockerfile just like volume. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – AymDev Commented Feb 5 at 10:38
  • TL;DR: bind mount are not designed to be used during image build but dockerfile frontend allow you to perform a RUN --mount=type=bind (but not from the host machine, only from the build context at best) – AymDev Commented Feb 5 at 10:41
  • (OT: echo "$(command)" is just a cumbersome way of writing command.) – Biffen Commented Feb 5 at 10:45
  • @AymDev thanks. perhaps this is the source of my confusion. I'm trying to provide access to host files during the image build. Docker's bind mounts docs state as use case: "Sharing .. files from the host machine to containers." and "Bind mounts are also available for builds:" Consequently, I believe that I'm implementing it incorrectly. – Jed Commented Feb 5 at 10:58
  • 1 Looking at what specifically you're trying to mount, does SSH agent forwarding during docker build answer your real question? (RUN --mount=type=ssh specifically to forward ssh credentials.) – David Maze Commented Feb 5 at 11:23
 |  Show 2 more comments

1 Answer 1

Reset to default 1

The docker-compose.yml defines the services, i.e., one or multiple containers for your project. For the images used to start these containers you can define how to build them with the build property of the services.

But this also means that the volumes of a service are defined only in regards to the running containers and have no effect on the build of them. Building the images and running the containers are distinctly different things. That's why your previous attempts to bind-mount something into the build process didn't work.

Though you can bind-mount directories into the build process with RUN --mount=type=bind this is limited to directories from other images/build stages or the build context. So you can't use this to bind-mount arbitrary directories from the host.

But since what you're actually trying to is to make your ssh credentials available you should be using RUN --mount=type=ssh in your Dockerfile:

FROM python:3.10-slim

RUN --mount=type=ssh ssh ...

To make the ssh-agent socket available during build start it with the --ssh flag:

docker compose build --ssh default

or add the ssh build property to your docker-compose.yml:

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      ssh: ["default"]
发布评论

评论列表(0)

  1. 暂无评论