Crear contenedor Docker aplicación GUI - EALite#

Dando continuidad al uso de contenedores que inicie en la publicación anterior, Crear contenedor LXC para aplicación GUI - EALite, reproduciré la instalación de Enterprise Architect Viewer (EALite) con Docker (y por supuesto, Wine). Si deseas reproducir el ejemplo de este caso, requieres reproducir la el artículo mencionado para extraer el directorio de Wine.

A diferencia de LXC, Docker está más orientado al aislamiento de aplicaciones y no de sistema operativo (LXC cumple una función más cercana a una máquina virtual) lo cual ayuda a un mejor despliegue de aplicaciones y la estandarización de las etapas de desarrollo y de pruebas.

Común a LXC tenemos imágenes base que podemos usar, disponibles en DockerHub. A partir de estas podemos completar nuestras necesidades especificando en el archivo Dockerfile.

Instalar Docker#

Recomiendo en Linux instalar docker con snap.

sudo snap install docker

Posteriormente, podemos asociar nuestro usuario para la ejecución sin ser administrador.

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

Puedes probar ejecutando como usuario regular, docker run hello-world.

Dockerfile#

Este archivo es el mecanismo mediante el cual se especifican las reglas de construcción de nuestra imagen. Se define un lenguaje común sin importar el sistema operativo base y las funciones específicas del sistema son usadas con una instrucción que habilita a ejecución en él.

Los comentarios en el archivo son como tradicionalmente estamos acostumbrados en otros lenguajes (entre ellos, bash), con signo número #. Esto posee una excepción, y es el caso donde existe una directriz después como el caso que se ejemplificara.

La directriz escape es usada para cambiar el carácter de salto de línea para instrucciones de múltiples líneas. Se puede tener la habitual barra invertida (\) que es conflictivo con rutas con espacios en Linux o rutas Windows, y la opción de la tilde invertida (`).

Después podemos definir la imagen base usando FROM seguido de la especificación de la imagen en DockerHub. En este caso, usaremos la imagen Docker de Ubuntu con arquitectura i386 y versión 18.04. En general, la estructura de invocación es arquitectura/ubuntu:version.

Las instrucciones son ejecutadas por defecto por el usuario root (administrador), de manera que podemos ejecutar la instalación de paquetes invocando directamente el llamado al sistema iniciando con RUN. Como se observa en el ejemplo, a continuación es una línea típica que se ejecuta en Ubuntu.

Nota

La creación del usuario es necesaria porque wine debe ejecutarse por un usuario regular. Adicional, el nombre de usuario corresponde al mismo nombre del usuario Linux del cual traemos la copia de la instalación en Wine (Wine asigna el nombre de usuario Windows igual al usuario Linux, luego, al copiar la carpeta de Wine, solo funcionará si encuentra el mismo usuario).

Podemos cambiar el directorio sobre el cual ejecutamos usando WORKDIR. En la siguiente línea usamos COPY para mover un directorio del sistema hospedador a la imagen. Existe una instrucción similar, ADD, la cual soporta que la fuente sea una URL realizando la descarga, y descomprime archivos tar.

Nota

El directorio que moveremos se genero en el contenedor LXC que construimos en Crear contenedor LXC para aplicación GUI - EALite. Para ello, iniciamos el contenedor y extraemos el directorio.

sudo lxc start ea
sudo lxc file pull -r ea/home/ubuntu/.wine .

Con USER cambiamos el usuario que ejecuta los procesos. Es importante que a la hora de concluir, si un proceso es ejecutado por un usuario regular, nuestro último cambio de usuario debe apuntar a él, de otra forma el contenedor estará activo para el usuario administrador. Otro aspecto importante es el comportamiento por defecto en Linux, donde puede crear el usuario si no existe (pero no el directorio de usuario).

Finalmente, es necesario indicar que se ejecuta cuando se lanza el contenedor. Esto es posible con CMD o con ENTRYPOINT. La diferencia es que el primero permite sobreescribir la ejecución enviando como parámetro lo que se desea ejecutar, mientras que la segunda opción solo ejecuta la configurada.

# escape=`
FROM i386/ubuntu:18.04
RUN apt update -q && apt install --install-recommends -y wine-stable
RUN apt install -y fonts-crosextra-carlito
RUN useradd -ms /bin/bash ubuntu
WORKDIR /home/ubuntu
COPY .wine .wine
RUN chown -R ubuntu .wine
USER ubuntu
RUN mkdir -p .local/bin && `
        echo "wine $HOME/.wine/drive_c/Program\ Files/Sparx\ Systems/EA\ LITE/EA.exe" > .local/bin/ealite && `
        chmod 755 .local/bin/ealite
CMD ".local/bin/ealite"

Construir imagen Docker#

La construcción la realizamos con la opción build. Se usa el argumento -t para indicar la etiqueta que asignaremos a la imagen y -f para relacionar la ruta del archivo dockerfile que se usará. El siguiente argumento no posee marca para indicarlo y corresponde al contexto, que viene a ser la ruta donde se encuentran los archivos que usaremos (que puede ser reemplazado por un archivo de contexto con la ruta a los distintos archivos).

docker build -t cosmoscalibur/ealite:latest -f dockerfile .

Ejecutar contenedor#

Ahora puedes lanzar un contenedor gráfico basado en la imagen construida con la siguiente instrucción.

docker run --net=host --env="DISPLAY" --volume="$HOME/.Xauthority:/root/.Xauthority:rw" cosmoscalibur/ealite:latest

Referencias#