Unable to upload a "banner" image for my group using my docker instance

It seems I can upload the banner itself fine, but once I tap on « Update Group », I get the following error:

Error: Network error: JSON Parse error: Unrecognized token '<'

e@https://mydomain/js/chunk-vendors.30484898.js:11:236135
error@https://mydomain/js/chunk-vendors.30484898.js:11:254323
w@https://mydomain/js/chunk-vendors.30484898.js:31:12584
O@https://mydomain/js/chunk-vendors.30484898.js:31:12900
value@https://mydomain/js/chunk-vendors.30484898.js:31:13517
forEach@[native code]
error@https://mydomain/js/chunk-vendors.30484898.js:11:251150
w@https://mydomain/js/chunk-vendors.30484898.js:31:12584
O@https://mydomain/js/chunk-vendors.30484898.js:31:12900
value@https://mydomain/js/chunk-vendors.30484898.js:31:13517
error@https://mydomain/js/chunk-vendors.30484898.js:36:103118
w@https://mydomain/js/chunk-vendors.30484898.js:31:12584
O@https://mydomain/js/chunk-vendors.30484898.js:31:12900
value@https://mydomain/js/chunk-vendors.30484898.js:31:13517
https://mydomain/js/chunk-vendors.30484898.js:11:98255
promiseReactionJob@[native code]

Digging in, it appears that web sockets might have bene the problem, however my nginx configuration on the host has this set for the « location »:
location / {
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}

Surely that’s all that’s required there?

Looking at the docker instance’s logs using docker logs 8f1732da94a5

08:36:59.857 request_id=FmYFAVwjawJQrZwAAOuC [info] POST /api
08:36:59.868 request_id=FmYFAVwjawJQrZwAAOuC [info] Sent 500 in 10ms
08:36:59.868 [error] #PID<0.23940.1> running Mobilizon.Web.Endpoint (connection #PID<0.23939.1>, stream id 1) terminated
Server: localhost:4000 (http)
Request: POST /api
** (exit) an exception was raised:
    ** (File.CopyError) could not copy from "/tmp/plug-1613/multipart-1613983019-298018007156562-1" to "/app/uploads/1dea9e99302516a338d4c0b1b8b33cfc1c9072a4c4e2594aae8615045e8cf3ab.jpg": permission denied
        (elixir 1.11.3) lib/file.ex:817: File.cp!/3
        (mobilizon 1.0.6) lib/web/upload/uploader/uploader.ex:48: Mobilizon.Web.Upload.Uploader.put_file/2
        (mobilizon 1.0.6) lib/web/upload/upload.ex:74: Mobilizon.Web.Upload.store/2
        (mobilizon 1.0.6) lib/graphql/resolvers/group.ex:103: anonymous fn/2 in Mobilizon.GraphQL.Resolvers.Group.save_attached_pictures/1
        (elixir 1.11.3) lib/enum.ex:2193: Enum."-reduce/3-lists^foldl/2-0-"/3
        (mobilizon 1.0.6) lib/graphql/resolvers/group.ex:158: Mobilizon.GraphQL.Resolvers.Group.update_group/3
        (absinthe 1.6.1) lib/absinthe/resolution.ex:209: Absinthe.Resolution.call/2
        (absinthe 1.6.1) lib/absinthe/phase/document/execution/resolution.ex:230: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1

I have tried with both Safari and Google Chrome.

As a hunch, I checked out the permissions of /app/uploads within the docker instance, and also /tmp/plug-1613

The /tmp/plug-1613 seems to be owned by « nobody.nobody », as follows:
drwxr-xr-x 2 nobody nobody 4.0K Feb 22 08:48 plug-1613

But I suspect the issue is actually /app/uploads, which are as follows:
drwxr-xr-x 2 root root 4.0K Feb 22 08:48 uploads

I’ve since opened this up making it world-writable, which « fixes » the problem so this was the problem! However I am not sure if this is the correct, secure default. Who should the owner be and what should the permissions be?