Installation on Fedora 31?

Hi, I’m looking to install WebODM on Fedora 31, but running into some difficulty.
I have some moderate experience with linux, but have never used Docker before.

According to what I have found through google, Fedora 31 switched to CGroupsV2, which prevents the docker daemon from running. Currently I have found two suggested workarounds…

  1. Add boot options in grub
    As detailled in this reddit post https://www.reddit.com/r/linuxquestions/comments/dn2psl/upgraded_to_fedora_31_docker_will_not_work/f5sml7f?utm_source=share&utm_medium=web2x
    I’d rather not go down this route as it definitely seems like a workaround and not a solution, but willing to try if needed.

  2. Use podman instead of docker
    As detailled in some of the comments here https://www.reddit.com/r/docker/comments/d8ufgy/has_anyone_managed_to_run_docker_ce_on_fedora_31/?utm_source=share&utm_medium=web2x
    I tried installing podman and making an alias for docker, but still ran into issues when running ./webodm.sh because it couldn’t find a Docker install. It seems like many people are supporting the switch to podman on Fedora, and it “should” be completely compatible.

Could anyone tell me which would be the best supported method going forward, both for future versions of Fedora and WebODM?

I’d go option #1. Podman may well be a “drop-in” replacement, but WebODM uses docker-compose extensively, so you might have more quirks to fix along the way if you go that route.

1 Like

Thanks very much for the reply. I’ll give it a go and report back with my findings!

1 Like

Managed to get WebODM working by adding myself to the docker group and doing a restart (not just log in/out). It might be nice if we could update the readme with a note that F31 users will need to alter their grub options?

I’m not running into an issue with SELinux, where it is denying write access by gunicorn, as I have changed the ODM media directory to a folder in my home structure. I could temporarily disable SELinux, but some advice on the “proper” way of dealing with this would be great!

For sure. Would you be interested to make a pull request? https://github.com/OpenDroneMap/docs

Sure! I’ve never done one before but will look into it. I’ll also see if I can find out what the “correct” way of working with SELinux should be, so that can be documented too.

Hi,

I’m trying to run WebODM on Fedora and the official support on “docking” is with podman, so i think it’s better to use with it, and podman has some advantages like it doesn’t require any daemon to run. You’ll have to install some packages to get the compatibility with Docker :
sudo dnf install podman-docker
sudo dnf install podman-compose

After that, go on webodm directory and run :
podman build -t webodm .

This builds the container so, after, to run, use this command :
podman run -d -p 8000:8000 webodm

1 Like

Thanks for the info Mak! I will give it a try. Did you have to do anything extra like aliasing, or does podman-docker take care of that?
Also, did you have any issues with SELinux using this method, or is it all well managed?

Edit: got podman installed… Initially had an error which I solved by adding “thomas:110000:65536” to my /etc/subuid and /etc/subgid files (though honestly didn’t understand why I was doing this!!)

The build now starts, and successfully copies all of the blobs. I’m now just running into trouble with the run command, where the container immediately closes. Any help would be appreciated!

So by adding the ‘i’ flag to the run command, I can get the container to stay up and running. Unfortunately I am unable to connect to webodm through a browser, though podman shows that port 8000 should be forwarded to the host. Because of the differences with podman and docker I have no idea how to troubleshoot this! I’ll keep trying and report back if I find a solution, but would appreciate any input.

Another update if anyone is interested!
I went through webodm.sh and replaced all instances of docker-compose (command only, not file names) with podman-compose. (Thought I had done this right at the start but maybe not?)

By doing this the majority of the script seems to run! I get to a point where the db, broker, and WebODM_node-odm_1 containers are all started, but worker and webapp both fail to start.
The error I get for both of these is “executable file not found in $PATH”, which is reproducible when just running “podman start -a webapp”.

I feel like I’m really close to having this run, so any tips to fix this final hurdle would be great!

I’ve figured out it’s something to do with entrypoint in docker-compose.yml. If I shorten it only to /bin/bash, then it doesn’t error, though obviously doesn’t run the necessary commands…

Hi,

Sorry for the late answer, and congratulations for your success. I think it’s not simplest as replace all Docker’s occurences with podman. You have to take careful of paths. Podman manages containers, overlay a images differently as Docker. All containers are in your folder ~/.local/share/containers/storage/ path. Try to see in what it is in.

Is anyone able to help me out by providing me with the output of
docker inspect webapp or docker inspect worker
Specifically looking for the “Path:” definition, but the entire output would be fine.

docker inspect webapp

[
    {
        "Id": "29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d",
        "Created": "2019-12-28T15:02:00.452454451Z",
        "Path": "/bin/bash",
        "Args": [
            "-c",
            "chmod +x /webodm/*.sh && /bin/bash -c \"/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/start.sh --create-default-pnode --setup-devenv\""
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 137,
            "Error": "",
            "StartedAt": "2019-12-28T15:02:04.08628328Z",
            "FinishedAt": "2019-12-28T15:10:20.00714159Z"
        },
        "Image": "sha256:65a047b8675ed70a83c748da17d94007a1f25d91fed5fcfe9417d7172c592a19",
        "ResolvConfPath": "/var/lib/docker/containers/29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d/hostname",
        "HostsPath": "/var/lib/docker/containers/29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d/hosts",
        "LogPath": "/var/lib/docker/containers/29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d/29e960e7bf46371f7500e8ba9eec3505a51ca1568ed6002b6d115c84763bac6d-json.log",
        "Name": "/webapp",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "webodm_appmedia:/webodm/app/media:rw",
                "/home/piero/Documents/WebODM:/webodm:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "webodm_default",
            "PortBindings": {
                "35729/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "35729"
                    }
                ],
                "8000/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8000"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "unless-stopped",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": [],
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "shareable",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/3d537d176146d115548150e0205d0c0000943ba36b4033430087c1f6d45ea06e-init/diff:/var/lib/docker/overlay2/d53528543f648610c41ef005d170c3e827780dbab153fa680969db7025c807f9/diff:/var/lib/docker/overlay2/2785b1e4c93264402eed1b88eba40b52b803a6f17d335fd173de547599d89b4c/diff:/var/lib/docker/overlay2/e411367d0ac09f0b63a289520d7bd5c7d58dcc75f9d822381c3d3d57a95ec816/diff:/var/lib/docker/overlay2/9763fc50141baa52ef0773b317ac4158935895008863a34af9b58fc57083e34b/diff:/var/lib/docker/overlay2/20ded7655b5e68c09e71860df716c9347f1b11488ca08cf34389ac3dda62a922/diff:/var/lib/docker/overlay2/a65368445903820daa7c53c3c6bf4b81bedb780beb47c0981483c7b00ebfa8bd/diff:/var/lib/docker/overlay2/c7e356195e32d5eb0a11f4607073d4f00537c082432144b6a88649857bde4e9e/diff:/var/lib/docker/overlay2/6258b25b4774bdbe51ed2888e0ec8c7163dde53a7e848405a6fed50e5c30d514/diff:/var/lib/docker/overlay2/2fa60771f03ebf9612ed4ec642c9c2aec9880bf4dba51b58199c7db95971f182/diff:/var/lib/docker/overlay2/9189fcb47ef27433a9b035a083d742f3700da94289b3c4e1c2d88aaf94fe861f/diff",
                "MergedDir": "/var/lib/docker/overlay2/3d537d176146d115548150e0205d0c0000943ba36b4033430087c1f6d45ea06e/merged",
                "UpperDir": "/var/lib/docker/overlay2/3d537d176146d115548150e0205d0c0000943ba36b4033430087c1f6d45ea06e/diff",
                "WorkDir": "/var/lib/docker/overlay2/3d537d176146d115548150e0205d0c0000943ba36b4033430087c1f6d45ea06e/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/piero/Documents/WebODM",
                "Destination": "/webodm",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "volume",
                "Name": "webodm_appmedia",
                "Source": "/var/lib/docker/volumes/webodm_appmedia/_data",
                "Destination": "/webodm/app/media",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "29e960e7bf46",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "35729/tcp": {},
                "8000/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "WO_PORT=8000",
                "WO_HOST=localhost",
                "WO_DEBUG=YES",
                "WO_BROKER=redis://broker",
                "WO_DEV=YES",
                "WO_DEFAULT_NODES=1",
                "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "LANG=C.UTF-8",
                "GPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D",
                "PYTHON_VERSION=3.6.9",
                "PYTHON_PIP_VERSION=19.3.1",
                "PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/ffe826207a010164265d9cc807978e3604d18ca0/get-pip.py",
                "PYTHON_GET_PIP_SHA256=b86f36cc4345ae87bfd4f10ef6b2dbfa7a872fbff70608a1e43944d283fd0eee",
                "PYTHONUNBUFFERED=1",
                "PYTHONPATH=:/webodm",
                "PROJ_LIB=/usr/share/proj"
            ],
            "Cmd": null,
            "Image": "opendronemap/webodm_webapp",
            "Volumes": {
                "/webodm": {},
                "/webodm/app/media": {}
            },
            "WorkingDir": "/webodm",
            "Entrypoint": [
                "/bin/bash",
                "-c",
                "chmod +x /webodm/*.sh && /bin/bash -c \"/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/start.sh --create-default-pnode --setup-devenv\""
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "6e0523a3e82b4862974f69b02379379a696eac06832e1b6ea3c180ed88c6706f",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "webodm",
                "com.docker.compose.project.config_files": "docker-compose.yml,docker-compose.nodeodm.yml,docker-compose.dev.yml",
                "com.docker.compose.project.working_dir": "/home/piero/Documents/WebODM",
                "com.docker.compose.service": "webapp",
                "com.docker.compose.version": "1.25.0"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "61d3dd3d2513d31ed58f0bd465c59fb8399214b446e5ea5efa96c3f24e03e3c9",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/61d3dd3d2513",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "webodm_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "webapp",
                        "29e960e7bf46"
                    ],
                    "NetworkID": "96bce326295fa36d3cec217637f8a0ab21b08332565e506d92c86a5a6929dfee",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

Note I think this was started with the --dev flag, so there’s an extra volume.

Thank you Piero. As I suspected it’s an issue with the path… Just compared with my own and I get this…

   "Path": "/bin/bash -c \"chmod +x /webodm/*.sh && /bin/bash -c \\\"/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/start.sh\\\"\"",
   "Args": [
       "/bin/bash -c \"chmod +x /webodm/*.sh && /bin/bash -c \\\"/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 -- /webodm/start.sh\\\"\""

podman-compose obviously isn’t properly separating the /bin/bash command from the additional arguments. I’ll have a play around and see if I can work out how to reformat the docker-compose.yml to make it read properly.

SUCCESS!! I edited the docker-compose.yml for webapp to look like this…

entrypoint: /bin/bash
command: -c “chmod +x /webodm/*.sh && /bin/bash -c “/webodm/wait-for-postgres.sh db /webodm/wait-for-it.sh -t 0 broker:6379 – /webodm/start.sh””

and something similar for worker, and I can now access localhost:8000.
I’d be interested to know if making that change affects the docker users?

I’ll do some more testing first, but if everything appears to work correctly, then I’ll try and make that pull request for the readme for Fedora users.

2 Likes

This is fantastic. Thanks @twchambers.

Thank you, but I spoke a little too soon!
Although everything is up and running, I’m getting the same issue as with Docker where SELinux is stopping things from functioning. It’s obviously just a case of setting the permissions correctly but it’ll take me a bit of time to figure out how to do that properly.
In the mean time the dirty workaround is setenforce 0.

How do you know it’s a permission problem with SELinux ? I haven’t such problem in my Fedora (it’s a near “fresh” install).

When I select photos and try to start a process, I get multiple alerts from SELinux Troubleshooter. Along the lines of “SELinux is preventing gunicorn from relabelto access on the file DJI_0688.JPG.”
setenforce 0 stops these alerts and lets the process run through.
Maybe it’s time for a fresh install…

Okay, so that’s why I said “it’s a fresh install”. I had in past with Fedora 27/28/29 and SELinux, many people complained about this. But with a.“fresh” install of Fedora 31, I haven’t encountered any problem with SELinux.

I tried a fresh install, and while it solve a few minor issues I’d been having with my system, it didn’t help anything in relation to ODM.
I was still unable to get your build and run commands to get an instance up and running properly, and with my method, SELinux still attempted to stop the process.
It’s highly likely I’m doing something wrong, as I’m very new to the idea of containers, but if you’re able to add any more detail on what you might have done, it would be really appreciated.