Headless VNC on Verdin iMX8M Plus in TorizonCore container

I’m using a Verdin iMX8M Plus and a Verdin development board. I’m using a TorizonCore reference image with sample containers. I have a docker image based on torizon/weston-vivante:2 with minimal changes.

I’m trying to get VNC to work with and without a monitor in a docker container following Remote Access the TorizonCore GUI Using VNC or RDP | Toradex Developer Center .

This works fine with an HDMI monitor attached. But I can’t connect a VNC client when there is no monitor attached.

I’ve found references to fixing this by adding a /boot/firmware/config.txt with these settings -

hdmi_force_hotplug=1
hdmi_drive=2
hdmi_mode=82

But when I add that to the container image, VNC doesn’t work and there’s no display on the monitor.

Below is the command line I’m using to launch the container, and no other containers are running when I do this. By the way this also has SD card exFAT support, courtesy of Jeremias :slight_smile:

docker run -d --rm --name=aevex --net=host
-v /dev:/dev -v /var/sota/storage/docker-compose
-v /tmp:/tmp -v /run/udev/:/run/udev/
–env ENABLE_VNC=1 --env ACCEPT_FSL_EULA=1
–device-cgroup-rule=‘c 4:* rmw’ --device-cgroup-rule=‘c 13:* rmw’
–device-cgroup-rule=‘c 199:* rmw’ --device-cgroup-rule=‘c 226:* rmw’
–device-cgroup-rule=‘b 179:* rmw’
–device /dev/fuse --cap-add SYS_ADMIN --cap-add CAP_SYS_TTY_CONFIG
aevex/geo-imx8m-plus --developer weston-launch
–tty=/dev/tty7 --user=root

What am I missing?

Greetings @techczech,

I was able to reproduce behavior on my side with our base torizon/weston-vivante:2 container image. I know an attached display shouldn’t be strictly necessary for a VNC connection so something may be wrong here.

On your side did you get any kind of error when trying to connect with VNC without a display? On my side i get some kind of message like “connection refused” or something similar.

Best Regards,
Jeremias

After detaching the monitor, I get “No connection could be made because the target machine actively refused it”.

From web searches it appears that is a default behavior, and you need the hdmi boot config settings to get around it. I’ve seen this as well on a completely different Ubuntu system. You’ll find several related discussions for Rasperry Pi, I tried a couple of those in both /boot and /boot/firmware. Putting a config.txt in /boot had no effect, when putting it in /boot/firmware it apparently got read, that’s when there was no VNC or monitor output.

I think I have something, you can force the HDMI interface to be enabled. This way the HDMI interface looks “active” to VNC despite no display actually being connected.

We have a section here on how to force this: Working with Weston on TorizonCore | Toradex Developer Center

Once I did this I was able to connect with VNC without a display. Though there are some lingering error/warning messages on the console since we’re forcing the interface without actually having a display. Could you give this a try and see if it works for you as well.

Best Regards,
Jeremias

Thank you, but sorry, I’m missing something again.

I can see a /sys/class/drm/card0-HDMI-A-1/status both from a Wayland terminal inside the container, and from Torizon Core serial debug terminal. That is the only “card*” suffixed with “HDMI-A-1”. If I try “echo on > /sys/class/drm/card0-HDMI-A-1/status” inside the container, as root, I get “Read-only file system”. If I do it from the TorizonCore debug terminal, logged in as “torizon”, I get “Permission denied”. I’d looked for TorizonCore root password before to sudo something else, and from what I’ve found the root account is disabled in TorizonCore. So can you tell me exactly what you did?

In order to run that command you need to be the root user itself. To do that login as the torizon user then run sudo su using the torizon user password. This will switch you to the root user and allow you to perform this command.

OK, that works for me too !!! From the debug terminal, I logged into “torizon”, then “sudo su”, then the echo command. I tried VNCing in with monitor connected, that worked fine (as before). Then disconnected the monitor, tried VNC again, and it worked fine (unlike before).

The issue now is that’s a mod to TorizonCore. Per Toradex’s strong recommendation I was trying to stay completely inside a docker container. If you can suggest a way to do that, I’d appreciate it.

Take it back, this appears to be solved. If I add a bind mount to the “docker run” arguments for HDMI (“-v /sys/class/drm/card0-HDMI-A-1:/sys/class/drm/card0-HDMI-A-1”), I can do the “echo on > /sys/class/drm/card0-HDMI-A-1/status” from inside the container, logged in as root. And can then VNC in after pulling the HDMI cable.

Thanks for the help !

Take it back again, there’s still an issue left. If you do the echo on from inside the container, the container needs to be restarted before VNC works with no monitor. So close.

You could probably make a script or systemd service that forces the HDMI interface on before any containers come up.

About your last response, I thought it was strongly recommended to stay away from changes in TorizonCore and keep them in the container?

I have something that works, inside the container, so we can put this to solved.

I’m not entirely happy with it as I have a similar need coming up that this won’t work for. But that’s a topic for a different thread, what I have works for the stated problem.

Details

I added another bind mount to the “docker run” to be able to “echo on > /sys/class/drm/card0-HDMI-A-1/status” from inside the container :

-v /sys/class/drm/card0-HDMI-A-1:/sys/class/drm/card0-HDMI-A-1 \

I made a /home/torizon/autorun.sh. I made that the entry point for the container. In Dockerfile :

ENTRYPOINT [“/bin/sh”, “-c”, “/home/torizon/autorun.sh”]

Important - the last line in this needs to call the entry point from the base torizon/weston-vivante image. Contents of autorun.sh :

  • This script is run at startup. This is done by making it the container ENTRYPOINT in the

  • Dockerfile used to build this container image. We need to call the original torizon/weston-

  • vivante entry script on conclusion to finish Toradex container initialization.

  • Mount the SD card if present
    mkdir /media/SDCard
    mount.exfat-fuse /dev/mmcblk1p1 /media/SDCard

  • Force HDMI connector state to allow it to run and access a GUI without a display connected, for VNC

  • Source : (see Jeremias’s link above)

  • I also found references to fixing this with adding a /boot/firmware/config.txt with settings

  • hdmi_force_hotplug=1 & hdmi_drive=1. I tried that, and with hdmi_drive set to 0, 1, and 2,

  • none of them worked.
    echo on > /sys/class/drm/card0-HDMI-A-1/status

  • Call the original torizon/weston-vivante container entry point script
    /usr/bin/entry.sh --developer weston-launch --tty=/dev/tty7 --user=root

With this, I’m able to cold start the iMX8M Plus in a development board with no monitor connected, then start the container and VNC into it.

I thought it was strongly recommended to stay away from changes in TorizonCore and keep them in the container?

I think you have a misunderstanding of this. You can make changes on TorizonCore when it makes sense. Not everything can or should be done within a container. If we didn’t want you doing changes on TorizonCore then we wouldn’t have created a tool for the sole purpose of doing changes/customizations on TorizonCore: TorizonCore Builder - Workflow | Toradex Developer Center

Things as they relate to your application should probably go into your container. But system-wide settings like network, display, and such can be done on TorizonCore when it makes sense to.

I just provided a work-around because your last comment indicated you still had an issue “Take it back again, there’s still an issue left.”

But if you found your own work-around then that’s fine too.

Best Regards,
Jeremias