Cómo crear un paquete AppImage paso a paso en GNU/Linux

Última actualización: 04/12/2025
Autor: Isaac
  • AppImage permite distribuir aplicaciones GNU/Linux en un único archivo autocontenido, portable y sin instalación tradicional.
  • La base de cualquier AppImage es un AppDir bien estructurado con AppRun, archivo .desktop, icono y binarios organizados bajo usr/.
  • Herramientas como linuxdeploy, AppImageKit y Pkg2appimage simplifican la detección de dependencias y la generación del paquete final.
  • El formato facilita ejecutar software reciente en múltiples distros, aunque con ciertas limitaciones en integración y actualización automática.

Qué es un archivo AppImage

Si te mueves a diario por el mundo de GNU/Linux, tarde o temprano te toparás con los famosos archivos .AppImage y querrás entender bien qué son, cómo usarlos y cómo crear los tuyos propios paso a paso. No es solo “otro formato más”: detrás de AppImage hay una filosofía muy clara de portabilidad, menos dependencias rotas y menos dolores de cabeza con versiones de bibliotecas.

Además, cuando empiezas a compilar tus propios programas o a empaquetar aplicaciones para otros, enseguida descubres que mantener .deb, .rpm y demás formatos para cada distro es un auténtico marrón. Ahí es donde AppImage, junto con herramientas como linuxdeploy, AppImageKit y Pkg2appimage, se convierte en una alternativa muy potente para distribuir software de escritorio en casi cualquier distribución moderna.

Qué es exactamente un paquete AppImage y por qué merece la pena

Un archivo AppImage es, en esencia, un ejecutable autocontenido para GNU/Linux que incluye la aplicación y todas sus dependencias necesarias (bibliotecas dinámicas, recursos, iconos, etc.) comprimidas en una única imagen. En lugar de instalarse como un paquete tradicional que reparte archivos por todo el sistema, se comporta de forma parecida a:

  • Un .exe “portable” en Windows, que puedes llevar en un pendrive y ejecutar donde quieras.
  • Un .dmg en macOS, que contiene la aplicación lista para usar sin una instalación clásica.

Cuando ejecutas una AppImage, el sistema monta internamente una imagen ISO comprimida en modo sólo lectura, prepara el entorno y lanza el programa que hay dentro. Una vez cierras la aplicación, el montaje temporal desaparece. No hay “instalación” real al estilo de los paquetes DEB o RPM: si borras el archivo .AppImage, te has llevado por delante el programa sin dejar restos (salvo algunos ficheros de configuración o integración si se han generado).

Este formato se engloba dentro de lo que se conoce como “aplicaciones universales para GNU/Linux”, junto con otros sistemas como Flatpak y Snap (y, en menor medida, propuestas como OrbitalApps). La idea es que el desarrollador empaquete una sola vez y el usuario pueda ejecutar en cualquier distribución GNU/Linux moderna, evitando el infierno de mantener versiones específicas para Debian, Ubuntu, Fedora, openSUSE, etc.

Entre las características más interesantes de AppImage destacan varias que la diferencian de los paquetes tradicionales: es portátil, no requiere permisos de root para ejecutarse y no toca ni las bibliotecas del sistema ni las preferencias globales. Es decir, puedes descargar una AppImage, darle permisos de ejecución y lanzarla en un Live USB, en un sistema estable con repositorios viejos o en una rolling release bastante reciente sin tener que compilar nada ni resolver dependencias.

Ventajas e inconvenientes del formato AppImage frente a los paquetes clásicos

Antes de meternos a fondo con el proceso de creación, conviene tener muy claro qué aporta este formato y cuáles son sus pegas, sobre todo si estás decidiendo si distribuir tu aplicación como AppImage, como paquete nativo o como ambos.

Por el lado positivo, una AppImage es un binario autocontenido con extensión .AppImage que se ejecuta prácticamente en cualquier distro sin necesidad de instalar nada adicional (más allá de FUSE en la mayoría de casos). Esto implica que:

  • No dependes de las bibliotecas del sistema: las librerías que tu programa necesita viajan dentro del propio archivo.
  • No necesitas permisos de superusuario para usar la aplicación, ya que no se copian archivos a rutas del sistema como /usr o /etc.
  • Es extremadamente portátil: puedes poner varias AppImages en un pendrive y usarlas en distintos equipos y distribuciones sin problemas.
  • Eliminan muchos conflictos de dependencias, típicos de “quiero usar una versión nueva de programa X en una distro estable antigua”.
  • Permiten usar aplicaciones recientes en distros LTS o muy conservadoras (Debian estable, Ubuntu LTS, etc.) sin romper el sistema.
  • Son ideales para probar software sin comprometer la seguridad, sobre todo si las combinas con sandboxing (por ejemplo, Firejail).
  The best way to Repair Excessive RAM and CPU Utilization in Home windows 10

Eso sí, no todo son ventajas. AppImage también tiene sus puntos flojos frente a los repositorios clásicos de cada distribución. Por ejemplo, como las aplicaciones incluyen todas sus librerías, el tamaño final suele ser mayor que el de un paquete nativo que reutiliza bibliotecas compartidas ya presentes en el sistema. Además:

  • La integración con el escritorio no siempre es perfecta. Existen herramientas como appimaged o AppImageLauncher para mejorar esto, pero en muchos casos hay que hacer algo de trabajo manual (menús, asociaciones de archivos, etc.).
  • Las aplicaciones AppImage suelen tardar un poco más en arrancar, porque primero hay que montar la imagen comprimida, aunque una vez abiertas funcionan con normalidad.
  • Las actualizaciones automáticas no siempre están bien resueltas: hay herramientas como AppImageUpdate o soporte para zsync, pero mucho software sigue requiriendo descargar la nueva AppImage y reemplazar la anterior a mano.
  • El catálogo de aplicaciones en formato AppImage no es tan amplio como el de los repositorios oficiales de las grandes distros, aunque cada vez incluye más proyectos importantes (Krita, GIMP, Kdenlive, LibreOffice, etc.).
  • En general, se considera que los paquetes mantenidos en los repositorios oficiales suelen tener una revisión de seguridad extra respecto a binarios descargados directamente de una web, así que hay que cuidar el origen de las AppImages que usamos.

Aun con todo, para muchos escenarios AppImage es una solución muy práctica: por ejemplo, ejecutar aplicaciones que no están en los repositorios de tu distro, saltarte dependencias disparatadas o usar software actual en máquinas antiguas. Y desde el punto de vista del desarrollador, empaquetar una única AppImage para todas las distros ahorra muchísimo trabajo.

Cómo se estructura una AppImage por dentro: el directorio AppDir

La mayor parte de las herramientas que generan AppImages trabajan a partir de un concepto básico: el AppDir, un directorio con una estructura reconocida por el ecosistema AppImage. Todo lo que acabará dentro del archivo .AppImage se organiza primero en ese árbol de directorios.

En su forma mínima, un AppDir necesita al menos tres archivos clave en su raíz:

  • AppRun: el script o ejecutable que se lanza cuando haces ./MiPrograma.AppImage. Se encarga de preparar el entorno (PATH, LD_LIBRARY_PATH, etc.) y de ejecutar la aplicación real.
  • Un archivo .desktop: contiene los metadatos de la aplicación (nombre, comentario, categorías, icono, comando de ejecución…) siguiendo la especificación Desktop Entry de freedesktop.org.
  • Un icono (normalmente .png o .svg): se usa tanto para mostrar el icono del archivo AppImage en los exploradores de archivos como para los lanzadores de aplicaciones integrados en el sistema.

Más allá de esa base mínima, lo habitual es que dentro del AppDir se respete una estructura similar a la de un sistema GNU/Linux convencional, respetando la FHS (Filesystem Hierarchy Standard). Es decir, crear subdirectorios como ./usr/bin, ./usr/lib o ./usr/share. Dentro de ellos irás colocando:

  • En usr/bin/, el binario principal de tu aplicación (por ejemplo, hello-world, Rectball, nvim, etc.).
  • En usr/lib/, las bibliotecas compartidas (.so) que tu programa necesita y que no deberías asumir que el usuario tiene instaladas en su sistema.
  • En usr/share/applications/, el archivo .desktop que describe la aplicación.
  • En usr/share/icons/hicolor/ (y rutas similares), los iconos de la aplicación en distintos tamaños.

Es fundamental que el ejecutable sea independiente de la ubicación en el sistema de archivos. Si tu programa asume rutas absolutas del estilo /usr/bin/miapp o /usr/share/miapp, tendrás problemas al ejecutar la AppImage, porque en tiempo de ejecución se monta en otra ruta temporal. Lo correcto es trabajar con rutas relativas o construirlas dinámicamente a partir de la ruta real del binario o del script AppRun.

Un AppDir algo más completo podría verse así en una lista de directorios:

$ ls -l
AppRun
miaplicacion.desktop
miaplicacion.svg
usr/

$ ls -R usr
usr/bin/miaplicacion
usr/lib/…
usr/share/applications/miaplicacion.desktop
usr/share/icons/hicolor/…

Una vez tengas esta estructura, herramientas como linuxdeploy o appimagetool (de AppImageKit) serán las encargadas de convertir tu AppDir en el archivo .AppImage final.

Archivo .desktop e integración básica con el escritorio

El archivo .desktop es una pieza clave, tanto para AppImage como para la integración de cualquier aplicación de escritorio en GNU/Linux. Es un simple fichero de texto con formato Desktop Entry que se puede editar con un editor de texto plano o con utilidades gráficas de edición de menús.

  Convierte tu vieja tablet en una pantalla de Android Auto

Un ejemplo sencillo de contenido podría ser:

[Desktop Entry]
Type=Application
Name=Rectball
Comment=Match gems and collect points in this puzzle game
Categories=Game;
Exec=Rectball
Icon=rectball

En este ejemplo, la clave Exec indica el comando que se va a ejecutar (sin ruta absoluta) y, si en tu AppRun configuras el PATH para incluir ${HERE}/usr/bin, el sistema encontrará el binario sin problemas. Es importante recalcar que:

  • La entrada Categories es obligatoria para muchas herramientas relacionadas con AppImage (por ejemplo, algunas variantes de linuxdeploy fallan si no está definida).
  • La clave Icon se suele mapear a un archivo tipo nombre.png o nombre.svg que debe estar accesible en los directorios de iconos esperados (por ejemplo, en el AppDir bajo usr/share/icons o junto al .desktop según el flujo de trabajo).

En algunos AppImages reales verás que la clave Icon se omite o se hace de forma algo distinta. Aun así, si quieres evitar sorpresas (por ejemplo, iconos que no se muestran correctamente cuando usas .png en vez de .svg), compensa definir Icon expresamente y comprobar en varias distros que se ve bien.

El script AppRun: corazón de la ejecución en AppImage

El archivo AppRun es el punto de entrada de la AppImage. Cuando el usuario ejecuta el archivo .AppImage, lo que se lanza en realidad es AppRun dentro del AppDir montado. Este script puede ser un shell script sencillo que:

  • Resuelva la ruta real desde la que se está ejecutando (teniendo en cuenta enlaces simbólicos y montajes temporales).
  • Prepare variables de entorno como PATH, LD_LIBRARY_PATH y otras que necesite tu programa para encontrar bibliotecas o recursos.
  • Lance el ejecutable real (ya sea leyendo la clave Exec del .desktop o invocando directamente usr/bin/miapp).

Un patrón muy habitual, que encontrarás en AppImageKit, es algo como:

#!/bin/sh
SELF=$(readlink -f "$0")
HERE=${SELF%/*}

export PATH="${HERE}/usr/bin:$PATH"
export LD_LIBRARY_PATH="${HERE}/usr/lib:$LD_LIBRARY_PATH"

EXEC=$(grep -e '^Exec=' "${HERE}"/*.desktop | head -n 1 | cut -d '=' -f 2 | cut -d ' ' -f 1)
exec "${EXEC}" "$@"

Este enfoque busca dinámicamente el valor de Exec en el archivo .desktop y lo ejecuta con los argumentos que haya pasado el usuario, lo que resulta muy flexible. Otros proyectos optan por versiones aún más sencillas. Por ejemplo, el AppImage de Neovim utiliza un AppRun minimalista del estilo:

#!/bin/bash
unset ARGV0
exec "$(dirname "$(readlink -f "${0}")")/usr/bin/nvim" ${@+"$@"}

Sea cual sea la variante que uses, la idea es que AppRun no dependa de rutas absolutas del sistema y sea capaz de funcionar correctamente en cualquier ubicación donde se monte la AppImage.

Herramientas para crear AppImages: linuxdeploy, AppImageKit y Pkg2appimage

A la hora de generar tu propio paquete AppImage, tienes varias herramientas principales sobre la mesa, cada una con su enfoque. La más recomendada para flujos de trabajo modernos es linuxdeploy, aunque AppImageKit y Pkg2appimage siguen teniendo su lugar.

linuxdeploy se encarga de analizar tu ejecutable, detectar sus dependencias y construir automáticamente la estructura AppDir adecuada (copiando bibliotecas a usr/lib, organizando archivos, etc.). Es especialmente útil cuando ya tienes un binario funcional y quieres empaquetarlo sin romperte demasiado la cabeza con qué librerías debes incluir.

Por su parte, AppImageKit proporciona, entre otras cosas, la herramienta appimagetool, que toma como entrada un AppDir ya montado y genera a partir de él el archivo .AppImage. Puedes descargar appimagetool directamente desde su repositorio de GitHub; curiosamente, se distribuye a su vez como una AppImage. Un uso típico sería:

./appimagetool-x86_64.AppImage MiApp.AppDir MiApp-x86_64.AppImage

En entornos como Docker o CI, hay que tener presente que AppImageKit requiere FUSE para poder montar la imagen internamente. Si FUSE no está disponible en el contenedor o la máquina, el proceso puede fallar, así que conviene revisarlo antes de automatizar builds.

La tercera pata importante es Pkg2appimage, pensada para casos en los que ya tienes un paquete existente (por ejemplo, tar.gz, .deb o incluso repositorios PPA) y quieres convertirlo en una AppImage. Esta herramienta se controla a través de un archivo de descripción .yml, donde defines de dónde se descarga el software, cómo se instalan los paquetes y qué archivos acaban en el AppDir resultante.

  ¿Cómo funciona la equiparación del 401k?

La forma típica de trabajar con Pkg2appimage es algo así:

  1. Clonar un repositorio con el .yml adecuado para la aplicación que quieres convertir (por ejemplo, un YAML de Packet Tracer adaptado).
  2. Descargar Pkg2appimage desde su GitHub y darle permisos de ejecución con chmod +x.
  3. Ajustar el archivo .yml para actualizar URLs de descarga que hayan cambiado o dependencias nuevas.
  4. Lanzar ./pkg2appimage NombreArchivo.yml y esperar a que genere el AppDir y la AppImage final.

Este enfoque resulta muy práctico para reciclar paquetes existentes que no funcionan bien en tu distro o que requieren “downgrades” de bibliotecas complejos. Pkg2appimage automatiza gran parte de ese trabajo y te deja un .AppImage listo para usar en diferentes sistemas.

Crear una AppImage desde tu propio ejecutable paso a paso

Imagina que tienes un programa sencillo, por ejemplo un proyecto llamado hello-world, con su binario en bin/ y sus bibliotecas en lib/. Podrías empaquetarlo como .zip, aprender a generar un .deb o un .rpm, pero también puedes aprovechar para empaquetarlo como AppImage. El flujo con linuxdeploy suele ser bastante directo.

Los pasos básicos serían estos: pasos clave

1. Preparar el entorno y obtener linuxdeploy

Lo primero es descargar la herramienta linuxdeploy y hacerla ejecutable. Normalmente se distribuye en binarios listos para usar (por ejemplo, como AppImage). Desde la terminal, algo así como:

wget https://github.com/linuxdeploy/linuxdeploy/releases/.../linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage

Además, si planeas ofrecer actualizaciones eficientes vía zsync, puedes instalar la utilidad zsync, por ejemplo en sistemas basados en Debian/Ubuntu con:

sudo apt-get install zsync

2. Construir la estructura AppDir

A continuación creas un directorio que funcionará como AppDir (por ejemplo, MiApp.AppDir) y dentro organizas la estructura mínima necesaria. Puedes hacerlo a mano o dejar que linuxdeploy genere parte de ello. La idea es:

  • Colocar tu ejecutable principal en MiApp.AppDir/usr/bin/. Por ejemplo, MiApp.AppDir/usr/bin/hello-world.
  • Permitir que linuxdeploy copie automáticamente las bibliotecas requeridas a MiApp.AppDir/usr/lib/ cuando lo ejecutes con las opciones adecuadas.
  • Crear el archivo .desktop dentro de MiApp.AppDir/usr/share/applications/ con los campos correctos: Name, Comment, Exec, Icon, Categories, etc.
  • Preparar los iconos y colocarlos en rutas tipo MiApp.AppDir/usr/share/icons/hicolor/, asegurándote de que el valor de la clave Icon en el .desktop coincide con el nombre del archivo (sin la extensión).

Es importante recordar que en el .desktop el campo Exec debe apuntar al nombre del ejecutable tal y como linuxdeploy lo buscará en usr/bin. Si usas Exec=hello-world, linuxdeploy asumirá que en usr/bin existe ese ejecutable.

3. Ejecutar linuxdeploy para empaquetar la aplicación

Con la estructura AppDir en su sitio, indicar la ruta al AppDir y, opcionalmente, módulos o plugins específicos (por ejemplo, para integrar iconos, archivos .desktop, etc.). linuxdeploy se encarga de:

  • Escanear el binario principal y detectar qué bibliotecas dinámicas necesita.
  • Copiar esas librerías dentro de usr/lib dentro del AppDir, siempre que no sean bibliotecas que se asume que ya existen en el sistema del usuario.
  • Dejar listo el AppDir para que posteriormente se convierta en AppImage (a veces, la propia linuxdeploy puede generar la AppImage en combinación con plugins).

Tras este proceso, tendrás en el directorio actual un archivo con extensión .AppImage, como por ejemplo hello-world-x86_64.AppImage, que podrás copiar donde quieras y ejecutar en otros sistemas GNU/Linux compatibles.

4. Hacer ejecutable y probar en varias distribuciones

Cuando linuxdeploy (o appimagetool) genera la AppImage, es muy posible que al principio no tenga el bit de ejecución activo. En ese caso, basta con hacer:

chmod +x hello-world-x86_64.AppImage
./hello-world-x86_64.AppImage

Es muy recomendable que pruebes tu AppImage en distintas distribuciones y versiones, incluyendo alguna relativamente antigua dentro del rango que quieras soportar (por ejemplo, la versión mínima de Ubuntu o Debian que pretendes soportar). Así te aseguras de que no te has dejado ninguna dependencia importante fuera y de que el ejecutable se comporta igual en todas partes.