Description
Description
We have a customer setup where a volume is bind mounted into a container and the container populates it with some files on first start.
Later another volume was added which is a subdirectory inside the first volume. This subdirectory gets created by the file population of the container at first start.
Now I'm aware this is not a really self consistent concept and therefore might be bad practice, however the problem is that is sometimes fails and sometime succeeds which is worse then just getting a error.
Steps To Reproduce
I tried to stay a close to the original setup as possible while removing everything which is not necessary. This is what I came up with to reproduce:
# parameters
NO_VARS=255
NO_RUNS=99
NO_INC_SIZE=3
TEST_PATH=/tmp
cd $TEST_PATH
cat << EOF > Dockerfile
FROM debian:latest
# create dirs to populate
RUN mkdir -p /foo/bar /foo/baz
RUN touch /foo/bar/iamhere
# create a larger container size
RUN for i in \$(seq 1 $NO_INC_SIZE); do \
cp -rv /usr /foo/baz/$i/ >/dev/null 2>&1; \
done
CMD sleep .1
EOF
cat << EOF > docker-compose.yml
services:
test:
container_name: test
image: race:condition
network_mode: "host"
volumes:
- type: volume
source: parent
target: /foo
- type: volume
source: subdir
target: /foo/bar
read_only: true
volumes:
parent:
driver: local
driver_opts:
type: none
device: \${TEST_PATH}/parent
o: bind
subdir:
driver: local
driver_opts:
type: none
device: \${TEST_PATH}/parent/bar
o: bind,ro
EOF
# build container
docker build -t race:condition .
# create a larger env file
rm -f .env
for i in $(seq 0 $NO_VARS); do
echo "VAR$i=$i" >> .env
done
echo "TEST_PATH=$TEST_PATH" >> .env
# loop to reproduce
rm -f debug.log
for no in $(seq 0 $NO_RUNS); do
# prepare clean state
docker compose down >/dev/null 2>&1
mkdir -p parent >/dev/null 2>&1
rm -rf parent/* >/dev/null 2>&1
docker volume rm -f tmp_parent tmp_subdir >/dev/null 2>&1
# test & report
docker compose up test >> debug.log 2>&1 && echo "$no: success" || echo "$no: failed"
done
Since this is a race condition it might behave differently on other systems depending on CPU,IO,etc.
You can play around with the parameters in search for the "sweet spot". I did not find any config that always fails, but some that are more likely to succeed more often %)
Compose Version
Docker Compose version v2.25.0
Used on RHLE 9.3
Installed Packages
Name : docker-compose-plugin
Version : 2.25.0
Release : 1.el9
Architecture : x86_64
Size : 59 M
Source : docker-compose-plugin-2.25.0-1.el9.src.rpm
Repository : @System
From repo : Default_Organization_docker-ce-stable_docker-ce-stable_el9_x86_64
Summary : Docker Compose (V2) plugin for the Docker CLI
URL : https://github.com/docker/compose/
License : ASL 2.0
Description : Docker Compose (V2) plugin for the Docker CLI.
:
: This plugin provides the 'docker compose' subcommand.
:
: The binary can also be run standalone as a direct replacement for
: Docker Compose V1 ('docker-compose').
Docker Environment
Client: Docker Engine - Community
Version: 26.0.0
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.13.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.25.0
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 2
Server Version: 26.0.0
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 5.14.0-284.11.1.el9_2.x86_64
Operating System: Red Hat Enterprise Linux 9.3 (Plow)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.736GiB
Name: dstorweb01tl.unicph.domain
ID: dfe1b231-0a99-45e5-8c16-93edec96d0b2
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Anything else?
I'm posting this here because I'm not able to reproduce this with Docker alone. Eg.
mkdir -p state; rm -rf state/* state/.*; docker run --rm -ti -v ./state/log:/var/log -v state:/var debian bash