WebAssembly en contenedores: Docker, Wasm y WASI

Con la llegada de WebAssembly (de ahora en adelante Wasm) en 2017, se abría un nuevo mundo de posibilidades. Con Wasm se busca ejecutar código binario escrito en casi cualquier lenguaje de programación y sin importar el navegador, de forma segura (en un entorno aislado) y de manera nativa (en ocasiones con mejor rendimiento).

Más tarde apareció WebAssembly System Interface (de ahora en adelante WASI), que permite que los binarios de Wasm puedan interactuar con el sistema operativo de forma más sencilla sin importar dónde se ejecuten.

Vamos a ver cómo compilar diversos lenguajes a Wasm/WASI y usarlo con Docker.

Índice

1. Entorno y configuración

El entorno en el que se han probado las herramientas explicadas en este tutorial es el siguiente:

  • Hardware: Portátil MacBook Pro 16′ 2021 (
    Text
    Apple M1 Max

    , 64 GB LPDDR5-6400, 2TB SSD).

  • Sistema Operativo: macOS Sonoma
    Text
    14.3.1
  • Docker Desktop
    Text
    4.28.0
  • Java
    Text
    17.0.9

    y Maven

    Text
    3.9.6
  • Go
    Text
    1.21.5
  • Rustup
    Text
    1.27.0

    y Rustc

    Text
    1.77.0

Para añadir el soporte de Wasm en Docker Desktop hay que habilitar lo siguiente:

  • En Ajustes, en la pestaña General, marcar «Use containerd for pulling and storing images».
  • En Ajustes, en la pestaña Features in development, marcar «Enable Wasm».

Después pulsamos en «Apply & Restart» y Docker Desktop configurará todo lo necesario para ejecutar el entorno de ejecución de Wasm.

2. Java

El proceso para compilar aplicaciones Java a Wasm puede realizarse de distintas maneras. En este caso se realiza con Maven a través del siguiente

Text
pom.xml

:

<project>

    ...

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <teavm.version>0.2.8</teavm.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.fermyon</groupId>
            <artifactId>teavm-classlib</artifactId>
            <version>${teavm.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.fermyon</groupId>
                <artifactId>teavm-maven-plugin</artifactId>
                <version>${teavm.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <targetDirectory>${project.build.directory}/generated/wasm</targetDirectory>
                            <targetType>WEBASSEMBLY</targetType>
                            <mainClass>Main</mainClass>
                            ...
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Como se puede observar, actualmente el plugin

Text
teavm-maven-plugin

soporta hasta

Text
Java 17

. Al ejecutar

Text
mvn clean package

, se generará el binario Wasm en el directorio

Text
target/generated/wasm

3. Go

En el caso de Go, el propio entorno soporta compilar a Wasm y WASI por lo que solo es necesario ejecutar el siguiente comando en un proyecto Go:

Text
GOOS=wasip1 GOARCH=wasm go build -o app.wasm

4. Rust

El caso de Rust es muy parecido al de Go, ya que de nuevo el propio entorno soporta Wasm y WASI. Por tanto, solo hay que ejecutar 2 acciones:

  • Activar el soporte de forma global con
    Text
    rustup target add wasm32-wasi

    .

  • Compilar con el comando
    Text
    cargo build --target wasm32-wasi

    .

El resultado será el binario Wasm en el directorio

Text
target/wasm32-wasi/debug/rust.wasm

.

5. Python

Estado [Marzo 2024]

Aunque la comunidad detrás de Wasm/WASI para Python es activa, no hay una manera clara de compilar el código Python a Wasm. En muchos casos las soluciones funcionan parcialmente o generan errores que impiden su uso.

  • Portar el proyecto de Python a WASI.
  • Compilar el código Python a WASI (no funciona actualmente con la versión
    Text
    2.2rc1

    ).

  • Framework Spin (solo compila a Wasm pero no a WASI).

6. Creación y arranque de contenedor Docker Wasm

El proceso para contenerizar aplicaciones Wasm siempre es el mismo: construir el binario Wasm e introducirlo en un contenedor. Ya que el entorno de Docker dispone de soporte para Wasm, no es necesario usar imágenes base complejas y con el siguiente

Text
Dockerfile

sería suficiente:

FROM scratch

COPY app.wasm /app.wasm

ENTRYPOINT ["/app.wasm"]

Después solo será necesario construir el contenedor con

Text
docker build --platform wasi/wasm -t wasm-app:latest .

y arrancarlo con

Text
docker run --rm --platform=wasi/wasm --runtime=io.containerd.wasmedge.v1 wasm-app:latest

.

7. Conclusiones

En el siguiente repositorio de GitHub se puede encontrar todo el código del tutorial. Para ejecutarlo solo hay que tener instalado el entorno de manera correcta y ejecutar el comando en un terminal “run-all.sh”.

Aunque esta tecnología es muy prometedora y no es nueva en el mundo del desarrollo, aún no está totalmente acogida por todos los lenguajes de programación. Hay lenguajes como C y Go que la soportan de manera nativa y pueden usarse en producción, mientras que con otros solo se puede «probar».

Por otro lado, Docker ha adoptado esta tecnología bastante rápido y la forma de usarla es sencilla. Esto puede hacer que cambie el paradigma de contenerización de las aplicaciones, ya que al compilar a Wasm todas las aplicaciones, se ejecutan de la misma forma (algo ideal para un entorno de contenedores como Kubernetes). Ejemplo de ello es lo que ocupan las imágenes «Hello Word» de cada tecnología (? la imagen de java solo ocupa 242kb ?):

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Consultor tecnológico de desarrollo de proyectos informáticos. Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación. Somos expertos en Java/Java EE

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

22/06/2026

Juan Antonio Jiménez Torres

Vamos a instrumentalizar un SDD para un microservicio bancario. En este artículo sobre SDD - Spec Driven Development, instrumentalizado sobre OpenSpec vamos a construir una PoC de algo más serio que una tabla periódica. Un microservicio bancario muy simplificado que gestione cuentas y permita hacer transferencias

16/06/2026

Juan Antonio Jiménez Torres

Este es el segundo artículo sobre SDD, Spec Driven Development, instrumentalizado sobre OpenSpec. Pero esta vez nos acercaremos usando softwere gratuito. Por un lado OpenCode en lugar de ClaudeCode y usando el modelo gratuito Gemma4 de Google en lugar de otros de pago.

08/06/2026

Juan Antonio Jiménez Torres

Aprenderemos sobre SDD – Spec Driven Development instrumentalizado sobre OpenSpec. Haremos un primer acercamiento usando ClaudeCode con Sonnet, para luego, en un artículo posterior pasarnos a la versión gratuita de OpenCode con Gemma4