"invalid volume specification" when passing environment variables - docker

Host: Centos 7
Docker version: 19.03.12, build 48a66213fe
Docker compose version: version 1.26.2, build eefe0d31
I am using the advice given here on specifying environment variables in the shell and then passing those into the compose file. So my docker-compose file looks like this:
version: '3.8'
services:
springboot:
image: <my image>
ports:
- "8445:8445"
depends_on:
- "database"
environment:
- SPRING_PROFILES_ACTIVE=dev
database:
image: "mongo"
Here's the error that I've run into:
ERROR: for 39b165c237b9_deploy_springboot_1 Cannot create container for service springboot: invalid volume specification: 'a9d7debde5ffcba2a023c12d5f1e822567e9b4047a1bda76efeefbfc80c1f622:app/data:rw': invalid mount config for type "volume": invalid mount path: 'app/data' mount path must be absolute
The corresponding Docker file does have a reference to VOLUME app/data, however that doesn't seem controversial.
If I take out the environment block, it seems to work fine (though the application starts without having the right config, but at least it doesn't error).
So what is the right way to pass on shell environment variables to the container?
EDIT
Thanks to #David Maze, it was indeed the VOLUME declaration in the original Docker file - nothing to do with docker-compose. Deleted it and it now works. Thanks!

there are 2 ways to specify directories in docker.
absolute path i.e. from the root e.g. /var/lib
relative path i.e. relative to the compose file e.g. ./app/data

Try replacing SPRING_PROFILES_ACTIVE=devby SPRING_PROFILES_ACTIVE: dev Instead, so replace = with : . And you should also add the volume to the docker-compose file:
version: "3.8"
services:
.
.
volumes:
- Path/to/your/volume
environment:
ENV_VAR1: Value1
ENV_VAR2: Value2
.
.
.
And according the error message, the path must be absolute.

Related

How to parameterize ports for docker-compose?

I am trying to parameterize a docker-compose file using .env. Doc
docker-compose.yml
version: '2.3'
networks:
default: { external: true, name: $NETWORK_NAME }
services:
rabbitmq_local:
image: 'rabbitmq:3.6-management-alpine'
ports:
# The standard AMQP protocol port
- ${RABBIT_PORT}:5672
# HTTP management UI
- '15672:15672'
.env file
NETWORK_NAME=uv_atp_network
RABBIT_PORT=5672
RABBIT_HTTP_MANAGEMENT_PORT=15672
Parameterizing NETWORK_NAME works, but parameterizing RABBIT_PORT doesn't, with
The Compose file 'docker-compose.yml' is invalid because:
services.rabbitmq_local.ports contains an invalid type, it should be a number, or an object
This makes me suspect RABBIT_PORT is interpreted as string rather than a number.
How can I parameterize it correctly?
EDIT
I found that forcing the variable to be mandatory
- ${RABBIT_PORT:?unspecified_rabbit_port}:5672
gives the error, meaning it is unset or empty.
What am I doing wrong?
It seems that when running with pytest and pytest-docker-compose the .env file has to be in the root folder of pytest, along with the pytest.ini file.
Running from docker-compose from command-line doesn't have that limitation in docker 1.24.
After relocating the file, the variables could be resolved.

Derby and WSL2: '.': invalid mount config for type "volume": invalid mount path: 'webappsDB' mount path must be absolute

I'm trying to create a simple volume in WSL2 (Ubuntu) for my local DB created in Derby. I have tried these two pieces of code (and similars) and none of them is working:
Option 1:
Dockerfile:
RUN mkdir -p webappsDB/MY_LOCAL_DB
VOLUME /mnt/c/Users/MY_USER/MY_APP/webappsDB/MY_LOCAL_DB:/usr/local/tomcat/webappsDB/MY_LOCAL_DB
Option 2:
docker-compose.yaml:
version: '3.4'
services:
app:
image: fanmixco/MY_APP:v1.0.0
volumes:
- /mnt/c/Users/MY_USER/MY_APP/webappsDB/MY_LOCAL_DB:/usr/local/tomcat/webappsDB/MY_LOCAL_DB
I'm constantly getting this error:
ERROR: for app Cannot create container for service app: invalid
volume specification: '...:webappsDB:rw': invalid mount config for
type "volume": invalid mount path: 'webappsDB' mount path must be
absolute
I also tried to add:
environment:
- COMPOSE_CONVERT_WINDOWS_PATHS=1
And didn't work. Any idea what I'm doing wrong? Thanks.
Enable path conversion from Windows-style to Unix-style in volume definitions
create a new Windows environment variable with the name COMPOSE_CONVERT_WINDOWS_PATHS and set it to 1
or
create a .env file in the docker-compose.yml file path and add the following
COMPOSE_CONVERT_WINDOWS_PATHS=1

How to copy files inside container with docker-compose

I have a simple image that runs a jar file. That jar file inside the image needs a special configuration file in order to run.
In the location with the docker-compose.yml I have a folder named "carrier" and under this folder I have that file.
The docker-compose.yml:
version: "3.3"
services:
web:
image: "myimage:1.80.0.0"
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
When I hit docker-compose up it complains that the file is not there, so it doesn't copy it.
If I do another option like I did in the .sh command, something like this:
volumes:
- ./carrier:/var/local/Config/:shared
It complains about another error:
C:\Tasks\2246>docker-compose up
Removing 2246_web_1
Recreating 1fbf5d2bcea4_2246_web_1 ... error
ERROR: for 1fbf5d2bcea4_2246_web_1 Cannot start service web: path /host_mnt/c/Tasks/2246/carrier is mounted on / but it is not a shared mount
Can someone please help me?
Copy the files using Dockerfile, use below;
FROM myimage:1.80.0.0
RUN mkdir -p /var/local/Config/
COPY carrier /var/local/Config/
EXPOSE 61003
docker-compose.yml
version: "3.3"
services:
web:
build:
dockerfile: Dockerfile
context: '.'
ports:
- "61003:61003"
In the end, run below command to build new image and start container
docker-compose up -d --build
You can use Dockerfile if it does not copy.
Dockerfile;
FROM image
COPY files /var/local/Config/
EXPOSE 61003
Docker-compose;
version: "3.3"
services:
web:
build: . (path contains Dockerfile)
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
Remove the last /
volumes:
- ./carrier:/var/local/Config
I'm not sure but you can try to set full access permissions for all user to /carrier:
chmod -R 777 /carrier
Thanks all for all your answers.
Seems like finally docker warned me with some comparisons over the windows files vs Linux files when building the image. (Not with docker compose but with Dockerfile).
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Tried it on linux and works.

Why in docker-compose I should write full path to volume?

I have some confusing moments with docker-compose volumes (In docker windows server (container)).
I wrote the next configuration
volumes:
- "C:/ProgramData/Docker/volumes/admin-stat-logs:C:/app/Logs"
and why it so necessary to write the full path to the volume?
if I write:
volumes:
- "admin-logs:C:/app/Logs"
it generates the error
ERROR: Named volume "admin-logs:C:/app/Logs:rw" is used in service "admin-stat-table" but no declaration was found in the volumes section.
why does it happen?
UPDATE
let me show what I mean(I made wrong explonation). In an image, we have a short announcement from the official documentation.
I write the same in my case:
volumes:
- admin-logs:C:/app/Logs
I create volume before by the terminal. When I start docker-compose up I get the next error
ERROR: Named volume "admin-stat-logs:C:/app/Logs:rw" is used in service "admin-stat-table" but no declaration was found in the volumes section.
I made a mistake in the first case, it's a simple mount to a folder, sorry for my misunderstanding.
volumes:
- "C:/ProgramData/Docker/volumes/admin-stat-logs:C:/app/Logs"
You don't need to use a full path. You can use a relative path to the location of your docker-compose.yml file.
When you write admin-logs:C:/app/Logs, you're telling docker-compose to use a volume named admin-logs. If you want to use a folder where you docker-compose is located, you can write ./admin-logs:C:/app/Logs.
If you plan to use a separated docker volume, you need to first define it in the docker-compose.yml. Here's an example covering both cases:
version: '3'
services:
mytest:
image: ubuntu:18.04
volumes:
- "mymnt:/mnt/volume"
- "./mymnt_on_host:/mnt/mounted_folder"
volumes:
mymnt:
You'll need a mymnt_on_host directory in the folder where the docker-compose.yml is located.
For more info about this topic, you can check the reference guide for the docker-compose.yml
UPDATE:
If you plan to use an already created volume in your docker-compose, you can use external: true in the volumes definition.
e.g.
version: '3'
services:
mytest:
image: ubuntu:18.04
volumes:
- "mymnt:/mnt/volume"
- "./mymnt_on_host:/mnt/mounted_folder"
volumes:
mymnt:
my_existing_volume:
external: true
Now if you start this, docker-compose won't try to generate my_existing_volume but it'll expect to find it already on the machine.
For more info check external reference.
Can you show your version value in the docker-compose.yml file. It should be version: '3' or version: '3.5'. Probably you have version: '2'

env_file is ignored in docker-compose and cause "The ... variable is not set" warning

I simply want to use a environment variable loaded from file in my docker-compose file. But after running the container, I only got
WARNING: The TESTVAR variable is not set. Defaulting to a blank string.
Only found this topic, but I'm using a later version of docker like there (docker-compose: 1.14.0, docker: 17.05.0-ce). And I changed the encoding to ISO 8859-1, since I found a github issue where strange behavior with encodings was detected. Both doesn't work.
My docker-compose file
version: '2'
services:
mysql:
container_name: test_${TESTVAR}
build: mysql
mem_limit: 1G
env_file:
- credentials.env
credentials.env contains only TESTVAR=test123. To start, I run docker-compose up mysql and I also tried to specify the environment variables directly in the compose file like this:
environment:
- TESTVAR=1234
Not working, too.
If you want to use variables in the docker-compose.yml you can do it with .env file, docker docs
$ cat .env
TAG=v1.5
TESTVAR=123
$ cat docker-compose.yml
version: '3'
services:
web:
image: "webapp:${TAG}"
environment: ["TESTVAR=${TESTVAR}"]

Resources