Skip to content

Fluree docker container startup fails, possible incorrect bind mount and container permissions #127

@schivmeister

Description

@schivmeister

Running the official command on a recent Linux system (be it Windows 11 WSL2 or native Ubuntu 24.04):

$ docker run -p 58090:8090 -v `pwd`/data:/opt/fluree-server/data fluree/server

Does not allow a connection to be made from for e.g. a NodeJS client:

FetchError: request to http://localhost:58090/fluree/create failed, reason: socket hang up
    at ClientRequest.<anonymous> (/home/schiv/data-centric-app-demo/client/node_modules/cross-fetch/node_modules/node-fetch/lib/index.js:1501:11)
    at ClientRequest.emit (node:events:507:28)
    at emitErrorEvent (node:_http_client:103:11)
    at Socket.socketOnEnd (node:_http_client:530:5)
    at Socket.emit (node:events:519:35)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
  type: 'system',
  errno: 'ECONNRESET',
  code: 'ECONNRESET'
}

Node.js v23.1.0

If making a cURL request like:

curl --location 'http://localhost:58090/fluree/create' \
--header 'Content-Type: application/json' \
--data '{
  "ledger": "cryptids",
  "insert": {
    "@id": "my-first-cryptid",
    "name": "Freddy the Yeti"
  }
}'

It will simply return an empty result, after which the server/DB crashes. This is what has been reported so far by the community, see #85.

Upon investigating the docker log:

WARNING: abs already refers to: #'clojure.core/abs in namespace: mikera.vectorz.core, being replaced by: #'mikera.vectorz.core/abs
16:02:12.842 [main] INFO  fluree.server.main - Starting Fluree server with profile: :prod
16:03:47.187 [async-dispatch-7] INFO  fluree.db.api - Creating ledger "fluree-demo"
16:03:47.202 [async-thread-macro-1] ERROR fluree.db.util.filesystem - Unable to create storage directory: "/opt/fluree-server/data/fluree-demo/commit/17cc9fb58069825ab841aae71ea8476699352a60f40448418323e0f7a85c21af.json" .
java.io.FileNotFoundException: /opt/fluree-server/data/fluree-demo/commit/17cc9fb58069825ab841aae71ea8476699352a60f40448418323e0f7a85c21af.json (No such file or directory)
        at java.base/java.io.FileOutputStream.open0(Native Method)
        at java.base/java.io.FileOutputStream.open(Unknown Source)
        at java.base/java.io.FileOutputStream.<init>(Unknown Source)
        at clojure.java.io$fn__11619.invokeStatic(io.clj:230)
        at clojure.java.io$fn__11619.invoke(io.clj:230)
        at clojure.java.io$fn__11543$G__11525__11550.invoke(io.clj:69)
        at clojure.java.io$output_stream.invokeStatic(io.clj:153)
        at clojure.java.io$output_stream.doInvoke(io.clj:138)
        at clojure.lang.RestFn.invoke(RestFn.java:410)
        at fluree.db.util.filesystem$write_file$fn__47041$fn__47042.invoke(filesystem.cljc:23)
        at fluree.db.util.filesystem$write_file$fn__47041.invoke(filesystem.cljc:21)
        at clojure.core.async$thread_call$fn__6200.invoke(async.clj:486)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
16:03:47.203 [async-thread-macro-1] ERROR fluree.db.util.filesystem - "Fatal Error, shutting down!"

It appears it is a permissions issue inside the container, leaving a critical file uncreated, which borks the DB as there is no graceful exit:

15:57:02.509 [async-thread-macro-1] ERROR fluree.db.util.filesystem - Unable to create storage directory: "/opt/fluree-server/data/fluree-demo/767/commit/17cc9fb58069825ab841aae71ea8476699352a60f40448418323e0f7a85c21af.json" .
java.io.FileNotFoundException: /opt/fluree-server/data/fluree-demo/767/commit/17cc9fb58069825ab841aae71ea8476699352a60f40448418323e0f7a85c21af.json (No such file or directory)

The given bind mount host folder appears to be owned by root:

drwxr-xr-x 2 root  root  4.0K Mar 21 22:02 data

However, running as root (sudo) has no effect on this. What does appear to have an effect, is creating a permissive folder ahead of time. For e.g.:

$ rm -rfvi data/ && mkdir data && chmod 777 data

OR, creating a native docker volume, by not passing a path for -v but just a name, for e.g. -v data (be careful that this then becomes a volume managed by Docker and won't be on your file system).

This allows the client to connect and make transactions. Files in this folder appear to have strange ownership:

$ ls data/ -lh
total 8.0K
drwxr-xr-x 4 10001 10001 4.0K Mar 21 22:06 fluree-demo
-rw-r--r-- 1 10001 10001 1.5K Mar 21 22:06 fluree-demo.json

They are owned by a UID and GID that do not exist in the host system, and are preconfigured in the image via ARG. The host user will not be able to delete these files, or change the ownership of the folder to 10001:10001, without root privileges.

I am not sure how the official instructions work for anybody, as this is a very delicate nuance which not everyone will be able to figure out, and running the docker command (as given by the docs) as root does not solve the problem.

It would be nice to have this UID/GUID matter resolved in the Fluree Docker configuration itself, or to have some official instructions on how to deal with this, if it is just a general Docker permissions issue resolvable by some user configuration on the host.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions