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:
docker-compose
and docker build
or docker compose
, as previously I was using docker-compose and none of the configurations work with docker-composeThe 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"]