I spun up a CentOS 8 VM to test this out, and running the podman
command from your post did result in a failure. I spent a little time this morning trying to figure out what was going on.
Looking at the output of podman run
, I can see the following error:
[root@localhost data]# podman run --name tiles -v /tmp/data:/data -p 8080:80 docker.io/klokantech/openmaptiles-server
[...]
2019-11-05 12:29:26,812 INFO exited: wizard (exit status 1; not expected)
If I podman exec
into the container, I can manually run the wizard
command and see more detailed logs. First, we need to figure out where the wizard
command lives. Since the container is using supervisord
as a process supervisor, that means we probably need to look in /etc/supervisor
for details:
[root@localhost ~]# podman exec -it tiles bash
root@de362646e453:/etc/supervisor# cd /etc/supervisor/
root@de362646e453:/etc/supervisor# ls
conf.d supervisord.conf
root@de362646e453:/etc/supervisor# cd conf.d/
root@de362646e453:/etc/supervisor/conf.d# ls
openmaptiles.conf
root@de362646e453:/etc/supervisor/conf.d# cat openmaptiles.conf
[program:wizard]
command=/bin/bash -c "cd /usr/local/src && node wizard"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
autostart=true
autorestart=false
startsecs=0
The key information is the command
line in the openmaptiles.conf
file. Let's try running the same command by hand:
root@de362646e453:/# cd /usr/local/src/
root@de362646e453:/usr/local/src# node wizard
Starting OpenMapTiles Map Server (action: run)
fs.js:961
return binding.readdir(pathModule._makeLong(path), options.encoding);
^
Error: EACCES: permission denied, scandir '/data'
at Error (native)
at Object.fs.readdirSync (fs.js:961:18)
at Wizard.init (/usr/local/src/wizard/src/main.js:928:19)
at new Wizard (/usr/local/src/wizard/src/main.js:119:8)
at Object.<anonymous> (/usr/local/src/wizard/src/main.js:1270:1)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
We're getting a "permission denied" error on the /data
directory. The permissions look okay:
root@de362646e453:/# ls -ld /data
drwxr-xr-x. 2 root root 6 Nov 5 12:08 /data
But we're not able to access it:
root@de362646e453:/# cd /data
root@de362646e453:/data# ls
ls: cannot open directory '.': Permission denied
If file permissions look okay but you're still unable to access something, that often means it's time to look at your selinux configuration. RHEL (and CentOS) both default to having selinux enabled. This will prevent a container from accessing parts of your filesystem to which they have not been explicitly granted access.
First, on the host, let's verify that selinux
is running in enforcing
mode:
[root@localhost ~]# getenforce
Enforcing
It is (as expected). Let's put it into permissive mode and see if that solves our problem:
[root@localhost ~]# setenforce 0
And now inside the container let's try and access the /data
directory again:
[root@localhost ~]# podman exec -it tiles bash
root@de362646e453:/# ls /data
root@de362646e453:/#
Great! No more errors. Let's try restarting the container:
[root@localhost data]# podman run --name tiles -v $(pwd):/data -p 8080:80 docker.io/klokantech/openmaptiles-server
/usr/lib/python2.7/dist-packages/supervisor/options.py:298: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
2019-11-05 12:37:18,493 CRIT Supervisor running as root (no user in config file)
2019-11-05 12:37:18,493 INFO Included extra file "/etc/supervisor/conf.d/openmaptiles.conf" during parsing
2019-11-05 12:37:18,498 INFO Creating socket tcp://localhost:8081
2019-11-05 12:37:18,500 INFO Closing socket tcp://localhost:8081
2019-11-05 12:37:18,510 INFO RPC interface 'supervisor' initialized
2019-11-05 12:37:18,511 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2019-11-05 12:37:18,511 INFO supervisord started with pid 1
2019-11-05 12:37:19,514 INFO spawned: 'wizard' with pid 8
2019-11-05 12:37:19,516 INFO spawned: 'xvfb' with pid 9
Starting OpenMapTiles Map Server (action: run)
2019-11-05 12:37:19,954 INFO success: wizard entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2019-11-05 12:37:19,954 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Config file not found!
Starting installation...
Installation wizard started at http://:::80/
List of available downloads ready.
That looks like a successful startup, and indeed, I can now access the tiles server on host port 8080
.
Now we have a decision to make:
- We can persistently disable selinux, or
- We can update our selinux configuration to permit the access that is currently being denied.
I would normally suggest (2), but it looks like the default selinux policy in CentOS 8 has some stupid defaults that make the process harder (the audit log messages that would identify the problem are disabled), so let's go with (1):
Edit /etc/selinux/config
.
Change SELINUX=enforcing
to either SELINUX=permissive
(permits access but selinux is still active and will log policy violations) or SELINUX=disabled
.
Reboot to make sure the change sticks as expected.
With this change, my CentOS 8 VM is now able to run the tiles server without a problem.