Code Monkey home page Code Monkey logo

docker-baseimage-gui's Introduction

A minimal docker baseimage to ease creation of X graphical application containers

Release Build Status Donate

This is a docker baseimage that can be used to create containers able to run any X application on a headless server very easily. The application's GUI is accessed through a modern web browser (no installation or configuration needed on the client side) or via any VNC client.

Table of Content

Images

Different docker images are available:

Base Distribution Docker Image Base Tag Size
Alpine 3.14 alpine-3.14
Alpine 3.15 alpine-3.15
Alpine 3.16 alpine-3.16
Alpine 3.17 alpine-3.17
Alpine 3.18 alpine-3.18
Alpine 3.19 alpine-3.19
Debian 10 debian-10
Debian 11 debian-11
Ubuntu 16.04 LTS ubuntu-16.04
Ubuntu 18.04 LTS ubuntu-18.04
Ubuntu 20.04 LTS ubuntu-20.04
Ubuntu 22.04 LTS ubuntu-22.04

Content

Here are the main components of the baseimage:

  • An init system.
  • A process supervisor, with proper PID 1 functionality (proper reaping of processes).
  • TigerVNC, a X server with an integrated VNC server.
  • Openbox, a window manager.
  • noVNC, a HTML5 VNC client.
  • NGINX, a high-performance HTTP server.
  • Useful tools to ease container building.
  • Environment to better support dockerized applications.

Versioning

Images are versioned. Version number follows the semantic versioning. The version format is MAJOR.MINOR.PATCH, where an increment of the:

  • MAJOR version indicates that a backwards-incompatible change has been done.
  • MINOR version indicates that functionality has been added in a backwards-compatible manner.
  • PATCH version indicates that a bug fix has been done in a backwards-compatible manner.

Tags

For each distribution-specific image, multiple tags are available:

Tag Description
distro-vX.Y.Z Exact version of the image.
distro-vX.Y Latest version of a specific minor version of the image.
distro-vX Latest version of a specific major version of the image.

Getting started

The Dockerfile for your application can be very simple, as only three things are required:

  • Instructions to install the application.
  • A script that starts the application (stored at /startapp.sh in container).
  • The name of the application.

Here is an example of a docker file that would be used to run the xterm terminal.

In Dockerfile:

# Pull base image.
FROM jlesage/baseimage-gui:alpine-3.15-v4

# Install xterm.
RUN add-pkg xterm

# Copy the start script.
COPY startapp.sh /startapp.sh

# Set the name of the application.
RUN set-cont-env APP_NAME "Xterm"

In startapp.sh:

#!/bin/sh
exec /usr/bin/xterm

Then, build your docker image:

docker build -t docker-xterm .

And run it:

docker run --rm -p 5800:5800 -p 5900:5900 docker-xterm

You should be able to access the xterm GUI by opening in a web browser:

http://[HOST IP ADDR]:5800

Using the Baseimage

Selecting a Baseimage

Using a baseimage based on Alpine Linux is the recommended choice. Not only because of its small size, but also because Alpine Linux is a distribution based on musl and BusyBox that is designed for security, simplicity and resource efficiency.

However, using this baseimage to integrate an application not part of the Alpine's software repository or without its source code available may be harder. This is because Alpine Linux uses musl C standard library instead of GNU C library (glibc) that most applications are built against. Compatibility between these two libraries is very limited.

Integrating glibc binaries often require to add glibc to the image. See the Adding glibc section for more details.

Else, Debian and Ubuntu images are well known Linux distributions that provide great compatibility with existing applications.

Container Startup Sequence

When the container is starting, the following steps are performed:

  • The init process (/init) is invoked.
  • Internal environment variables are loaded from /etc/cont-env.d.
  • Initialization scripts under /etc/cont-init.d are executed in alphabetical order.
  • Control is given to the process supervisor.
  • The service group /etc/services.d/default is loaded, along with its dependencies.
  • Services are started, in proper order.
  • Container is now fully started.

Container Shutdown Sequence

There are two ways a container can shutdown:

  1. When the implemented application terminates.
  2. When Docker performs a shutdown of the container (e.g via the docker stop command).

In both cases, the shutdown sequence is:

  • All services are terminated, in reverse order.
  • If some processes are still alive, a SIGTERM is sent to everyone.
  • After 5 seconds, all remaining processes are forcefully terminated via the SIGKILL signal.
  • The process supervisor execute the exit script (/etc/services.d/exit).
  • The exit script executes, in alphabetical order, finalization scripts defined under /etc/cont-finish.d/.
  • Container is full stopped.

Environment Variables

Environment variables are very useful to customize the behavior of the container and its application.

There are two types of environment variables:

  • Public: These variables are targeted to people using the container. They provide a way to configure it. They are declared in the Dockerfile, via the ENV instruction. Their value can be set by users during the creation of the container, via the -e "<VAR>=<VALUE>" argument of the docker run command. Also, many Docker container management systems use these variables to automatically provide configuration parameters to the user.

  • Internal: These variables are the ones that don't need to be exposed to users. They are useful for the application itself, but are not intended to be changed by users.

NOTE: If a variable is defined as both an internal and public one, the value of the public variable takes precedence.

Public Environment Variables

The following public environment variables are provided by the baseimage:

Variable Description Default
USER_ID ID of the user the application runs as. See User/Group IDs to better understand when this should be set. 1000
GROUP_ID ID of the group the application runs as. See User/Group IDs to better understand when this should be set. 1000
SUP_GROUP_IDS Comma-separated list of supplementary group IDs of the application. (no value)
UMASK Mask that controls how permissions are set for newly created files and folders. The value of the mask is in octal notation. By default, the default umask value is 0022, meaning that newly created files and folders are readable by everyone, but only writable by the owner. See the online umask calculator at http://wintelguy.com/umask-calc.pl. 0022
LANG Set the locale, which defines the application's language, if supported. Format of the locale is language[_territory][.codeset], where language is an ISO 639 language code, territory is an ISO 3166 country code and codeset is a character set, like UTF-8. For example, Australian English using the UTF-8 encoding is en_AU.UTF-8. en_US.UTF-8
TZ TimeZone used by the container. Timezone can also be set by mapping /etc/localtime between the host and the container. Etc/UTC
KEEP_APP_RUNNING When set to 1, the application will be automatically restarted when it crashes or terminates. 0
APP_NICENESS Priority at which the application should run. A niceness value of -20 is the highest priority and 19 is the lowest priority. The default niceness value is 0. NOTE: A negative niceness (priority increase) requires additional permissions. In this case, the container should be run with the docker option --cap-add=SYS_NICE. 0
INSTALL_PACKAGES Space-separated list of packages to install during the startup of the container. Packages are installed from the repository of the Linux distribution this container is based on. ATTENTION: Container functionality can be affected when installing a package that overrides existing container files (e.g. binaries). (no value)
PACKAGES_MIRROR Mirror of the repository to use when installing packages. (no value)
CONTAINER_DEBUG Set to 1 to enable debug logging. 0
DISPLAY_WIDTH Width (in pixels) of the application's window. 1920
DISPLAY_HEIGHT Height (in pixels) of the application's window. 1080
DARK_MODE When set to 1, dark mode is enabled for the application. 0
SECURE_CONNECTION When set to 1, an encrypted connection is used to access the application's GUI (either via a web browser or VNC client). See the Security section for more details. 0
SECURE_CONNECTION_VNC_METHOD Method used to perform the secure VNC connection. Possible values are SSL or TLS. See the Security section for more details. SSL
SECURE_CONNECTION_CERTS_CHECK_INTERVAL Interval, in seconds, at which the system verifies if web or VNC certificates have changed. When a change is detected, the affected services are automatically restarted. A value of 0 disables the check. 60
WEB_LISTENING_PORT Port used by the web server to serve the UI of the application. This port is used internally by the container and it is usually not required to be changed. By default, a container is created with the default bridge network, meaning that, to be accessible, each internal container port must be mapped to an external port (using the -p or --publish argument). However, if the container is created with another network type, changing the port used by the container might be useful to prevent conflict with other services/containers. NOTE: a value of -1 disables listening, meaning that the application's UI won't be accessible over HTTP/HTTPs. 5800
VNC_LISTENING_PORT Port used by the VNC server to serve the UI of the application. This port is used internally by the container and it is usually not required to be changed. By default, a container is created with the default bridge network, meaning that, to be accessible, each internal container port must be mapped to an external port (using the -p or --publish argument). However, if the container is created with another network type, changing the port used by the container might be useful to prevent conflict with other services/containers. NOTE: a value of -1 disables listening, meaning that the application's UI won't be accessible over VNC. 5900
VNC_PASSWORD Password needed to connect to the application's GUI. See the VNC Password section for more details. (no value)
ENABLE_CJK_FONT When set to 1, open-source computer font WenQuanYi Zen Hei is installed. This font contains a large range of Chinese/Japanese/Korean characters. 0

Internal Environment Variables

The following internal environment variables are provided by the baseimage:

Variable Description Default
APP_NAME Name of the implemented application. DockerApp
APP_VERSION Version of the implemented application. (no value)
DOCKER_IMAGE_VERSION Version of the Docker image that implements the application. (no value)
DOCKER_IMAGE_PLATFORM Platform (OS / CPU architecture) of the Docker image that implements the application. (no value)
HOME Home directory. (no value)
XDG_CONFIG_HOME Defines the base directory relative to which user specific configuration files should be stored. /config/xdg/config
XDG_DATA_HOME Defines the base directory relative to which user specific data files should be stored. /config/xdg/data
XDG_CACHE_HOME Defines the base directory relative to which user specific non-essential data files should be stored. /config/xdg/cache
TAKE_CONFIG_OWNERSHIP When set to 0, ownership of the content of the /config directory is not taken during startup of the container. 1
INSTALL_PACKAGES_INTERNAL Space-separated list of packages to install during the startup of the container. Packages are installed from the repository of the Linux distribution this container is based on. (no value)
SUP_GROUP_IDS_INTERNAL Comma-separated list of supplementary group IDs of the application. These are merged with the ones that might be supplied by SUP_GROUP_IDS. (no value)

Adding/Removing Internal Environment Variables

Internal environment variables are defined by adding a file to /etc/cont-env.d/ inside the container, where the name of the file is the name of the variable and its value is defined by the content of the file.

If the file has execute permission, the init process will execute the program and the value of the environment variable is expected to be printed to its standard output.

NOTE: If the program exits with the return code 100, the environment variable is not set (this is different than being set with an empty value).

NOTE: Any output to stderr performed by the program is redirected to the container's log.

NOTE: The helper set-cont-env can be used to set internal environment variables from the Dockerfile.

Availability

Since public environment variables are defined during the creation of the container, they are always available to all your scripts and services, as soon as the container starts.

For internal environment variables, they first need to be loaded during the startup of the container before they can be used. Since this is done before running init scripts and services, availability should not be an issue.

Docker Secrets

Docker secrets is a functionality available to swarm services that offers a secure way to store sensitive information such as username, passwords, etc.

This baseimage automatically exports, as environment variables, Docker secrets that follow this naming convention:

CONT_ENV_<environment variable name>

For example, for a secret named CONT_ENV_MY_PASSWORD, the environment variable MY_PASSWORD is created, with its content matching the one of the secret.

Ports

Here is the list of ports used by the baseimage. With a container using the default bridge network, these ports can be mapped to the host via the -p <HOST_PORT>:<CONTAINER_PORT> parameter.

Port Mapping to host Description
5800 Optional Port to access the application's GUI via the web interface. Mapping to the host is optional if access through the web interface is not wanted. For a container not using the default bridge network, the port can be changed with the WEB_LISTENING_PORT environment variable.
5900 Optional Port to access the application's GUI via the VNC protocol. Mapping to the host is optional if access through the VNC protocol is not wanted. For a container not using the default bridge network, the port can be changed with the VNC_LISTENING_PORT environment variable.

User/Group IDs

When mapping data volumes (via the -v flag of the docker run command), permissions issues can occur between the host and the container. Files and folders of a data volume are owned by a user, which is probably not the same as the default user under which the implemented application is running. Depending on permissions, this situation could prevent the container from accessing files and folders on the shared volume.

To avoid this problem, you can specify the user the application should run as.

This is done by passing the user ID and group ID to the container via the USER_ID and GROUP_ID environment variables.

To find the right IDs to use, issue the following command on the host, with the user owning the data volume on the host:

id <username>

Which gives an output like this one:

uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),4(adm),24(cdrom),27(sudo),46(plugdev),113(lpadmin)

The value of uid (user ID) and gid (group ID) are the ones that you should be given the container.

Locales

The default locale of the container is set to POSIX. If this cause issues with your application, the proper locale can be installed. For example, adding the following instructions to your Dockerfile set the locale to en_US.UTF-8.

RUN \
    add-pkg locales && \
    sed-patch 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    locale-gen
ENV LANG=en_US.UTF-8

NOTE: Locales are not supported by musl C standard library on Alpine. See:

Accessing the GUI

Assuming that container's ports are mapped to the same host's ports, the graphical interface of the application can be accessed via:

  • A web browser:
http://<HOST IP ADDR>:5800
  • Any VNC client:
<HOST IP ADDR>:5900

Security

By default, access to the application's GUI is done over an unencrypted connection (HTTP or VNC).

Secure connection can be enabled via the SECURE_CONNECTION environment variable. See the Environment Variables section for more details on how to set an environment variable.

When enabled, application's GUI is performed over an HTTPs connection when accessed with a browser. All HTTP accesses are automatically redirected to HTTPs.

When using a VNC client, the VNC connection is performed over SSL. Note that few VNC clients support this method. SSVNC is one of them.

SSVNC

SSVNC is a VNC viewer that adds encryption security to VNC connections.

While the Linux version of SSVNC works well, the Windows version has some issues. At the time of writing, the latest version 1.0.30 is not functional, as a connection fails with the following error:

ReadExact: Socket error while reading

However, for your convienence, an unoffical and working version is provided here:

https://github.com/jlesage/docker-baseimage-gui/raw/master/tools/ssvnc_windows_only-1.0.30-r1.zip

The only difference with the offical package is that the bundled version of stunnel has been upgraded to version 5.49, which fixes the connection problems.

Certificates

Here are the certificate files needed by the container. By default, when they are missing, self-signed certificates are generated and used. All files are PEM encoded, x509 certificates.

Container Path Purpose Content
/config/certs/vnc-server.pem VNC connection encryption. VNC server's private key and certificate, bundled with any root and intermediate certificates.
/config/certs/web-privkey.pem HTTPs connection encryption. Web server's private key.
/config/certs/web-fullchain.pem HTTPs connection encryption. Web server's certificate, bundled with any root and intermediate certificates.

NOTE: To prevent any certificate validity warnings/errors from the browser or VNC client, make sure to supply your own valid certificates.

NOTE: Certificate files are monitored and relevant daemons are automatically restarted when changes are detected.

VNC Password

To restrict access to your application, a password can be specified. This can be done via two methods:

  • By using the VNC_PASSWORD environment variable.
  • By creating a .vncpass_clear file at the root of the /config volume. This file should contains the password in clear-text. During the container startup, content of the file is obfuscated and moved to .vncpass.

The level of security provided by the VNC password depends on two things:

  • The type of communication channel (encrypted/unencrypted).
  • How secure access to the host is.

When using a VNC password, it is highly desirable to enable the secure connection to prevent sending the password in clear over an unencrypted channel.

Access to the host by unexpected users with sufficient privileges can be dangerous as they can retrieve the password with the following methods:

  • By looking at the VNC_PASSWORD environment variable value via the docker inspect command. By defaut, the docker command can be run only by the root user. However, it is possible to configure the system to allow the docker command to be run by any users part of a specific group.
  • By decrypting the /config/.vncpass file. This requires the user to have the appropriate permission to read the file: it has to be root or be the user defined by the USER_ID environment variable.

DH Parameters

Diffie-Hellman (DH) parameters define how the DH key-exchange is performed. More details about this algorithm can be found on the OpenSSL Wiki.

DH Parameters are saved into the PEM encoded file located inside the container at /config/certs/dhparam.pem. By default, when this file is missing, 2048 bits DH parameters are automatically generated. Note that this one-time operation takes some time to perform and increases the startup time of the container.

Initialization Scripts

During the container startup, initialization scripts are executed in alphabetical order. They are executed before starting services.

Initialization scripts are located at /etc/cont-init.d/ inside the container.

To have a better predictability of the execution order, name of the scripts follows the XX-name.sh format, where XX is a sequence number.

The following ranges are used by the baseimage:

  • 10-29
  • 70-89

Unless specific needs are required, containers built against this baseimage should use the range 50-59.

Finalization Scripts

Finalization scripts are executed, in alphabetical order, during the shutdown process of the container. They are executed after all services have been stopped.

Finalization scripts are located under /etc/cont-finish.d/ inside the container.

Services

Services are programs handled by the process supervisor that run in background. When a service dies, it can be configured to be automatically restarted.

Services are defined under /etc/services.d/ in the container. Each service has its own directory, in which different files are used to store the behavior of the service.

The content of files provides the value for the associated configuration setting. If the file has execution permission, it will be executed by the process supervisor and its output is taked as the value of the configuration setting.

File Type Description Default
run Program The program to run. N/A
is_ready Program Program invoked by the process supervisor to verify if the service is ready. The program should exit with an exit code of 0 when service is ready. PID of the service if given to the program as parameter. N/A
kill Program Program to run when service needs to be killed. The PID of the service if given to the program as parameter. Note that the TERM signal is still sent to the service after executing the program. N/A
finish Program Program invoked when the service terminates. The service's exit code is given to the program as parameter. N/A
params String Parameter for the service's program to run. One parameter per line. No parameter
environment String Environment to use for the service. One environment variable per line, of the form key=value. Environment untouched
respawn Boolean Whether or not the process must be respawned when it dies. FALSE
sync Boolean Whether or not the process supervisor waits until the service ends. This is mutually exclusive with respawn. FALSE
ready_timeout Unsigned integer Maximum amount of time (in milliseconds) to wait for the service to be ready. 5000
interval Interval Interval, in seconds, at which the service should be executed. This is mutually exclusive with respawn. No interval
uid Unsigned integer The user ID under which the service will run. $USER_ID
gid Unsigned integer The group ID under which the service will run. $GROUP_ID
sgid Unsigned integer List of supplementary group IDs of the service. One group ID per line. Empty list
umask Octal integer The umask value (in octal notation) of the service. 0022
priority Signed integer Priority at which the service should run. A niceness value of -20 is the highest priority and 19 is the lowest priority. 0
workdir String The working directory of the service. Service's directory path
ignore_failure Boolean When set, the inability to start the service won't prevent the container to start. FALSE
shutdown_on_terminate Boolean Indicates that the container should be shut down when the service terminates. FALSE
min_running_time Unsigned integer The minimum amount of time (in milliseconds) the service should be running before considering it as ready. 500
disabled Boolean Indicates that the service is disabled, meaning that it won't be loaded nor started. FALSE
.dep Boolean Indicates that the service depends on another one. For example, having srvB.dep means that srvB should be started before this service. N/A

The following table provides more details about some value types:

Type Description
Program An executable binary, a script or a symbolic link to the program to run. The program file must have the execute permission.
Boolean A boolean value. A true value can be 1, true, on, yes, y, enable, enabled. A false value can be 0, false, off, no, n, disable, disabled. Values are case insensitive. Also, the presence of an empty file indicates a true value (i.e. the file can be "touched").
Interval An unsigned integer value. The following values are also accepted (case insensitive): yearly, monthly, weekly, daily, hourly.

Service Group

A service group is a service for which there is no run program. The process supervisor will only load its dependencies.

Default Service

During startup, the process supervisor first load the service group default. This service group contains dependencies to services that should be started and that are not a dependency of the app service.

Service Readiness

By default, a service is considered ready once it has been successfully launched and ran for a minimum amount of time (500ms by default).

This behavior can be adjusted with the following methods:

  • By adjusting the minimum amount of time the service should run before considering it as ready. This can be done by adding the min_running_time file to the service's directory.
  • By informing the process supervisor when the service is ready. This is done by adding the is_ready program to the service's directory, along with ready_timeout file to indicate the maximum amount of time to wait for the service to be ready.

Configuration Directory

Applications often need to write configuration, data, states, logs, etc. Inside the container, this data should be stored under the /config directory.

This directory is intended to be mapped to a folder on the host. The goal is to write stuff outside the container to keep this data persistent.

NOTE: During the container startup, ownership of this folder and all its content is taken. This is to make sure that /config can be accessed by the user configured through USER_ID/GROUP_ID. This behavior can be adjusted via the TAKE_CONFIG_OWNERSHIP internal environment variable.

Application's Data Directories

A lot of applications use the environment variables defined by the XDG Base Directory Specification to determine where to store various data. The baseimage sets these variables so they all fall under /config/:

  • XDG_DATA_HOME=/config/xdg/data
  • XDG_CONFIG_HOME=/config/xdg/config
  • XDG_CACHE_HOME=/config/xdg/cache
  • XDG_STATE_HOME=/config/xdg/state

Container Log

Everything written to the standard output and standard error output of scripts executed by the init process and services is saved into the container's log. The container log can be viewed with the command docker logs <name of the container>.

To ease consultation of the log, all messages are prefixed with the name of the service or script. Also, it is a good idea to limit the number of information written to this log. If a program's output is too verbose, it is preferable to redirect it to a file. For example, the run command of a service that redirects the standard output and standard error output to different files could be:

#!/bin/sh
exec /usr/bin/my_service > /config/log/my_service_out.log 2> /config/log/my_service_err.log

Logrotate

The baseimage integrates logrotate, an utility used to rotate and compress log files. This tool runs automatically once a day via a service. The service is automatically disabled when no log files are configured.

To enable the rotation/compression of a log file, a configuration file needs to be added to the /etc/cont-logrotate.d directory inside the container. This configuration defines how to handle this specific log file.

Here is a simple example of a configuration defined at /etc/cont-logrotate.d/myapp:

/config/log/myapp.log {
    minsize 1M
}

This configuration file can override the default parameters, which are defined at /opt/base/etc/logrotate.conf inside the container. In summary, by default:

  • Log files are rotated weekly.
  • Four weeks worth of backlogs are kept.
  • Rotated log files are compressed.
  • Date is used as a suffix of rotated log files.

For more details about the content of logrotate configuration files, see the manual at https://linux.die.net/man/8/logrotate.

Log Monitor

The baseimage includes a simple log monitor. This monitor allows sending notification(s) when a particular message is detected in a log or status file.

This system has two main components:

  • Notification definitions: Describe properties of a notification (title, message, severity, etc), how it is triggered (filtering function) and the associated monitored file(s).
  • Backends (targets): Once a matching string is found in a file, a notification is triggered and sent to one or more backends. A backend can implement any functionality. For example, it could send the notification to the container's log, a file or an online service.

There are two types of files that can be monitored:

  • Log files: A log file is a file having new content appended to it.
  • *Status files: A status file doesn't have new content appended. Instead, its whole content is refreshed/overwritten periodically.

Notification Definition

The definition of a notification consists in multiple files, stored in a directory under /etc/logmonitor/notifications.d inside the container. For example, definition of notification MYNOTIF is found under /etc/logmonitor/notifications.d/MYNOTIF/.

The following table describe files part of the definition:

File Mandatory Description
filter Yes Program (script or binary with executable permission) used to filter messages from a log file. It is invoked by the log monitor with a single argument: a line from the log file. On a match, the program should exit with a value of 0. Any other values is interpreted as non-match.
title Yes File containing the title of the notification. To produce dynamic content, the file can be a program (script or binary with executable permission). In this case, the program is invoked by the log monitor with the matched message from the log file as the single argument. Output of the program is used as the notification's title.
desc Yes File containing the description/message of the notification. To produce dynamic content, the file can be a program (script or binary with executable permission). In this case, the program is invoked by the log monitor with the matched message from the log file as the single argument. Output of the program is used as the notification's description/message.
level Yes File containing severity level of the notification. Valid severity level values are ERROR, WARNING or INFO. To produce dynamic content, the file can be a program (script or binary with executable permission). In this case, the program is invoked by the log monitor with the matched message from the log file as the single argument. Output of the program is used as the notification's severity level.
source Yes File containing the absolute path(s) to file(s) to monitor (one path per line). Prepend the path with status: to indicate that the file is a status file. A path with prefixed with log: or without any prefix is considered as a log file.

Notification Backend

Definition of a notification backend is stored in a directory under /etc/cont-logmonitor/targets.d. For example, definition of STDOUT backend is found under /etc/cont-logmonitor/target.d/STDOUT/. The following table describe files part of the definition:

File Mandatory Description
send Yes Program (script or binary with executable permission) that sends the notification. It is invoked by the log monitor with the following notification properties as arguments: title, description/message and the severity level.
debouncing No File containing the minimum amount time (in seconds) that must elapse before sending the same notification with this backend. A value of 0 means infinite (notification is sent once). If this file is missing, no debouncing is done.

By default, the baseimage contains the following notification backends:

Backend Description Debouncing time
stdout Display a message to the standard output, making it visible in the container's log. Message of the format is {LEVEL}: {TITLE} {MESSAGE}. 21 600s (6 hours)
yad Display the notification in a window box, visible in the application's GUI. Infinite

Adding glibc

For baseimages based on Alpine Linux, glibc can be installed to the image by adding the following line to your Dockerfile:

RUN install-glibc

Helpers

The baseimage contains a few helpers that can be used when bulding a container or during the execution of a container.

Adding/Removing Packages

To add or remove packages, use the helpers add-pkg and del-pkg provided by this baseimage. To minimize the size of the container, these tools perform proper cleanup and make sure that no useless files are left after addition or removal of packages.

Also, these tools can be used to easily install a group packages temporarily. Using the --virtual NAME parameter, this allows installing packages and remove them at a later time using the provided NAME (no need to repeat given packages).

Note that if a specified package is already installed, it will be ignored and will not be removed automatically. For example, the following commands could be added to Dockerfile to compile a project:

RUN \
    add-pkg --virtual build-dependencies build-base cmake git && \
    git clone https://myproject.com/myproject.git
    make -C myproject && \
    make -C myproject install && \
    del-pkg build-dependencies

Supposing that, in the example above, the git package was already installed when the call to add-pkg is performed, running del-pkg build-dependencies doesn't remove it.

Modifying Files With Sed

sed is a useful tool often used in container builds to modify files. However, one downside of this method is that there is no easy way to determine if sed actually modified the file or not.

It's for this reason that the baseimage includes a helper that gives sed a "patch-like" behavior: if applying a sed expression results in no change on the target file, then an error is reported. This helper is named sed-patch and has the following usage:

sed-patch [SED_OPT]... SED_EXPRESSION FILE

Note that the sed option -i (edit files in place) is already supplied by the helper.

It can be used in Dockerfile, for example, like this:

RUN sed-patch 's/Replace this/By this/' /etc/myfile

If running this sed expression doesn't bring any change to /etc/myfiles, the command fails and thus, the Docker build also.

Evaluating Boolean Value

Environment variables are often used to store a boolean value. Using the helpers is-bool-value-true and is-bool-value-false allows to easily determine if a value is "true" or "false".

The following values are considered "true":

  • 1
  • true
  • yes
  • enabled
  • enable
  • on

The following values are considered "false":

  • 0
  • false
  • no
  • disabled
  • disable
  • off

For example, the following shell script snippet checks if the environment variable CONTAINER_DEBUG contains a "true" value:

if is-bool-value-true "${CONTAINER_DEBUG:-0}"; then
    # Do something...
fi

Taking Ownership of a Directory

The helper take-ownership recursively sets the user ID and group ID of a directory and all the files and directories under it.

This helper is well suited for scenarios where the directory is mapped to the host. If on the host this directory is a network share, setting/changing the ownership via chown can fail. The helper handles this case by ignoring the failure if a write test turns out to be positive.

For example, the following command take ownership of /config, by automatically using the user and group IDs from the USER_ID and GROUP_ID environment variables:

take-ownership /config

User and group IDs can also be explicit. For example, to set ownership to user ID 99 and group ID 100:

take-ownership /config 99 100

Setting Interval Environment Variable

The helper set-cont-env can be used to set internal environment variables from the Dockerfile.

For example, the following line can be added to the Dockerfile to set the value of the APP_NAME internal environment variable:

RUN set-cont-env APP_NAME "Xterm"

This automatically creates the environment variable file under /etc/cont-env.d.

Application Icon

A picture of your application can be added to the image. This picture is displayed in the WEB interface's navigation bar. This is also the master picture used to generate favicons that support different browsers and platforms.

Add the following command to your Dockerfile, with the proper URL pointing to your master icon: The master icon should be a square PNG image with a size of at least 260x260 for optimal results.

# Generate and install favicons.
RUN \
    APP_ICON_URL=https://github.com/jlesage/docker-templates/raw/master/jlesage/images/generic-app-icon.png && \
    install_app_icon.sh "$APP_ICON_URL"

Note that favicons are generated by RealFaviconGenerator.

Dark Mode

Dark mode can be enabled via the DARK_MODE environment variable. When enabled, the web interface used to display the application is automatically adjusted accordingly.

For the application itself, supporting dark mode is more complicated. Applications don't use the same toolkit to build their UI and each toolkit has its own way to activate the dark mode.

The baseimage provides support for the GTK and QT toolkits.

GTK

When dark mode is enabled, the baseimage automatically setups the environment to force the application to use a dark theme. Under the hood, this is done by setting the following environment variables:

  • GTK_THEME is set to Adwaita:dark. This is used by GTK3 and GTK4 applications.
  • GTK2_RC_FILES is set to /opt/base/share/themes/Dark/gtk-2.0/gtkrc. This is used by GTK2 applications.

QT

When dark mode is enabled, the baseimage automatically setup the environment to force the application to use a dark theme. Under the hood, this is done by setting the QT_STYLE_OVERRIDE environment variable to Adwaita-Dark.

In addition, the application's Dockerfile should install the Adwaita style/theme. It is provided by the adwaita-qt package, available from the Ubuntu, Debian or Alpine Linux software repositories.

NOTE: Dark mode is currently supported by QT5 and QT6.

Tips and Best Practices

Do Not Modify Baseimage Content

Try to avoid modifications to files provided by the baseimage. This minimizes the risk of breaking your container after using a new version of the baseimage.

Default Configuration Files

It is often useful to keep the original version of a configuration file. For example, a copy of the original file could be modified by an initialization script before being installed.

These original files, also called default files, should be stored under the /defaults directory inside the container.

The $HOME Variable

The application is run under a Linux user having its own ID. This user has no login capability, has no password, no valid login shell and no home directory. It is effectively a kind of user used by daemons.

Thus, by default, the $HOME environment variable is not set. While this should be fine in most case, some applications may expect the $HOME environment variable to be set (since normally the application is run by a logged user) and may not behave correctly otherwise.

To make the application happy, the home directory can be set at the beginning of the startapp.sh script:

export HOME=/config

Adjust the location of the home directory to fit your needs. However, if the application uses the home directory to write data, make sure it is done in a volume mapped to the host (e.g. /config),

Note that the same technique can be used by services, by exporting the home directory into their run script.

Referencing Linux User/Group

The Linux user/group under which the application is running can be referenced via:

  • Its ID, as indicated by the USER_ID/GROUP_ID environment variable.
  • By the user/group app. The app user/group is setup during the startup to match the configured USER_ID/GROUP_ID.

Using rootfs Directory

All files that need to be copied into the container should be stored in your source tree under the directory rootfs. The folder structure into this directory should reflect the structure inside the container. For example, the file /etc/cont-init.d/my-init.sh inside the container should be saved as rootfs/etc/cont-init.d/my-init.sh in your source tree.

This way, copying all the required files to the correct place into the container can be done with this single line in your Dockerfile:

COPY rootfs/ /

Maximizing Only the Main Window

By default, the application's window is maximized and decorations are hidden. When the application has multiple windows, this behavior may need to be restricted to only the main one.

The window manager can be configured to apply different behaviors for different windows of the application. A specific window is identified by matching one or more of its properties:

  • Name of the window.
  • Class of the window.
  • Title of the window.
  • Type of the window.
  • etc.

To find the value of a property for a particular window:

  • Create and start an instance of the container.
  • From the host, start the obxprop tool:
docker exec [container name or id] obxprop | grep "^_OB_APP"
  • Access the GUI of the application and click somewhere on the interested window.
  • Information about that window will be printed.

The following table shows how to find the relevant information:

Property Value
Name The window's _OB_APP_NAME property.
Class The window's _OB_APP_CLASS property.
Title The window's _OB_APP_TITLE property.
GroupName The window's _OB_APP_GROUP_NAME property.
GroupClass The window's _OB_APP_GROUP_CLASS property.
Type The window's _OB_APP_TYPE property. The type can be one of the following values: desktop, dialog, dock, menu, normal, notification, splash, toolbar, utility.
Role The window's _OB_APP_ROLE property.

By default, the window manager configuration matches only the type of the window, which must be normal. More restrictions can be added to better select the correct window.

To do this, matching criterias can be defined by adding a file located at /etc/openbox/main-window-selection.xml in the container. This file should have one matching critera per line, in XML format. For example, to match against both the type and the name of the window, the file content should be:

<Type>normal</Type>
<Name>My Application</Name>

NOTE: To maintain backward compatibility with previous 4.x versions, the container fallbacks to /etc/jwm/main-window-selection.jwmrc if /etc/openbox/main-window-selection.xml does not exist.

Adaptations from the 3.x Version

For existing applications using the previous version of the baseimage, few adaptations are needed when updating to the new baseimage. Here are a few tips:

  • Verify exposed environment variables: each of them should be categorized as a public or private one. See the Environment Variables section.
  • Initialization scripts should be renamed to have the proper naming format. See the Initialization Scripts section.
  • Parameters/definition of services should be adjusted for the new system. See the Services section.
  • Verify that no scripts are using with-contenv in their shebang (e.g. from init scripts).
  • Set the APP_VERSION and DOCKER_IMAGE_VERSION internal environment variables when/if needed.
  • Any adjustment to the window manager config (e.g. to maximize only the main window) should be adapted to use the new mechanism. See the Maximizing Only the Main Window section.

docker-baseimage-gui's People

Contributors

jlesage avatar thomashilzendegen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-baseimage-gui's Issues

Feature Request: Replace x11vnx and xvfb with TigerVNC to enable remote resize

It would be great to replace x11vnc and xvfb with TigerVNC. This would allow resizing of the remote desktop accordingly to resizing the browser window (perhaps best with disable option e.g. by setting the width and height explicitly).

I would like the help in the process if you want to.

Is there something that directly speaks against this idea? Perhaps you already tried and have good reasons not to use TigerVNC?

Best regards

Benedict

docker image tags

Hi,
So far I've been using the docker tags "jlesage/baseimage-gui:alpine-3.10" without the version number on the end, but with the new alpine-3.11 the available tags all have "v" "number" at the end. Just asking if that's your new standard going forward? No problem if so, I can update all my dockerfiles to comply with the new tags.
thanks

Favicons referenced using absolute paths

Favicons are referenced using absolute paths (i.e. /images/icons/...)

All other resources in /opt/novnc/index.vnc are referenced using relative paths (i.e. js/..., css/..., etc).

Referencing resources via absolute paths breaks the application when it is running behind a reverse proxy using path based routing (i.e. http://server/appname/ --> http://realserver/).

This issue is affecting the 'jlesage/docker-handbrake' project, but as the script that installs the favicons exists in this project (i.e. /usr/local/bin/install_app_icon.sh), I am filing the issue here.

CJK_FONT not installing on Debian10 images

On Debian this script fails https://raw.githubusercontent.com/jlesage/docker-baseimage-gui/master/rootfs/etc/cont-init.d/10-cjk-font.sh with the following error

[cont-init.d] 10-cjk-font.sh: executing...
[cont-init.d] 10-cjk-font.sh: installing CJK font...
[cont-init.d] 10-cjk-font.sh: Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
[cont-init.d] 10-cjk-font.sh: Get:2 http://deb.debian.org/debian buster InRelease [122 kB]
[cont-init.d] 10-cjk-font.sh: Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
[cont-init.d] 10-cjk-font.sh: Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [267 kB]
[cont-init.d] 10-cjk-font.sh: Get:5 http://dist.jriver.com/latest/mediacenter buster InRelease [3612 B]
[cont-init.d] 10-cjk-font.sh: Get:6 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB]
[cont-init.d] 10-cjk-font.sh: Get:7 http://deb.nodesource.com/node_12.x buster InRelease [4584 B]
[cont-init.d] 10-cjk-font.sh: Get:8 http://dist.jriver.com/latest/mediacenter buster/main armhf Packages [683 B]
[cont-init.d] 10-cjk-font.sh: Get:9 http://dist.jriver.com/latest/mediacenter buster/main i386 Packages [707 B]
[cont-init.d] 10-cjk-font.sh: Get:10 http://dist.jriver.com/latest/mediacenter buster/main amd64 Packages [677 B]
[cont-init.d] 10-cjk-font.sh: Get:11 http://dist.jriver.com/latest/mediacenter buster/main arm64 Packages [644 B]
[cont-init.d] 10-cjk-font.sh: Get:12 http://deb.debian.org/debian buster-updates/main amd64 Packages [9504 B]
[cont-init.d] 10-cjk-font.sh: Get:13 http://deb.nodesource.com/node_12.x buster/main amd64 Packages [767 B]
[cont-init.d] 10-cjk-font.sh: Fetched 8434 kB in 2s (4919 kB/s)
[cont-init.d] 10-cjk-font.sh: Reading package lists...
[cont-init.d] 10-cjk-font.sh: Reading package lists...
[cont-init.d] 10-cjk-font.sh: Building dependency tree...
[cont-init.d] 10-cjk-font.sh: Reading state information...
[cont-init.d] 10-cjk-font.sh: The following NEW packages will be installed:
[cont-init.d] 10-cjk-font.sh:   fonts-wqy-zenhei
[cont-init.d] 10-cjk-font.sh: 0 upgraded, 1 newly installed, 0 to remove and 40 not upgraded.
[cont-init.d] 10-cjk-font.sh: Need to get 7472 kB of archives.
[cont-init.d] 10-cjk-font.sh: After this operation, 16.8 MB of additional disk space will be used.
[cont-init.d] 10-cjk-font.sh: Get:1 http://deb.debian.org/debian buster/main amd64 fonts-wqy-zenhei all 0.9.45-7 [7472 kB]
[cont-init.d] 10-cjk-font.sh: debconf: delaying package configuration, since apt-utils is not installed
[cont-init.d] 10-cjk-font.sh: Fetched 7472 kB in 1s (11.1 MB/s)
[cont-init.d] 10-cjk-font.sh: dpkg: unrecoverable fatal error, aborting:
[cont-init.d] 10-cjk-font.sh:  unknown system group 'messagebus' in statoverride file; the system group got removed
[cont-init.d] 10-cjk-font.sh: before the override, which is most probably a packaging bug, to recover you
[cont-init.d] 10-cjk-font.sh: can remove the override manually with dpkg-statoverride
[cont-init.d] 10-cjk-font.sh: E: Sub-process /usr/bin/dpkg returned an error code (2)
[cont-init.d] 10-cjk-font.sh: exited 0.

Removing this line root messagebus 4754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper in /var/lib/dpkg/statoverride fixes this.

Modified 10-cjk-font.sh

#!/usr/bin/with-contenv sh

set -e # Exit immediately if a command exits with a non-zero status.
set -u # Treat unset variables as an error.

log() {
    echo "[cont-init.d] $(basename $0): $*"
}

if [ "${ENABLE_CJK_FONT:-0}" -eq 1 ]; then
    if fc-list | grep -q "WenQuanYi Zen Hei"; then
        log "CJK font already installed."
    else
        log "installing CJK font..."
        if [ -n "$(which apk)" ]; then
            add-pkg wqy-zenhei --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing 2>&1 | sed "s/^/[cont-init.d] $(basename $0): /"
        else
            sed -i /messagebus/d /var/lib/dpkg/statoverride
            add-pkg fonts-wqy-zenhei 2>&1 | sed "s/^/[cont-init.d] $(basename $0): /"
        fi
    fi
fi

# vim: set ft=sh :

Add support for running with x11docker?

Hi! I've tried to run your example, replacing xterm with glxspeheres64 (the installed correctly from edge/testing repo of alpine) via x11docker.

Tested with a lot of different options but I got all the time this error:

/bin/sh: -c requires an argument

Do you have any idea why is this? Thanks.

Enable dark mode for apps

Enable dark mode of linux in order to get the QT dark mode, and apps like mkvcleaver, mkvtoolnix, handbrake could trigger automatically dark mode.

Update Documentation to Specify Remote Presence Port Requirement

The documentation specifies the ports you can use to access the web interface and the VNC server for the container, but I do not see anything that references the Remote Presence Port is that the container uses when it connects to connect to iDRAC 6.

You can see this value when you log into the iDRAC admin console and navigate to System -> Console/Media -> Configuration.

I changed the Remote Presence Port on my iDRAC6 controller in my Dell R410 Server to port 4900. I forget why I did it - it was a long time ago. The default value is 5900 per Dell's documentation.

Since the Remote Presence Port value is not exposed in your Docker container, when you try to connect via the container, the connection fails.

I changed the Remote Presence Port in iDRAC6 from 4900 back to the default 5900, and I was able to connect using the Docker container!!! This is AWESOME!

Great job! Please update the docs to reflect this as it's pretty important.

Enable toggling of direct VNC server access.

By default, both ports 5800 and 5900 are exposed in the container. It would be fantastic to be able to add the option toggle the following port exposures:

  • 5800 (VNC web GUI only)
  • 5900 (VNC server only)
  • 5800-5900 (both VNC web GUI, VNC server; current mode)

This would enable the selection of the preferred connection for an end user and minimize service exposure in the container.

Prevent minimize for very customized non-standard UIs

I´m currently trying to base a JRiver Media Center 25 container off your image. It´s already kind of working, but when you click minimize you have no way to get it back, other than restarting the container.

If you´re interested I have made the repo public on my gitlab right now https://gitlab.shio.at/max/jrivermc25-docker

Would be glad for any suggestions on how to achieve this, or wether or not you had to deal with this before. It works fine with guis that use standard window decorations. They go away. But for this one it neigher will go fullscreen on start, nor will it remove the mimize actions.

I don´t really expect any help necessarily. But if you already know, I´d appreaciate it nevetheless. Otherwise, I´ll keep digging this weekend (or after) and report back if I happened to solve it eventually.

Unable to build MTPlayer docker container

Hello,

I'm using your JDownloader docker container a while and I'm happy. Now I tried to implement my own container based on your baseimage to run MTPlayer, Java-File.

The dockerfile loads jlesage/baseimage-gui:alpine-3.9-glibc-v3.5.2, install openjdk11, download MTPlayer and try to start MTPlayer:

`
FROM jlesage/baseimage-gui:alpine-3.9-glibc-v3.5.2

ARG DOCKER_IMAGE_VERSION=unknown

ARG MTPLAYER_URL=https://www.p2tools.de/extra/download/MTPlayer-9.zip

WORKDIR /tmp

RUN \
    add-pkg --virtual build-dependencies curl p7zip && \
    curl -# -L -o MTPlayer-9.zip ${MTPLAYER_URL} && \
    7za x MTPlayer-9.zip && \
    del-pkg build-dependencies

RUN \
    apk --no-cache add openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community
    
COPY rootfs/ /

WORKDIR /tmp/MTPlayer

ENV APP_NAME="MTPlayer" \
    S6_KILL_GRACETIME=8000

VOLUME ["/config"]
VOLUME ["/output"]`

I know there is a lot of optimization (e.g. volumes), but I tried first to run the app and after I will make it nice.

In rootfs there is a file called startapp.sh with the following lines:

#!/bin/sh
java -Djava.awt.headless=false -jar ./MTPlayer.jar "$@"

I build the image with docker build -t mtplayer . and the build-process-output looks fine. When I try to start the container with

docker run -it -p 5800:5800 mtplayer

I get the following error:

[12:59:59] INFO:         Proxy Authentication: not configured
Exception in thread "main" java.lang.UnsupportedOperationException: Unable to open DISPLAY
        at com.sun.glass.ui.gtk.GtkApplication.lambda$new$6(GtkApplication.java:173)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:171)
        at com.sun.glass.ui.gtk.GtkPlatformFactory.createApplication(GtkPlatformFactory.java:41)
        at com.sun.glass.ui.Application.run(Application.java:144)
        at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:258)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:269)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
        at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:834)

Any idea how I can solve this please?

Carsten

IP 192.168.0.1 used by host?

I can run container fine and install & run chrome normally. But when I try to navigate to our LAN server (located in 192.168.0.1) connection is rejected. A NMAP scan from inside the the container shows dns is correctly result but that ip redirects to local instead of remote machine:

# nmap 192.168.0.1        

Starting Nmap 7.40 ( https://nmap.org ) at 2018-08-27 09:19 UTC
Nmap scan report for xxxxxxxxxx.xxxxxxxxx.local (192.168.0.1)
Host is up (0.000036s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
111/tcp  open  rpcbind
5800/tcp open  vnc-http
5900/tcp open  vnc

Which service is taking the 192.168.0.1 ip? Ifconfig doesn't show any device

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 54140  bytes 42405776 (40.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 46411  bytes 13510655 (12.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1  (Local Loopback)
        RX packets 71085  bytes 13893319 (13.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 71085  bytes 13893319 (13.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

GUI Dark background

Make the background of the GUI in dark mode (not talking about the apps inside, but just the white background in a black or dark grey background.)

Update VNC source

Hello,

Thanks for these great containers.
Is it possible that you can update
libvncserver
x11vnc
novnc

These were forked in 2017 and I am pretty sure there are many improvements till now. It would be great if you could upgrade these.

Ubuntu focal

Hello! Thank you for your nice work!

Could you, please, extend it to ubuntu: focal? I tried to do it on my own, but I got confused.

Environment variables not sticking after container launch

Hey @jlesage I am using your base image for a build of mine. Dockerfile below. Basically, it launches an instance of Thunderbird, which gives me the accessibility of webmail and the features of a desktop client. As Thunderbird profiles are launched from home directories, I mapped /config/app to a host directory containing the profile/settings. To test, I launched the container, with xterm as the startapp, set the home env with HOME=/config/app, and then proceeded to successfully launch thunderbird with thunderbird. With the test being successful, the last step is then to set the home directory for the user app (uid 1000) to /config/app within the dockerfile: ENV HOME="/config/app"

FROM jlesage/baseimage-gui:debian-10
RUN apt update && \
  apt upgrade -y && \
  apt install -y thunderbird

#Debugging purposes
Run apt install htop xterm -y
COPY startapp.sh /startapp.sh
ENV APP_NAME="Thunderbird"
ENV HOME="/cofig/app/"

However, upon logging into xterm as user app, HOME remains empty:
Screen Shot 2021-04-23 at 2 55 05 PM

Can you tell me how/why this ENV isn't sticking or is getting overwritten? Thanks!

PS Love your work. Keep it up!

Changing port from Environment Variables

As other tools from jlesage, it should be great to change the port from the Environment Variables.
I am using Docker inside of Synology DSM and is hard to do some configuration unless are exposed as variables.
I am using more applications from jlesage and I can't use them at the same time due to having the same port 5800 (like jdownloader) unless mapping ports, which I would like to avoid (although I know is possible).

ARM64 Build

Hello,

is there any plan to create ARM64v8 images of this project?.

They are only amd64 as far as I've seen and it would be useful for all of us having Raspberry Pi 4 (or clusters of it).

Thank you!

Update images to Alpine 3.10

Hi!! First of all thank you for this awesome image. I use it for various applications and it would be awesome if you can update it to Alpine 3.10 :)

Thank you!

Provide mechanism for custom fonts on startup.

It would be great to enable the use of loading custom fonts when the image is stared. My thought is something like this:

  • Load font files in a unique namespace in the config mountpoint: /config/baseimage/fonts
  • Setup an environment variable that will trigger loading if enabled, e.g. ENABLE_CUSTOM_FONTS=1
  • On container start, the startup script checks the environment variable, and runs a font cache update: fc-cache -f -v -y /config/baseimage/fonts

This would enable end user custom fonts to be install simply by placing them in the correct location, ensuring it is enabled and restarting the docker container.

new environment variable for port number

The default port is set to 5800 for all your docker images and the default cannot be changed. For containers on my normal docker network this is fine since I can remap the ports in the compose file, but if I use a VPN docker network then all containers share the same network interface as the vpn client container.

For instance, the vpn client docker compose file would look something like this:
vpn_client:
image: dperson/openvpn-client
ports:
#ports for app containers' UI to be reachable from local network
#firefox
- "5801:5800"
#jdownloader
#- "5802:5800"
.... etc

and then your docker containers would have in their compose section:
network_mode: "service:vpn_client"

Since all your docker images share 5800 as the default port, I can't use more than one of them on my VPN docker network. Please add an environment variable to the base-image to change the default port number to allow cases like this.

The system shuts down right after the start

I am using Docker (Version 2.0.0.0-win81 (29211)) on Windows 10. Following exactly your example "Getting started" provided in README.md, I got the following log, mentioning "s6-applyuidgid: fatal: unable to exec /startapp.sh: No such file or directory":

C:\Users\Sofke\Desktop\dockerGui>docker build -t docker-xterm .
Sending build context to Docker daemon 5.12kB
Step 1/4 : FROM jlesage/baseimage-gui:alpine-3.6
---> 03c81ba1677f
Step 2/4 : RUN add-pkg xterm
---> Using cache
---> b8433a4f4a96
Step 3/4 : COPY startapp.sh /startapp.sh
---> 3ba17dfd408f
Step 4/4 : ENV APP_NAME="Xterm"
---> Running in c3d4798cc140
Removing intermediate container c3d4798cc140
---> 37268c153245
Successfully built 37268c153245
Successfully tagged docker-xterm:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

C:\Users\Sofke\Desktop\dockerGui>docker run --rm -p 5800:5800 -p 5900:5900 docker-xterm
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 00-app-niceness.sh: executing...
[cont-init.d] 00-app-niceness.sh: exited 0.
[cont-init.d] 00-app-script.sh: executing...
[cont-init.d] 00-app-script.sh: exited 0.
[cont-init.d] 00-app-user-map.sh: executing...
[cont-init.d] 00-app-user-map.sh: exited 0.
[cont-init.d] 00-clean-logmonitor-states.sh: executing...
[cont-init.d] 00-clean-logmonitor-states.sh: exited 0.
[cont-init.d] 00-clean-tmp-dir.sh: executing...
[cont-init.d] 00-clean-tmp-dir.sh: exited 0.
[cont-init.d] 00-set-app-deps.sh: executing...
[cont-init.d] 00-set-app-deps.sh: exited 0.
[cont-init.d] 00-set-home.sh: executing...
[cont-init.d] 00-set-home.sh: exited 0.
[cont-init.d] 00-take-config-ownership.sh: executing...
[cont-init.d] 00-take-config-ownership.sh: exited 0.
[cont-init.d] 00-xdg-runtime-dir.sh: executing...
[cont-init.d] 00-xdg-runtime-dir.sh: exited 0.
[cont-init.d] 10-certs.sh: executing...
[cont-init.d] 10-certs.sh: exited 0.
[cont-init.d] 10-cjk-font.sh: executing...
[cont-init.d] 10-cjk-font.sh: exited 0.
[cont-init.d] 10-nginx.sh: executing...
[cont-init.d] 10-nginx.sh: exited 0.
[cont-init.d] 10-vnc-password.sh: executing...
[cont-init.d] 10-vnc-password.sh: exited 0.
[cont-init.d] 10-web-index.sh: executing...
[cont-init.d] 10-web-index.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] starting s6-fdholderd...
[services.d] starting xvfb...
[xvfb] starting...
[services.d] starting openbox...
[openbox] starting...
Openbox-Message: Openbox was compiled without image loading support. Icons in menus will not be loaded.
[services.d] starting certsmonitor...
[services.d] starting logmonitor...
[services.d] starting nginx...
[logmonitor] no file to monitor: disabling service...
[certsmonitor] disabling service: secure connection not enabled.
[services.d] starting statusmonitor...
[nginx] starting...
[services.d] starting x11vnc...
[statusmonitor] no file to monitor: disabling service...
[x11vnc] starting...
[services.d] starting app...
14/12/2018 20:36:41 passing arg to libvncserver: -rfbport
14/12/2018 20:36:41 passing arg to libvncserver: 5900
14/12/2018 20:36:41 passing arg to libvncserver: -rfbportv6
14/12/2018 20:36:41 passing arg to libvncserver: -1
14/12/2018 20:36:41 passing arg to libvncserver: -httpportv6
14/12/2018 20:36:41 passing arg to libvncserver: -1
14/12/2018 20:36:41 passing arg to libvncserver: -desktop
14/12/2018 20:36:41 passing arg to libvncserver: Xterm
[app] starting Xterm...
14/12/2018 20:36:41 x11vnc version: 0.9.14 lastmod: 2015-11-14 pid: 749
s6-applyuidgid: fatal: unable to exec /startapp.sh: No such file or directory
14/12/2018 20:36:41 Using X display :0
14/12/2018 20:36:41 rootwin: 0x43 reswin: 0x400001 dpy: 0x35eea00
14/12/2018 20:36:41
14/12/2018 20:36:41 ------------------ USEFUL INFORMATION ------------------
[services.d] done.
14/12/2018 20:36:41 X DAMAGE available on display, using it for polling hints.
14/12/2018 20:36:41 To disable this behavior use: '-noxdamage'
14/12/2018 20:36:41
14/12/2018 20:36:41 Most compositing window managers like 'compiz' or 'beryl'
14/12/2018 20:36:41 cause X DAMAGE to fail, and so you may not see any screen
14/12/2018 20:36:41 updates via VNC. Either disable 'compiz' (recommended) or
14/12/2018 20:36:41 supply the x11vnc '-noxdamage' command line option.
14/12/2018 20:36:41 X COMPOSITE available on display, using it for window polling.
14/12/2018 20:36:41 To disable this behavior use: '-noxcomposite'
14/12/2018 20:36:41
14/12/2018 20:36:41 Wireframing: -wireframe mode is in effect for window moves.
14/12/2018 20:36:41 If this yields undesired behavior (poor response, painting
14/12/2018 20:36:41 errors, etc) it may be disabled:
14/12/2018 20:36:41 - use '-nowf' to disable wireframing completely.
14/12/2018 20:36:41 - use '-nowcr' to disable the Copy Rectangle after the
14/12/2018 20:36:41 moved window is released in the new position.
14/12/2018 20:36:41 Also see the -help entry for tuning parameters.
14/12/2018 20:36:41 You can press 3 Alt_L's (Left "Alt" key) in a row to
14/12/2018 20:36:41 repaint the screen, also see the -fixscreen option for
14/12/2018 20:36:41 periodic repaints.
14/12/2018 20:36:41 GrabServer control via XTEST.
14/12/2018 20:36:41
14/12/2018 20:36:41 Scroll Detection: -scrollcopyrect mode is in effect to
14/12/2018 20:36:41 use RECORD extension to try to detect scrolling windows
14/12/2018 20:36:41 (induced by either user keystroke or mouse input).
14/12/2018 20:36:41 If this yields undesired behavior (poor response, painting
14/12/2018 20:36:41 errors, etc) it may be disabled via: '-noscr'
14/12/2018 20:36:41 Also see the -help entry for tuning parameters.
14/12/2018 20:36:41 You can press 3 Alt_L's (Left "Alt" key) in a row to
14/12/2018 20:36:41 repaint the screen, also see the -fixscreen option for
14/12/2018 20:36:41 periodic repaints.
14/12/2018 20:36:41
14/12/2018 20:36:41 XKEYBOARD: number of keysyms per keycode 7 is greater
14/12/2018 20:36:41 than 4 and 51 keysyms are mapped above 4.
14/12/2018 20:36:41 Automatically switching to -xkb mode.
14/12/2018 20:36:41 If this makes the key mapping worse you can
14/12/2018 20:36:41 disable it with the "-noxkb" option.
14/12/2018 20:36:41 Also, remember "-remap DEAD" for accenting characters.
14/12/2018 20:36:41
14/12/2018 20:36:41 X FBPM extension not supported.
14/12/2018 20:36:41 X display is not capable of DPMS.
14/12/2018 20:36:41 --------------------------------------------------------
14/12/2018 20:36:41
14/12/2018 20:36:41 Default visual ID: 0x21
[services.d] stopping services
14/12/2018 20:36:41 Read initial data from X display into framebuffer.
14/12/2018 20:36:41 initialize_screen: fb_depth/fb_bpp/fb_Bpl 24/32/5120
14/12/2018 20:36:41
14/12/2018 20:36:41 X display :0 is 32bpp depth=24 true color
14/12/2018 20:36:41
14/12/2018 20:36:41 Listening for VNC connections on TCP port 5900
14/12/2018 20:36:41
14/12/2018 20:36:41 Xinerama is present and active (e.g. multi-head).
14/12/2018 20:36:41 Xinerama: number of sub-screens: 1
14/12/2018 20:36:41 Xinerama: no blackouts needed (only one sub-screen)
14/12/2018 20:36:41
14/12/2018 20:36:41 fb read rate: 1851 MB/sec
14/12/2018 20:36:41 fast read: reset -wait ms to: 10
14/12/2018 20:36:41 fast read: reset -defer ms to: 10
14/12/2018 20:36:41 The X server says there are 10 mouse buttons.
14/12/2018 20:36:41 screen setup finished.
14/12/2018 20:36:41

The VNC desktop is: 94c38ecbd105:0
PORT=5900


Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?

The scheme stores pixel data offscreen on the VNC viewer side for faster
retrieval. It should work with any VNC viewer. Try it by running:

x11vnc -ncache 10 ...

One can also add -ncache_cr for smooth 'copyrect' window motion.
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching

[services.d] stopping app...
[services.d] stopping x11vnc...
caught signal: 15
14/12/2018 20:36:41 deleted 40 tile_row polling images.
[services.d] stopping statusmonitor...
[services.d] stopping nginx...
[services.d] stopping logmonitor...
[services.d] stopping certsmonitor...
[services.d] stopping openbox...
[services.d] stopping xvfb...
[services.d] stopping s6-fdholderd...
[cont-finish.d] executing container finish scripts...
[cont-finish.d] done.
[s6-finish] syncing disks.
[s6-finish] sending all processes the TERM signal.
[s6-finish] sending all processes the KILL signal and exiting.

/dev/sr0 permissions

Hi,

I'm trying to correct an issue I've got using this image as a base for a piece of software called dvdisaster. I've managed to get all the build working but I'm struggling with the permissions to /dev/sr0. On the docker host my user with id 1000 is a member of the cdrom group which has rw on /dev/sr0 on my host but the app user inside the container isn't able to access sr0 from my host.

I have then docker exec'd into the container and done usermod -aG cdrom app and reloaded the app and it's then able to access /dev/sr0. I've tried adding the usermod to my Dockerfile but I think this user is made on container start.

Any tips?

Thanks,
b3vis

P.S I tried to look through your MakeMKV container to see how you've solved this on that image but was unable to see anything obvious

Unable to access JRiver docker via web

I set up JRiver docker on a QNAP running QTS 4.4.3 vith a VNS set up for more security. If I use a web interface I get a JRiver screen but a red X at the top to the right of JRiver. When I look at the QNAP Container station it shows an app withthe directory/User I used for the config with JRiverMC26 under that when I expand it. When I look at the run informtion it appears to be taking a number of errors.

I'll send you the run info if you can tell me how to attach it. It's in a TBZ file type and it doesn't look like my PC will handle converting/expanding that.

Full Desktop

Hi

Is there a way to run a full desktop , with this ?

Basically I have an app that calls a web browser for authentication purposes

Any help is appreciated

Thanks

Fails to rebuild baseimage-gui:ubuntu-16.0.4

I tried to build a baseimage-gui for ubuntu 14.04 to be able to use Ivideon with gui on my synology NAS.
(it does not work on ubuntu 16.04)

Not succeeding I went to try to rebuild the baseimage-gui:ubuntu-16.04-v3.3.5
I followed the full build process basimage ./build.sh ubuntu-16.04 then baseimage-gui idem

  • in baseimage build curl curl no URL (idem for basimage-gui) (docker version 17.0.5.0-ce)
    solved transforming ARG xxx_URL in ENV xxx_URL
  • bats not available (I don't know how to install it on Synoloy)
  • basimage-16.0.4 finally built. It seems working I tried to build the xterm exemple. It stopped because of no display, but seems to work correctly

Then build of baseimage-gui

  • I also had to to change a few ARG in ENV
  • I have a lot of build errors
    • a few of these
      "invoke-rc.d: policy-rc.d denied execution of start."
    • and of these
      "npm WARN enoent ENOENT: no such file or directory, open '/tmp/package.json'
      npm WARN tmp No description
      npm WARN tmp No repository field.
      npm WARN tmp No README data
      npm WARN tmp No license field."

At the end an image is build but when I use it (xterm exemple) it doesn't work (docker build OK) and docker run start and immediately stop with the following logs

docker logs xterm

ifelse: fatal: unable to exec /etc/s6/init-no-catchall/init-stage1: Permission denied
ifelse: fatal: unable to exec /etc/s6/init-no-catchall/init-stage1: Permission denied

Could you help me debbug.
What is different in your building process ?

x86 Version

Hi,
I need to run WinScp on the container using wine. as for now WinScp is x86 based and can't be running
with .x64 wine.
Cheers

Running multiple containers access via vnc is not possible

Thank you for your good and easy to customize base image with a nice gui
I use your base image and customized it with running custom code now i have following problem
when i run more then 1 replicas on my vm in swarm mode
i can just access the latest created replica via http://hostdns:5800

i cannot use a port range in my docker compose file as its not allowed in swarm mode
currently my stack looks like that
version: '3' services: worker: image: vnc-docker:1.0 shm_size: 2g privileged: true volumes: - /home/username/firefox:/config:rw ports: - 5800:5800 deploy: mode: replicated replicas: 1 update_config: parallelism: 1 delay: 10s restart_policy: condition: any

i tried different things out, like creating a custom network and use it

something like
ports: - 5800-5900:5800
does not work
i just found out now that there is something like mcvlan, but i just couldn't figure out how to create a macvlan network and use it in my compose?

/dev/null access

Trying to run an app using jlesage/baseimage-gui:debian-10. Its trying to write to /dev/null. It doesn't seem to be able to create a temporary file. Any suggestions. I tried running the container under privileged mode that doesn't seem to help.

Failed to work with gitkraken

Dockerfile:

FROM jlesage/baseimage-gui:debian-10

# Install gitkraken.
RUN apt update \
    && apt install -y wget \
    && wget https://release.gitkraken.com/linux/gitkraken-amd64.deb  -P /tmp \
    && apt remove -y wget \
    && apt install -y gconf2 gconf-service libgtk2.0-0 libnotify4 libnss3 gvfs-bin xdg-utils libxss1 libasound2 procps\
    && dpkg -i /tmp/gitkraken-amd64.deb \
    && rm -rf /var/cache/apt /tmp/gitkraken-amd64.deb

# Copy the start script.
COPY startapp.sh /startapp.sh

# Set the name of the application.
ENV APP_NAME="GitKraken"

startapp.sh

#!/bin/sh
exec /usr/bin/gitkraken

docker run --rm -p 5800:5800 -p 5900:5900 gitkraken
Result:

[services.d] starting statusmonitor...
[services.d] starting logmonitor...
[statusmonitor] no file to monitor: disabling service...
[services.d] starting app...
[logmonitor] no file to monitor: disabling service...
[app] starting GitKraken...
[services.d] done.
**Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted**
[services.d] stopping services
[services.d] stopping app...
[services.d] stopping logmonitor...
[services.d] stopping statusmonitor...
[services.d] stopping openbox...
[services.d] stopping certsmonitor...
[services.d] stopping nginx...
[services.d] stopping x11vnc...
caught signal: 15
20/08/2020 14:30:59 deleted 40 tile_row polling images.
[services.d] stopping xvfb...
[services.d] stopping s6-fdholderd...
[cont-finish.d] executing container finish scripts...
[cont-finish.d] done.
[s6-finish] syncing disks.
[s6-finish] sending all processes the TERM signal.
[s6-finish] sending all processes the KILL signal and exiting.

Any hint?

JS errors when pasting a lot of data using the clipboard

When using the clipboard and submitting a lot of data, a loop of JavaScript errors happen.

From a user perspective, the clipboard submit does't work and the interface doesn't seem to be responsive. A refresh of the page is needed.

fail to rebuild base image from Dockerfiles

Hi,
I'm trying to rebuild a base image from Dockerfile.debian
It fails because of unknown commands: add-pkg, del-pkg, sed-patch and install-icon...
same for Dockerfile.alpine.

I must have missed something...
Thans for your comments

running java application does not work

Hey, I'm trying to run Nitro Explorer 3 inside this container. The container always exits immediately throwing the error:

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
        no swt-gtk-4335 in java.library.path
        no swt-gtk in java.library.path
        Can't load library: /dev/null/libswt-gtk-4335-64.so
        Can't load library: /dev/null/libswt-gtk-64.so

        at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
        at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
        at org.eclipse.swt.internal.C.<clinit>(Unknown Source)
        at org.eclipse.swt.internal.Converter.wcsToMbcs(Unknown Source)
        at org.eclipse.swt.internal.Converter.wcsToMbcs(Unknown Source)
        at org.eclipse.swt.widgets.Display.<clinit>(Unknown Source)
        at gui.MainWindow.open(MainWindow.java:65)
        at gui.MainWindow.main(MainWindow.java:55)
        ... 5 more

I have tried alpine, debian and ubuntu, i always get this message.

My basic approach is this:
Inside the Dockerfile

  1. I copy the .jar file to the /opt/nitro/ directory
  2. Install java
  3. Copy startapp.sh to /

Inside the startapp.sh:
/usr/bin/java -jar /opt/nitro/myapp.jar

A lot of hours have gone into this and I don't know what I could possibly do to make this work.
If you could assist me, that would be awesome.

Thanks!

enable clipboard

Is there a way to enable clipboard at the image? I want to paste into the application and copy from the application running in the container

QXcbConnection: Could not connect to display :0

Trying to create a Calibre docker based on this image, keep getting this error:
QXcbConnection: Could not connect to display :0

Dockerfile:

FROM jlesage/baseimage-gui:ubuntu-16.04

RUN apt-get update && \
apt-get install -y  python wget xz-utils xdg-utils locales

RUN wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin

ENV LANG=en_US.UTF-8
RUN locale-gen en_US.UTF-8

# Copy the start script.
COPY startapp.sh /startapp.sh

# Set the name of the application.
ENV APP_NAME="Calibre"

startapp just contains a call to start calibre from /opt/calibre/ . Any insight appreciated.

Container immediately exits

Hey, I want to run a wine application with this docker image. But when i start the container, it exits immediately.

This is my Dockerfile:

FROM jlesage/baseimage-gui:debian-9
RUN \
        dpkg --add-architecture i386 && \
        apt update && \
        apt install -y  \
                        mono-complete \
                        wget \
                        wine 
                        
COPY startapp.sh /startapp.sh
COPY ./randomwindowsapp /app
ENV APP_NAME="Crystaltile2"

This is my startapp.sh:

#!/bin/sh
/usr/bin/wine /app/randomwindowsapp.exe

Do you know what im doing wrong here?
Thanks!

[enhancment][help wanted] Use with VSCode Dev Container

I'm trying to use this brilliant image with VSCode Dev Container and I fail miserably. Seems to be some issue with the VSCode sleep command to keep workspace open and the startapp.sh functionality. As a workaround I have been trying to let this image sleep and wait for connection to x server over tcp by adding '-listen tcp -ac' to the Xvfb startup, and have my program connect from another container. However getting this working seems to be above my level of understanding :( Any ideas?

Can't make the container to use NVIDIA GPU

Hi,

I have been trying to use this amazing container to run GPU applications. So far I have not ben able to do so.
I created a new container (I addedd the recipies that creates this container https://gitlab.com/nvidia/samples/blob/master/opengl/ubuntu16.04/turbovnc-virtualgl/Dockerfile )
I have tried everything, and even when I am able to run virtualgl with no problem and that the NVIDIA drivers ar eproperly configured (you can run nvidia-smi inside the container) the container doesn't use the GPU.
I reviewed your code and tried to make sense of it but I can't find the missing link. Have you run any application GPU capable with this recipie?
It would be really nice to have something like that .

archlinux dist

Hello and thank-you for your work.
What do you think about add archlinux to your list of distribututions?

Thanks

Any chance of a version of this based off the ubuntu nvidia docker images?

It would be super useful for a image for this based against the nvidia docker images potentially to accelerate rendering if GPUs are available or as in my case in order to use CUDA to accelerate the program I am running.

This would potentially be extremely useful for people if they wanted to run things like Handbrake as it would enable accelerated transcoding using the nvidia runtime for docker.

At the moment I am tinkering with this to see if I can get it working, but you'd be a lot more familiar with your image!

Rebuilding Baseimage: no encryption library could be found

I´m trying to rebuild the baseimage for debian9 (arm) and debian10 (amd64 & arm) also did debian9 amd64 now. SSL does not work for VNC. I´m getting this error somewhere in the logs

==========================================================================
*** No encryption library could be found. ***
A libvncserver/libvncclient built this way will not support SSL encryption.
To enable SSL install the necessary development packages (perhaps it is named
something like libssl-dev or gnutls-dev) and run configure again.
==========================================================================

The test for it is also failing


Checking availability of VNC SSL port 5900...
   (in test file tests/test_secure_port_availability.bats, line 33)
     `(( TIMEOUT > 0 ))' failed
   Starting docker container...
   Stopping docker container...
   1fc896a668cd3a6b6b03e701372aa876debf76b19a417e622c2b64a36099e7d7
   Removing docker container...
   1fc896a668cd3a6b6b03e701372aa876debf76b19a417e622c2b64a36099e7d7

Are you getting the same error, or am I doing something wrong?

Problem with Qt application

Hi @jlesage !

I have a problem building my rclonebrowser image, the application only runs on first execution, and since the restart of the container, I only get a black screen. Did you notice problems with Qt applications? Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.