# Compila tu imagen de Rust


## Prerrequisitos

- Has instalado la última versión de [Docker Desktop](/get-started/get-docker/).
- Tienes un [cliente git](https://git-scm.com/downloads). Los ejemplos de esta sección utilizan un cliente git basado en la línea de comandos, pero puedes utilizar cualquier cliente.

## Resumen

Esta guía te acompaña en el proceso de compilación de tu primera imagen de Rust. Una imagen incluye todo lo necesario para ejecutar una aplicación: el código o binario, el entorno de ejecución, las dependencias y cualquier otro objeto del sistema de archivos que sea necesario.

## Obtén la aplicación de muestra

Clona la aplicación de muestra para usarla con esta guía. Abre una terminal, cambia al directorio en el que deseas trabajar y ejecuta el siguiente comando para clonar el repositorio:

```console
$ git clone https://github.com/docker/docker-rust-hello && cd docker-rust-hello
```

## Crea un Dockerfile para Rust

Ahora que tienes una aplicación, puedes usar `docker init` para crear un Dockerfile para ella. Dentro del directorio `docker-rust-hello`, ejecuta el comando `docker init`. `docker init` proporciona cierta configuración predeterminada, pero tendrás que responder algunas preguntas sobre tu aplicación. Consulta el siguiente ejemplo para responder a las preguntas de `docker init` y utiliza las mismas respuestas.

```console
$ docker init
Welcome to the Docker Init CLI!

This utility will walk you through creating the following files with sensible defaults for your project:
  - .dockerignore
  - Dockerfile
  - compose.yaml
  - README.Docker.md

Let's get started!

? What application platform does your project use? Rust
? What version of Rust do you want to use? 1.92.0
? What port does your server listen on? 8000
```

Ahora deberías tener los siguientes archivos nuevos en tu directorio `docker-rust-hello`:

- Dockerfile
- .dockerignore
- compose.yaml
- README.Docker.md

## Elige una imagen base

Antes de editar tu Dockerfile, debes elegir una imagen base. Puedes usar la [Imagen Oficial de Docker para Rust](https://hub.docker.com/_/rust), o una [Docker Hardened Image (DHI)](https://hub.docker.com/hardened-images/catalog/dhi/rust).

Las Docker Hardened Images (DHIs) son imágenes base mínimas, seguras y listas para producción mantenidas por Docker. Ayudan a reducir las vulnerabilidades y simplifican el cumplimiento normativo. Para más detalles, consulta [Docker Hardened Images](/dhi/).

**Uso de Docker Hardened Images**



Las Docker Hardened Images (DHIs) están disponibles públicamente y se pueden usar directamente como imágenes base.
Para descargar (pull) Docker Hardened Images, autentícate una vez con Docker:

```bash
docker login dhi.io
```

Usa las DHIs del registro dhi.io, por ejemplo:

```bash
FROM dhi.io/rust:${RUST_VERSION}-alpine3.22-dev AS build
```

El siguiente Dockerfile es equivalente al generado por `docker init`, pero utiliza una DHI de Rust como imagen base de compilación:

```dockerfile {title=Dockerfile}
# Asegúrate de que RUST_VERSION coincida con la versión de Rust
ARG RUST_VERSION=1.92
ARG APP_NAME=docker-rust-hello

################################################################################
# Crea una etapa para compilar la aplicación.
################################################################################

FROM dhi.io/rust:${RUST_VERSION}-alpine3.22-dev AS build
ARG APP_NAME
WORKDIR /app

# Instala las dependencias de compilación del host.
RUN apk add --no-cache clang lld musl-dev git

# Compila la aplicación.
RUN --mount=type=bind,source=src,target=src \
    --mount=type=bind,source=Cargo.toml,target=Cargo.toml \
    --mount=type=bind,source=Cargo.lock,target=Cargo.lock \
    --mount=type=cache,target=/app/target/ \
    --mount=type=cache,target=/usr/local/cargo/git/db \
    --mount=type=cache,target=/usr/local/cargo/registry/ \
    cargo build --locked --release && \
    cp ./target/release/$APP_NAME /bin/server

################################################################################
# Crea una nueva etapa para ejecutar la aplicación que contenga lo mínimo.
# Usamos dhi.io/static para la etapa final porque es un entorno de ejecución mínimo de Docker Hardened Image (básicamente "el sistema operativo justo para ejecutar el binario"), lo que ayuda a mantener la imagen pequeña y con una menor superficie de ataque en comparación con un entorno de ejecución completo de Alpine/Debian.
################################################################################

FROM dhi.io/static:20250419 AS final

# Copia el ejecutable desde la etapa de compilación "build".
COPY --from=build /bin/server /bin/

# Configura rocket para escuchar en todas las interfaces.
ENV ROCKET_ADDRESS=0.0.0.0

# Expone el puerto en el que escucha la aplicación.
EXPOSE 8000

# Lo que debe ejecutar el contenedor cuando se inicia.
CMD ["/bin/server"]

```

**Uso de las Imágenes Oficiales de Docker**



```dockerfile {title=Dockerfile}
# Fija la versión de la cadena de herramientas de Rust utilizada en la etapa de compilación.
ARG RUST_VERSION=1.92

# Nombre del binario compilado producido por Cargo (debe coincidir con el nombre del paquete en Cargo.toml).
ARG APP_NAME=docker-rust-hello

################################################################################
# Etapa de compilación (imagen de Rust de DOI)
# Esta etapa compila la aplicación.
################################################################################

FROM docker.io/library/rust:${RUST_VERSION}-alpine AS build

# Vuelve a declarar las variables (args) dentro de la etapa si deseas usarlas aquí.
ARG APP_NAME

# Todos los pasos de compilación ocurren dentro de /app.
WORKDIR /app

# Instala las dependencias de compilación necesarias para compilar crates de Rust en Alpine
RUN apk add --no-cache clang lld musl-dev git

# Compila la aplicación
RUN --mount=type=bind,source=src,target=src \
    --mount=type=bind,source=Cargo.toml,target=Cargo.toml \
    --mount=type=bind,source=Cargo.lock,target=Cargo.lock \
    --mount=type=cache,target=/app/target/ \
    --mount=type=cache,target=/usr/local/cargo/git/db \
    --mount=type=cache,target=/usr/local/cargo/registry/ \
    cargo build --locked --release && \
    cp ./target/release/$APP_NAME /bin/server

################################################################################
# Etapa de ejecución (imagen de Alpine de DOI)
# Esta etapa ejecuta el binario ya compilado con dependencias mínimas.
################################################################################

FROM docker.io/library/alpine:3.18 AS final

# Crea un usuario sin privilegios (buena práctica recomendada)
ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser

# Reduce los privilegios para la ejecución.
USER appuser

# Copia solo el binario compilado desde la etapa de compilación.
COPY --from=build /bin/server /bin/

# Rocket: escucha en todas las interfaces dentro del contenedor.
ENV ROCKET_ADDRESS=0.0.0.0

# Documenta el puerto en el que escucha tu aplicación.
EXPOSE 8000

# Inicia la aplicación.
CMD ["/bin/server"]
```


Para compilar una imagen, solo es necesario el Dockerfile. Abre el Dockerfile en tu IDE o editor de texto favorito y observa lo que contiene. Para obtener más información sobre los Dockerfiles, consulta la [referencia de Dockerfile](/reference/dockerfile/).

## Archivo .dockerignore

Cuando ejecutas `docker init`, también se crea un archivo [`.dockerignore`](/reference/dockerfile/#dockerignore-file). Utiliza el archivo `.dockerignore` para especificar patrones y rutas que no deseas que se copien en la imagen para mantener la imagen lo más pequeña posible. Abre el archivo `.dockerignore` en tu IDE o editor de texto favorito y observa qué contiene ya.

## Compilar una imagen

Ahora que has creado el Dockerfile, puedes compilar la imagen. Para hacer esto, utiliza el comando `docker build`. El comando `docker build` compila imágenes de Docker a partir de un Dockerfile y un contexto. El contexto de una compilación es el conjunto de archivos ubicados en la RUTA o URL especificada. El proceso de compilación de Docker puede acceder a cualquiera de los archivos ubicados en este contexto.

El comando de compilación opcionalmente acepta una bandera `--tag`. La etiqueta establece el nombre de la imagen y una etiqueta opcional en el formato `nombre:etiqueta`. Si no pasas una etiqueta, Docker utiliza "latest" como su etiqueta predeterminada.

Compila la imagen de Docker.

```console
$ docker build --tag docker-rust-image-dhi .
```

Deberías ver una salida como la siguiente.

```console
[+] Building 1.4s (13/13) FINISHED                                                                                                                                 docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                               0.0s
 => => transferring dockerfile: 1.67kB                                                                                                                                             0.0s
 => [internal] load metadata for dhi.io/static:20250419                                                                                                                            1.1s
 => [internal] load metadata for dhi.io/rust:1.92-alpine3.22-dev                                                                                                                   1.2s
 => [auth] static:pull token for dhi.io                                                                                                                                            0.0s
 => [auth] rust:pull token for dhi.io                                                                                                                                              0.0s
 => [internal] load .dockerignore                                                                                                                                                  0.0s
 => => transferring context: 646B                                                                                                                                                  0.0s
 => [build 1/3] FROM dhi.io/rust:1.92-alpine3.22-dev@sha256:49eb72825a9e15fe48f2c4875a63c7e7f52a5b430bb52b8254b91d132aa5bf38                                                       0.0s
 => => resolve dhi.io/rust:1.92-alpine3.22-dev@sha256:49eb72825a9e15fe48f2c4875a63c7e7f52a5b430bb52b8254b91d132aa5bf38                                                             0.0s
 => [final 1/2] FROM dhi.io/static:20250419@sha256:74fc43fa240887b8159970e434244039aab0c6efaaa9cf044004cdc22aa2a34d                                                                0.0s
 => => resolve dhi.io/static:20250419@sha256:74fc43fa240887b8159970e434244039aab0c6efaaa9cf044004cdc22aa2a34d                                                                      0.0s
 => [internal] load build context                                                                                                                                                  0.0s
 => => transferring context: 117B                                                                                                                                                  0.0s
 => CACHED [build 2/3] WORKDIR /build                                                                                                                                              0.0s
 => CACHED [build 3/3] RUN --mount=type=bind,source=src,target=src     --mount=type=bind,source=Cargo.toml,target=Cargo.toml     --mount=type=bind,source=Cargo.lock,target=Cargo  0.0s
 => CACHED [final 2/2] COPY --from=build /build/target/release/docker-rust-hello /server                                                                                           0.0s
 => exporting to image                                                                                                                                                             0.1s
 => => exporting layers                                                                                                                                                            0.0s
 => => exporting manifest sha256:cc937bbdd712ef6e5445501f77e02ef8455ef64c567598786d46b7b21a4d4fa8                                                                                  0.0s
 => => exporting config sha256:077507b483af4b5e1a928e527e4bb3a4aaf0557e1eea81cd39465f564c187669                                                                                    0.0s
 => => exporting attestation manifest sha256:11b60e7608170493da1fdd88c120e2d2957f2a72a22edbc9cfbdd0dd37d21f89                                                                      0.0s
 => => exporting manifest list sha256:99a1b925a8d6ebf80e376b8a1e50cd806ec42d194479a3375e1cd9d2911b4db9                                                                             0.0s
 => => naming to docker.io/library/docker-rust-image-dhi:latest                                                                                                                    0.0s
 => => unpacking to docker.io/library/docker-rust-image-dhi:latest                                                                                                                 0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/yczk0ijw8kc5g20e8nbc8r6lj
```

## Ver imágenes locales

Para ver una lista de imágenes que tienes en tu máquina local, tienes dos opciones. Una es usar la CLI de Docker y la otra es usar [Docker Desktop](/desktop/use-desktop/images/). Como ya estás trabajando en la terminal, echemos un vistazo a la lista de imágenes usando la CLI.

Para listar imágenes, ejecuta el comando `docker images`.

```console
$ docker images
IMAGE                          ID             DISK USAGE   CONTENT SIZE   EXTRA
docker-rust-image-dhi:latest   99a1b925a8d6       11.6MB         2.45MB    U   
```

Deberías ver al menos una imagen en la lista, incluyendo la imagen que acabas de compilar `docker-rust-image-dhi:latest`.

## Etiquetar imágenes

Como se mencionó anteriormente, el nombre de una imagen se compone de componentes de nombre separados por barras diagonales. Los componentes de nombre pueden contener letras minúsculas, dígitos y separadores. Un separador puede incluir un punto, uno o dos guiones bajos, o uno o más guiones. Un componente de nombre no puede comenzar ni terminar con un separador.

Una imagen se compone de un manifiesto y una lista de capas. No te preocupes demasiado por los manifiestos y las capas en este momento, aparte de que una "etiqueta" apunta a una combinación de estos artefactos. Puedes tener múltiples etiquetas para una imagen. Crea una segunda etiqueta para la imagen que compilaste y echa un vistazo a sus capas.

Para crear una nueva etiqueta para la imagen que compilaste, ejecuta el siguiente comando.

```console
$ docker tag docker-rust-image-dhi:latest docker-rust-image-dhi:v1.0.0
```

El comando `docker tag` crea una nueva etiqueta para una imagen. No crea una nueva imagen. La etiqueta apunta a la misma imagen y es solo otra forma de hacer referencia a ella.

Ahora, ejecuta el comando `docker images` para ver una lista de las imágenes locales.

```console
$ docker images
IMAGE                          ID             DISK USAGE   CONTENT SIZE   EXTRA
docker-rust-image-dhi:latest   99a1b925a8d6       11.6MB         2.45MB    U   
docker-rust-image-dhi:v1.0.0   99a1b925a8d6       11.6MB         2.45MB    U  
```

Puedes ver que dos imágenes comienzan con `docker-rust-image-dhi`. Sabes que son la misma imagen porque si miras la columna `IMAGE ID`, puedes ver que los valores son iguales para ambas imágenes.

Elimina la etiqueta que acabas de crear. Para hacer esto, utiliza el comando `rmi`. El comando `rmi` significa eliminar imagen (remove image).

```console
$ docker rmi docker-rust-image-dhi:v1.0.0
Untagged: docker-rust-image-dhi:v1.0.0
```

Ten en cuenta que la respuesta de Docker te indica que Docker no eliminó la imagen, sino que solo le quitó la etiqueta ("untagged"). Puedes comprobarlo ejecutando el comando `docker images`.

```console
$ docker images
IMAGE                          ID             DISK USAGE   CONTENT SIZE   EXTRA
docker-rust-image-dhi:latest   99a1b925a8d6       11.6MB         2.45MB    U   
```

Docker eliminó la imagen etiquetada con `:v1.0.0`, pero la etiqueta `docker-rust-image-dhi:latest` sigue disponible en tu máquina.

## Resumen

Esta sección mostró cómo puedes usar `docker init` para crear un Dockerfile y un archivo .dockerignore para una aplicación Rust. Luego te mostró cómo compilar una imagen. Y finalmente, te mostró cómo etiquetar una imagen y listar todas las imágenes.

Información relacionada:

- [Referencia de Dockerfile](/reference/dockerfile/)
- [Archivo .dockerignore](/reference/dockerfile/#dockerignore-file)
- [Referencia de CLI de docker init](/reference/cli/docker/init/)
- [Referencia de CLI de docker build](/reference/cli/docker/buildx/build/)
- [Docker Hardened Images](/dhi/)

## Pasos siguientes

En la siguiente sección, aprenderás cómo ejecutar tu imagen como un contenedor.

