Docker container does not run, if run with default entrypoint
Closed this issue · 8 comments
If I run this docker command (e.g. running the default entrypoint)
docker run \
--rm \
--net='bridge' \
--pids-limit 2048 \
-e TZ="Europe/Berlin" \
-e 'SML2MQTT_ANALYZE'='1' \
-v '/mnt/user/appdata/sml2mqtt':'/sml2mqtt':'rw' \
--device='/dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DK0EILL8-if00-port0:/dev/serial-ESY' \
--device='/dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DK0EJGPM-if00-port0:/dev/serial-EMH' \
'spacemanspiff2007/sml2mqtt:latest'
the output is:
Starting with sml2mqtt with user id: 9001 and group id: 9001
Create group sml2mqtt with id 9001
Create user sml2mqtt with id 9001
[2024-08-05 12:08:05,620] [sml ] INFO | Starting V3.0
[2024-08-05 12:08:05,620] [asyncio ] DEBUG | Using selector: EpollSelector
Shutting down ...
[2024-08-05 12:08:05,622] [sml.shutdown ] INFO | Shutting down ...
[2024-08-05 12:08:05,622] [sml.shutdown ] DEBUG | Starting shutdown
[2024-08-05 12:08:05,622] [sml.shutdown ] DEBUG | Stop devices
[2024-08-05 12:08:05,622] [sml.shutdown ] DEBUG | Stop devices done!
[2024-08-05 12:08:05,622] [sml.shutdown ] DEBUG | Shutdown complete
[2024-08-05 12:08:05,622] [sml.tasks ] DEBUG | Shutdown Task finished!
[2024-08-05 12:08:05,623] [sml.tasks ] DEBUG | All tasks done
[2024-08-05 12:08:05,623] [sml ] INFO | Closed with return code 0
But if I do this instead (running the entrypoint explicitly)
docker run \
--rm -it \
--entrypoint su-exec \
--net='bridge' \
--pids-limit 2048 \
-e TZ="Europe/Berlin" \
-e 'SML2MQTT_ANALYZE'='1' \
-v '/mnt/user/appdata/sml2mqtt':'/sml2mqtt':'rw' \
--device='/dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DK0EILL8-if00-port0:/dev/serial-ESY' \
--device='/dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DK0EJGPM-if00-port0:/dev/serial-EMH' \
'spacemanspiff2007/sml2mqtt:latest' \
sml2mqtt tini -- python -m sml2mqtt --config /sml2mqtt/config.yml
it works as expected:
[2024-08-05 12:14:52,646] [sml ] INFO | Starting V3.0
[2024-08-05 12:14:52,647] [asyncio ] DEBUG | Using selector: EpollSelector
[2024-08-05 12:14:52,649] [sml.serial ] DEBUG | Port /dev/serial-ESY successfully opened
[2024-08-05 12:14:52,649] [sml.serial ] DEBUG | Port /dev/serial-EMH successfully opened
[2024-08-05 12:14:53,762] [sml.serial-ESY ] INFO |
[2024-08-05 12:14:53,763] [sml.serial-ESY ] INFO | Received Frame
[... the rest of the output]
Can you maybe take a look at what's happening?
If you need any further assistance, I'm more than welcome to help you.
My Host OS is running UNRAID on AMD64.
What does happen if you run the container with
su-exec sml2mqtt tini -- python -m sml2mqtt --config /sml2mqtt/config.yml
?
Either the program does not find the config file (because it's not passed as an argument) and then immediately shuts down because there are no meters defined or the container somehow does receive the signal to shutdown.
That works as well, when I pass sh
as entrypoint and then do the providede su-exec sml2mqtt tini -- python -m sml2mqtt --config /sml2mqtt/config.yml
command.
There's a warning though, but I think that can be safely ignored
[WARN tini (7)] Tini is not running as PID 1 and isn't registered as a child subreaper.
Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
I've pushed Version 3.1 which adds some more logging because it's not clear why the shutdown occurs.
Could you try that version and if that still not works could you try "/entrypoint.sh
as an entrypoint?
There we go! :)
[sml] ERROR | SerialException during startup: [Errno 13] could not open port /dev/serial-ESY: [Errno 13] Permission denied: '/dev/serial-ESY'
[sml] ERROR | Traceback (most recent call last):
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/serial/serialposix.py", line 322, in open
[sml] ERROR | self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
[sml] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[sml] ERROR | PermissionError: [Errno 13] Permission denied: '/dev/serial-ESY'
[sml] ERROR |
[sml] ERROR | During handling of the above exception, another exception occurred:
[sml] ERROR |
[sml] ERROR | Traceback (most recent call last):
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/sml2mqtt/__main__.py", line 33, in a_main
[sml] ERROR | device.set_source(await create_source(device, settings=input_cfg))
[sml] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/sml2mqtt/sml_source/setup_source.py", line 10, in create_source
[sml] ERROR | return await SerialSource.create(device, settings)
[sml] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/sml2mqtt/sml_source/serial.py", line 26, in create
[sml] ERROR | transport, protocol = await create_serial_connection(
[sml] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/serial_asyncio/__init__.py", line 448, in create_serial_connection
[sml] ERROR | serial_instance = serial.serial_for_url(*args, **kwargs)
[sml] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/serial/__init__.py", line 90, in serial_for_url
[sml] ERROR | instance.open()
[sml] ERROR | File "/usr/local/lib/python3.12/site-packages/serial/serialposix.py", line 325, in open
[sml] ERROR | raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
[sml] ERROR | serial.serialutil.SerialException: [Errno 13] could not open port /dev/serial-ESY: [Errno 13] Permission denied: '/dev/serial-ESY'
/sml2mqtt # ls -lha /dev/serial-E*
crw-rw---- 1 root cron 188, 1 Aug 6 06:16 /dev/serial-EMH
crw-rw---- 1 root cron 188, 0 Aug 6 06:16 /dev/serial-ESY
Hmm.... I'm not quiet sure, how would I fix that, beside modifiying the entrypoint.sh
file?!
You have to set the env vars USER_ID and GROUP_ID for the container to a user that has access rights to the serial port.
Typically you would use a non-root user, grant access rights to the serial ports and then set the env vars accordingly.
Thanks for your analysis.
There's no such mentioning of that at https://sml2mqtt.readthedocs.io/en/latest/installation.html#docker , sorry that I didn't know of that.
As I'm a docker novice, maybe you can answer this question to me:
How would I modify the rights to that file(s) inside docker?!
Or does that inherit the rights of the underlying OS? I would very much not like to make any changes on the host OS, because it's somewhat complicated.
There's no such mentioning of that at https://sml2mqtt.readthedocs.io/en/latest/installation.html#docker , sorry that I didn't know of that.
Yes, I'm aware of that. I still have to update the docs once I go from the native install to the docker container so no worries.
How would I modify the rights to that file(s) inside docker?!
Or does that inherit the rights of the underlying OS? I would very much not like to make any changes on the host OS, because it's somewhat complicated.
It's the PUID and PGID of the user of the host system.
Just create a new user, add it to the group dialout
and use the ID of that user.
If that's not possible you can just set the ID of the user you run docker with.
Typically this is used so the process does not have e.g. root rights in case an attacker gains access to the container.
Since sml2mqtt doesn't provide an API and just pushed values outgoing the attack surface is imho very limited.
Thank you very much for your time and explanation. I think this is solved :)