Invalid configuration: Failed to load config file
piplongrun opened this issue · 16 comments
I created a user/group with id 2999 on the host, then ran the Production-grade instruction command from the README.md. Docker shows the container has exited immediately:
pip@ubuntu18:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
354ec93509ed tomsquest/docker-radicale "docker-entrypoint.s…" 15 seconds ago Exited (1) 14 seconds ago radicale
Digging up the log file for the container shows me this error:
{"log":"ERROR: Invalid configuration: Failed to load config file '/config/config': No such file: '/config/config'\n","stream":"stderr","time":"2019-09-15T21:00:58.133814892Z"}
And indeed /config/config
isn't there. The folder for config and data have been created, but the config file is missing inside the config folder:
pip@ubuntu18:~$ ls -la ./radicale
total 16
drwxr-xr-x 4 root root 4096 Sep 18 16:12 ./
drwxr-xr-x 6 pip pip 4096 Sep 18 16:12 ../
drwxr-xr-x 2 root root 4096 Sep 18 16:12 config/
drwxr-xr-x 2 radicale radicale 4096 Sep 18 16:12 data/
This is on a fresh Ubuntu 18 install with Docker version 19.03.2, build 6a30dfc.
So I made these changes to get everything working out of the box: piplongrun/docker-radicale@f98424...595b21
(See also docker/docs#2979)
Hi,
Thanks for reporting this.
I am unable to reproduce given a valid /config
volume. (following the documentation at https://github.com/tomsquest/docker-radicale#custom-configuration)
For example, here is a custom config folder where the config
file has been copied. Before that I create the /opt/radicale/data
and /opt/radicale/config
folder.
$ tree /opt/radicale
/opt/radicale
├── config
│ └── config
└── data
Then the production command can be run successfully given the volume are adapted:
docker run -d --name radicale \
-p 127.0.0.1:5232:5232 \
--read-only \
--init \
--security-opt="no-new-privileges:true" \
--cap-drop ALL \
--cap-add CHOWN \
--cap-add SETUID \
--cap-add SETGID \
--cap-add KILL \
--pids-limit 50 \
--memory 256M \
--health-cmd="curl --fail http://localhost:5232 || exit 1" \
--health-interval=30s \
--health-retries=3 \
-v /opt/radicale/data:/data \
-v /opt/radicale/config:/config:ro \
tomsquest/docker-radicale
By the way, I saw your PR and having the config volume mounted readonly is a good think from a security point of view.
I am able to reproduce @piplongrun's problem using the docker-compose.yml provided. The strange thing is that this should not happen, right? Since the provided config file is copied into /config before /config is declared a volume, and according to the Dockerfile documentation:
The docker run command initializes the newly created volume with any data that exists at the specified location within the base image.
I am confused why the generated config volume is empty.
- are you able to reproduce without the capabilities (
--cap-drop
,--cap-add
)? - are you able to reproduce without the
volumes
? (and without the capabilities drop)
FYI, regarding capabilities, I had some strange permission issues (why I did no undestand, but seems that the root on the container was not able to touch the files owned by root on the host :/).
Just to dispell any misunderstanding: any volume mounted on a container will shadow the target directory.
ie. given container have a /container-folder
, when running -v /host-directory:/container-folder
then the container will only see the content of /host-directory
in its /container-folder
.
Hence, related to this issue, the container's /config
is replaced by the host config
volume, which means that the host must have a config
file in mounted config
directory.
Trying that now.
Without capabilities:
radicale:
image: tomsquest/docker-radicale:amd64
build:
context: https://github.com/tomsquest/docker-radicale.git
args:
- UID=1000
- GID=1000
restart: unless-stopped
healthcheck:
interval: 5m
read_only: true
security_opt:
- no-new-privileges:true
# cap_drop:
# - ALL
# cap_add:
# - SETUID
# - SETGID
# - CHOWN
# - KILL
init: true
volumes:
- ./testradicale/data:/data
- ./testradicale/config:/config:ro
- ./testradicale/htpasswd:/htpasswd:ro
jeslinmx@localhost:~/selfhosting$ ls testradicale
ls: cannot access 'testradicale': No such file or directory
jeslinmx@localhost:~/selfhosting$ dc up -d radicale
Starting selfhosting_radicale_1 ... done
jeslinmx@localhost:~/selfhosting$ docker logs -f 363b237445ba15733963890d254d9d1db59cdbc316bf2ab3b70543c450cbc610
ERROR: Invalid configuration: Failed to load config file '/config/config': No such file: '/config/config'
Without capabilities and volumes:
radicale:
image: tomsquest/docker-radicale:amd64
build:
context: https://github.com/tomsquest/docker-radicale.git
args:
- UID=1000
- GID=1000
restart: unless-stopped
healthcheck:
interval: 5m
read_only: true
security_opt:
- no-new-privileges:true
# cap_drop:
# - ALL
# cap_add:
# - SETUID
# - SETGID
# - CHOWN
# - KILL
init: true
# volumes:
# - ./testradicale/data:/data
# - ./testradicale/config:/config:ro
# - ./testradicale/htpasswd:/htpasswd:ro
everything runs fine.
Just to dispell any misunderstanding: any volume mounted on a container will shadow the target directory.
ie. given container have a
/container-folder
, when running-v /host-directory:/container-folder
then the container will only see the content of/host-directory
in its/container-folder
.Hence, related to this issue, the container's
/config
is replaced by the hostconfig
volume, which means that the host must have aconfig
file in mountedconfig
directory.
But this only applies if /host-directory
exists, right? Otherwise as per the documentation, docker should create /host-directory
and populate it with the contents of /container-folder
, and only then does /host-directory
shadow /container-folder
?
By the way, @tomsquest what is your docker -v
? I suspect this is being caused by a problem in docker not behaving according to documentation - I am having the same problem with the netdata image.
Hum, @jeslinmx , I did not know about Docker pulling data from the container when the host dir does not exist.
Here is my docker version:
$ docker -v
Docker version 19.03.2, build 6a30dfca03
Tested on Ubuntu LTS 18.04 and 19.04.
Hum, @jeslinmx , I did not know about Docker pulling data from the container when the host dir does not exist.
I was under the impression that that's what the line
39 COPY config /config/config
in the Dockerfile was supposed to achieve - copying a basic config into the volume so it would be dumped into a host directory upon mounting.
Here is my docker version:
$ docker -v Docker version 19.03.2, build 6a30dfca03
Tested on Ubuntu LTS 18.04 and 19.04.
Same as both @piplongrun and I. How strange.
COPY config /config/config
is in the Dockerfile, which means it is already done when docker run
is executed. docker run
will run the entrypoint script and the CMD
command (which could be override).
So without mounting volume, the /config/config
file exists.
Closing this issue as it seems that the missing config file is due to the behaviour of Docker when mounting a missing directory in the container.
Hi, I am running into this issue and it seems don't have an obvious solution. Can anyone shed some lights?
Startup command I use:
docker run -d --name radicale \
-p 127.0.0.1:5232:5232 \
-e UID=1000 \
-e GID=1000 \
--init \
--security-opt="no-new-privileges:true" \
--cap-drop ALL \
--cap-add CHOWN \
--cap-add SETUID \
--cap-add SETGID \
--cap-add KILL \
--pids-limit 50 \
--memory 256M \
--health-cmd="curl --fail http://localhost:5232 || exit 1" \
--health-interval=30s \
--health-retries=3 \
-v /opt/radicale/data:/data \
-v /opt/radicale/config:/config \
tomsquest/docker-radicale
@lifehome did you put the config file under your /opt/radicale/config, ie. the complete file path should be : /opt/radicale/config/config.
@tomsquest I have successfully started using my command above after copying and create the config file.
Tho is it possible to automate the creation of the config file?
In fact, you only need to mount the config volume if you changed something in the config.
Else -v /opt/radicale/config:/config \
is useless.
Indeed, the config file is IN the container, mounting a volume "on it", just replace/shadow the config directory, then radicale cannot find is config file.