Ubuntu HowTo: How to correctly run graphical application in Docker container with Qt and D-Bus?

Original Source Link

I was trying to get Audex running inside 16.04 LTS Docker container on the 20.04 LTS host.

The below method works normally for Gtk-based applications, I have tested it.

In current case I did the following:

sudo apt-get update
sudo apt-get install docker.io
sudo usermod -a -G docker $USER
# reboot

mkdir ~/docker-audex
cat > ~/docker-audex/Dockerfile << EOF
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y audex
CMD audex
EOF

docker build -t ubuntu:audex ~/docker-audex

Then try to launch it from terminal and got the output:

$ docker run -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --user="$(id --user):$(id --group)" ubuntu:audex 
QDBusConnection: session D-Bus connection created before QCoreApplication. Application
may misbehave. audex(7): KUniqueApplication: Cannot find the D-Bus
session server:  "/usr/bin/dbus-launch terminated abnormally with the
following error: Autolaunch error: X11 initialization failed. " 

audex(6): KUniqueApplication: Pipe closed unexpectedly.  

or

$ docker run -e DISPLAY -e DBUS_SESSION_BUS_ADDRESS -v /tmp/.X11-unix:/tmp/.X11-unix --user="$(id --user):$(id --group)" ubuntu:audex

QDBusConnection: session D-Bus connection created before
QCoreApplication. Application may misbehave. audex(7):
KUniqueApplication: Cannot find the D-Bus session server:  "Failed to
connect to socket /run/user/1000/bus: No such file or directory" 

audex(6): KUniqueApplication: Pipe closed unexpectedly.```

or

$ docker run -e DISPLAY -e DBUS_SESSION_BUS_ADDRESS -v /tmp/.X11-unix:/tmp/.X11-unix -v /run:/run --user="$(id --user):$(id --group)" ubuntu:audex
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave. audex(7):
KUniqueApplication: Cannot find the D-Bus session server:  "An
AppArmor policy prevents this sender from sending this message to this
recipient; type="method_call", sender="(null)" (inactive)
interface="org.freedesktop.DBus" member="Hello" error name="(unset)"
requested_reply="0" destination="org.freedesktop.DBus" (bus)" 

audex(6): KUniqueApplication: Pipe closed unexpectedly.  

and application window was not shown.

I suppose I have a problem with D-Bus here. How can we fix it?


Update, following @SimonSudler answer below:

$ docker run -e DISPLAY -e DBUS_SESSION_BUS_ADDRESS     -v /tmp/.X11-unix:/tmp/.X11-unix -v /run:/run     --user="$(id --user):$(id --group)"     --security-opt apparmor=unconfined     ubuntu:audex

QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
Error: Can not find password entry for uid 1000.
trying to create local folder //.kde: Permission denied
audex(7)/KSharedDataCache KSharedDataCache::Private::mapSharedMemory: Failed to establish shared memory mapping, will fallback to private memory -- memory usage will increase 
Usage: mv [OPTION]... [-T] SOURCE DEST
  or:  mv [OPTION]... SOURCE... DIRECTORY
  or:  mv [OPTION]... -t DIRECTORY SOURCE...
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.

Mandatory arguments to long options are mandatory for short options too.
      --backup[=CONTROL]       make a backup of each existing destination file
  -b                           like --backup but does not accept an argument
  -f, --force                  do not prompt before overwriting
  -i, --interactive            prompt before overwrite
  -n, --no-clobber             do not overwrite an existing file
If you specify more than one of -i, -f, -n, only the final one takes effect.
      --strip-trailing-slashes  remove any trailing slashes from each SOURCE
                                 argument
  -S, --suffix=SUFFIX          override the usual backup suffix
  -t, --target-directory=DIRECTORY  move all SOURCE arguments into DIRECTORY
  -T, --no-target-directory    treat DEST as a normal file
  -u, --update                 move only when the SOURCE file is newer
                                 than the destination file or when the
                                 destination file is missing
  -v, --verbose                explain what is being done
  -Z, --context                set SELinux security context of destination
                                 file to default type
      --help     display this help and exit
      --version  output version information and exit

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through
the VERSION_CONTROL environment variable.  Here are the values:

  none, off       never make backups (even if --backup is given)
  numbered, t     make numbered backups
  existing, nil   numbered if numbered backups exist, simple otherwise
  simple, never   always make simple backups

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report mv translation bugs to <http://translationproject.org/team/>
Full documentation at: <http://www.gnu.org/software/coreutils/mv>
or available locally via: info '(coreutils) mv invocation'
audex(7)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
Error: Can not find password entry for uid 1000.
X Error: BadAccess (attempt to access private resource denied) 10
  Extension:    130 (MIT-SHM)
  Minor opcode: 1 (X_ShmAttach)
  Resource id:  0x12d
X Error: BadShmSeg (invalid shared segment parameter) 128
  Extension:    130 (MIT-SHM)
  Minor opcode: 5 (X_ShmCreatePixmap)
  Resource id:  0x3a00017
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x3a00018
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x3a00018
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x3a00018
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x3a00018

adding --ipc=host does not help either:

$ docker run --ipc=host -e DISPLAY -e DBUS_SESSION_BUS_ADDRESS     -v /tmp/.X11-unix:/tmp/.X11-unix -v /run:/run     --user="$(id --user):$(id --group)"     --security-opt apparmor=unconfined     ubuntu:audex
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
Error: Can not find password entry for uid 1000.
trying to create local folder //.kde: Permission denied
audex(7)/KSharedDataCache KSharedDataCache::Private::mapSharedMemory: Failed to establish shared memory mapping, will fallback to private memory -- memory usage will increase 
Usage: mv [OPTION]... [-T] SOURCE DEST
  or:  mv [OPTION]... SOURCE... DIRECTORY
  or:  mv [OPTION]... -t DIRECTORY SOURCE...
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.

Mandatory arguments to long options are mandatory for short options too.
      --backup[=CONTROL]       make a backup of each existing destination file
  -b                           like --backup but does not accept an argument
  -f, --force                  do not prompt before overwriting
  -i, --interactive            prompt before overwrite
  -n, --no-clobber             do not overwrite an existing file
If you specify more than one of -i, -f, -n, only the final one takes effect.
      --strip-trailing-slashes  remove any trailing slashes from each SOURCE
                                 argument
  -S, --suffix=SUFFIX          override the usual backup suffix
  -t, --target-directory=DIRECTORY  move all SOURCE arguments into DIRECTORY
  -T, --no-target-directory    treat DEST as a normal file
  -u, --update                 move only when the SOURCE file is newer
                                 than the destination file or when the
                                 destination file is missing
  -v, --verbose                explain what is being done
  -Z, --context                set SELinux security context of destination
                                 file to default type
      --help     display this help and exit
      --version  output version information and exit

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through
the VERSION_CONTROL environment variable.  Here are the values:

  none, off       never make backups (even if --backup is given)
  numbered, t     make numbered backups
  existing, nil   numbered if numbered backups exist, simple otherwise
  simple, never   always make simple backups

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report mv translation bugs to <http://translationproject.org/team/>
Full documentation at: <http://www.gnu.org/software/coreutils/mv>
or available locally via: info '(coreutils) mv invocation'
audex(7)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
Error: Can not find password entry for uid 1000.

Run container without apparmor profile

The reason for this, is the docker-default profile for apparmor. The rules are integrated via this template into the docker daemon.

There is a quick way to verify, if this profile causes the issue, add the --security-opt apparmor=unconfined to the run command:

docker run -e DISPLAY -e DBUS_SESSION_BUS_ADDRESS 
    -v /tmp/.X11-unix:/tmp/.X11-unix -v /run:/run 
    --user="$(id --user):$(id --group)" 
    --security-opt apparmor=unconfined 
    -v /dev/sr0:/dev/sr0 
    -v /dev/cdrom:/dev/cdrom 
    --privileged 
    ubuntu:audex

You could start to write an apparmor profile for audex, but I don’t think it is worth the trouble. Since audix is a CD ripper, the user requires some “privileged” access to insert/remove CDs into the PC. So using the apparmor=unconfined should be secure enough.

Coredump of Audex

When audex starts, it executes several commands it expects to be encoders (e.g. faac --help). For some reason it also executes mv --help, which creates the weird output. At least that does not seem to be part of the problem. Also this behavior only occurs before the ~/.kde/share/config/audexrc file is written. After that, only the crash remains…

Looking at the core dump of audex:

gdb /usr/bin/audex core.audex.3225
...
(gdb) bt
#0  0x00007f8799abda7f in KUrl::KUrl(QString const&) () from /usr/lib/libkdecore.so.5
#1  0x00007f879b4c7245 in KCompactDisc::cdromDeviceUrl(QString const&) () from /usr/lib/libkcompactdisc.so.4
#2  0x0000000000423469 in MainWindow::MainWindow (this=0x23ef580, parent=<optimized out>, __in_chrg=<optimized out>, 
    __vtt_parm=<optimized out>) at /build/buildd/audex-0.78/mainwindow.cpp:39
#3  0x000000000041a159 in main (argc=3, argv=0x7ffd939ccf58) at /build/buildd/audex-0.78/main.cpp:46

I seams that audix dies while trying to read the CD-ROM device URL. I added the /dev/sr0 and /dev/cdrom to accommodate that, but it does not have any effect (see handbreak example with docker). Also adding the audex user in the container to the cdrom group did not help.

This seams to be a bug in old audix version from 16.04, which expects a legacy URL string.

It might be impossible to run audex from ubuntu:16.04 on a current Ubuntu system because of some missing “old” KDE behavior. There is however a Neon/Docker from KDE, but it requires also a KDE on the host.

Tagged : / / / /

Leave a Reply

Your email address will not be published. Required fields are marked *