define inline file in docker-compose - docker

I'm currently using a bind mount to mount a file from the host to a container:
volumes:
- type: bind
source: ./localstack_setup.sh
target: /docker-entrypoint-initaws.d/init.sh
Is there a way to define the ./localstack_setup.sh inline in the docker-compose.yml? I want to use a remote Docker host, and docker-compose up fails because the remote host doesn't have the file.

I don't know about any opinion to run a script into docker-compose itself. I recommend you to parametrize your shell script with ENVRIOMENT variable replacers to be in general in terms of the native docker image.

Related

Docker Compose - bind source path does not exist

In my docker compose service I have the following:
volumes:
- ~/DockerStuff/Projects:/root/Documents/Projects
- ~/DockerStuff/Downloads:/root/Downloads
But when I run docker compose up I'm being told:
Error response from daemon: invalid mount config for type "bind": bind source path does not exist
I keep seeing things saying that you can create bind volumes and if the host directory doesn't exist, Docker shall create it on the fly. But these seem specific to DockerFile setups rather than compose files.
Is such functionality possible in docker compose too? :)
The ~ symbols is not expanded by docker compose.
You have to rely on this approach:
building script
HOME=${HOME} docker-compose ... command options ...
docker compose yaml
volumes:
- ${HOME}/DockerStuff/Projects:/root/Documents/Projects
- ${HOME}/DockerStuff/Downloads:/root/Downloads
In order to create the host folder for the docker-compose volume binding if it doesn't exist just add bind.create_host_path to your volumes section -
volumes:
- type: bind
source: localFolder/subFolderIfNeeded
target: /data
bind:
create_host_path: true
NOTE: Tested on Docker compose 2.15.1

How to write a script which can run the creation of Docker volumes in one command

In my Docker environment I have always to run the command to create volumes manually like
docker volume create --name= ...
I would like a way to speed up this process with a script shell which could help me to run at once.
If I could see a possible solution would be great as I have many volumes to create manually
A possible solution would be to use docker-compose and have a docker_compose.yml file composed only of volumes but no services:
version: "3.8"
volumes:
logvolume01: {}
logvolume02: {}
logvolume03: {}
When run, this creates the volumes accordingly:
$ docker-compose up
Creating volume "docker_logvolume01" with default driver
Creating volume "docker_logvolume02" with default driver
Creating volume "docker_logvolume03" with default driver
Attaching to
$ docker volume ls
DRIVER VOLUME NAME
local docker_logvolume01
local docker_logvolume02
local docker_logvolume03
If you need a more complex set of options while creating your volumes, you can find them in the documentation.
Just a little quirk to note here: per default, when you are using docker-compose, the volumes will be prefixed with the name of the folder you are in, this is done by Docker so there is no collision between different Docker projects.
This is the reason why, in the example above, the volumes are starting with docker_, because the folder I am in, is called docker.
To fix this, just give a name to your volumes:
version: "3.8"
volumes:
logvolume01:
name: logvolume01
logvolume02:
name: logvolume02
logvolume03:
name: logvolume03
Running this modified version gives:
$ docker-compose up
Creating volume "logvolume01" with default driver
Creating volume "logvolume02" with default driver
Creating volume "logvolume03" with default driver
Attaching to
$ docker volume ls
DRIVER VOLUME NAME
local logvolume01
local logvolume02
local logvolume03

Docker-compose and volumes

When I create a volume manually and include it in docker-compose, if I don't prefix the volume tag with docker_, docker compose creates a new volume prefixed with docker_
For example:
I create a volume with:
docker volume create myvolume
It's visible at /var/lib/docker/volumes/myvolume.
I include it in my docker-compose yaml file, but when I run docker-compose, a new volume is created at /var/lib/docker/volumes/docker_myvolume
If I call my volume docker_myvolume and include that in my docker-compose yaml, it uses it and doesn't create it's own.
Is this normal behavior?
Yes, this is normal behavior. When you specify a volume in your docker-compose.yml file without a leading driver_ prefix, Docker Compose will create a new volume with a name that is prefixed with driver_. This is because Docker Compose uses a default driver for creating and managing volumes, which is the local driver.
You can specify a volume in your docker-compose.yml file with the external option to tell Docker Compose to use an existing volume instead of creating a new one. For example:
version: '3'
services:
myservice:
volumes:
- type: volume
source: myvolume
target: /app/data
volume:
external: true
This will tell Docker Compose to use the existing volume myvolume instead of creating a new one.
Yes, Compose generally prefixes things with its project name. This includes containers, networks, and named volumes. In general, if you actually need to interact with these things, there is an equivalent docker-compose command that chooses the correct name (e.g., docker-compose exec).
In general you shouldn't be directly modifying things inside /var/lib/docker. That directory tree is Docker's private state and there are no particular guarantees about the format of files there. If your use case involves directly interacting with the volume files from the host, either use a /host/path:/container/path bind mount or explicitly specify the storage location using volume options.

How can Docker on Windows 10 access Network Drives?

I wrote some scripts I use in a docker container. For the scripts to be usefull I need to access some network mounts.
On my Mac it's easy. In my docker-compose.yml I have:
volumes:
- type: bind
source: /Volumes/Teams/myteam/folder/subfolder
target: /subfolder
On my colleagues Windows Laptop /Volumes/Teams is mounted as T: so my naive approach was to use
volumes:
- type: bind
source: /t/myteam/folder/subfolder
target: /subfolder
From the git shell this path can be used. But when starting docker-compose up from that shell, he gets error messages
ERROR: for 255d3d7d2944_my-tools_helpscripts_1 Cannot create container for service helpscripts: b'Mount denied:\nThe source path "T:/myteam/folder/subfolder"\ndoesn\'t exist and is not known to Docker'
Encountered errors while bringing up the project.
In docker's settings for shared drives, the T: drive is not listed.
How can we solve this issue?
I think I found a solution that should fit for me:
Start my container with capabilities SYS_ADMIN and DAC_READ_SEARCH
Mount inside the containter with
mount -t cifs -o user=USER,domain=DOMAIN //SERVER/Teams /mnt/T

Docker-Compose mount volume overwrites host files

I am mounting a directory from a CMS with content files inside a docker container.
The mounting works absolutely.
The CMS got some basic files, which are copied into the mounted folder in the container during build. Then it will be mounted to a directory on the host. Now the files from the Container are also on the host. I can change them and they will be kept in sync.
If i restart my container docker-compose stop && docker-compose up -d the files on the host will be overwritten by the default ones from the container build.
Is there a possibility to force the local state of the file to overwrite the file in the container?
Kind regards
maybe try configuring it as read only
docker run -v volume-name:/path/in/container:ro my/image
You can set it as read only as gCoh answer. See the following for docker-compose:
volumes:
- type: bind
source: ./host-source-folder
target: /container-folder
read_only: true

Resources