Closed ganzevoort closed 9 months ago
I could make a pullrequest like this, but maybe you have ideas about a more generic solution.
diff --git a/entrypoint.sh b/entrypoint.sh
index ea350a9..daa0c97 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -28,6 +28,15 @@ TM_UID="${TM_UID:-${PUID}}"
TM_GID="${TM_GID:-${PGID:-${TM_UID}}}"
+if [ -n "${TM_LOSTANDFOUND:-}" -a ! -d "/opt/${TM_USERNAME}/lost+found" ]
+then
+ echo "ERROR: /opt/${TM_USERNAME} is not a mounted filesystem"
+ echo "INFO: container probably started too soon, retry in 1 minute"
+ sleep 60
+ exit 1
+fi
+
+
# common functions
password_var_or_file() {
# check PASSWORD and PASSWORD_FILE are both not set
Your best bet is to use a feature that not as many people are aware of in Docker: use --mount
syntax instead of -v
for volumes which when using Docker Compose, is called the Long Syntax. The difference between volume and mount is that volume will create the parent directory/directories if they do not exist. Mount or Long Syntax will have the container fail to start with an error if the path does not exist.
Taking their example and minimizing it:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
- type: bind
source: ./static
target: /opt/app/static
volumes:
mydata:
When you try to start the container, it fails:
$ docker compose up
[+] Building 0.0s (0/0) docker:desktop-linux
[+] Running 1/0
✔ Network long_default Created 0.0s
⠋ Container long-web-1 Creating 0.0s
Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /host_mnt/Users/mbentley/temp/long/static
That will happen on both at create time and then just when the container is started, like after a reboot. Here I created the container successfully with the directory existing, stopped the container, removed the directory, and then tried to start the container manually:
$ docker start long-web-1
Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /host_mnt/Users/mbentley/temp/long/static
Error: failed to start containers: long-web-1
Thanks for your suggestion.
I think I'll have to move the content from the root of the backup filesystem to a subdirectory and bind that (using long syntax) instead because the directory I'm binding now exists, it's intended to be the mountpoint for the real backup filesystem.
It feels like a more robust "fail if backupspace is not (yet) available" solution 👍 I'll try and see what it does.
With the missing directory, the container just fails to start without retrying (I have restart: unless-stopped) so this means I'll have to manually start the timemachine container after the filesystem is mounted.
For now I'll stick with the entrypoint0 workaround.
Closing for now unless someone has a better workaround.
What problem are you looking to solve?
On my server, the timemachine docker container starts too soon, before the filesystem that I want to bind to /opt/timemachine is available.
That filesystem is ext4, on an external disk over iscsi through a wireguard vpn. Starting the vpn and iscsi systems takes some time but when that's done the performance is ok.
Because docker starts too soon, /opt/timemachine is actually bound to the directory under the mountpoint and the backups of our laptops fill the (small) root filesystem of my raspberry pi.
Describe the solution that you have in mind
At startup, verify that /opt/timemachine/lost+found is a directory. If not, wait a minute then fail.
If the container starts before the mount completes, it will never see the mounted filesystem and instead continue to use the directory under the mountpoint. That's why at startup it cannot loop until mounted, but must "exit 1" and get auto-restarted.
My solution assumes that /opt/timemachine should be a mounted ext4 filesystem. Of course this isn't true for everybody. I think an additional environment variable should be used to enable the behaviour I'd like to see.
Additional Context
The relevant part from my
docker-compose.yml
:To add wait-until-mounted, I added an
entrypoint0.sh
with: