# Sobrescribir los valores predeterminados del contenedor





## Explicación

Cuando un contenedor de Docker se inicia, ejecuta una aplicación o comando. El contenedor obtiene este ejecutable (script o archivo) de la configuración de su imagen. Los contenedores vienen con configuraciones predeterminadas que normalmente funcionan bien, pero puedes cambiarlas si es necesario. Estos ajustes ayudan a que el programa del contenedor se ejecute exactamente como deseas.

Por ejemplo, si tienes un contenedor de base de datos existente que escucha en el puerto estándar y deseas ejecutar una nueva instancia del mismo contenedor de base de datos, es posible que desees cambiar la configuración del puerto en el que escucha el nuevo contenedor para que no entre en conflicto con el contenedor existente. A veces, es posible que desees aumentar la memoria disponible para el contenedor si el programa necesita más recursos para manejar una carga de trabajo pesada, o establecer las variables de entorno para proporcionar detalles de configuración específicos que el programa necesita para funcionar correctamente.

El comando `docker run` ofrece una forma potente de sobrescribir estos valores predeterminados y adaptar el comportamiento del contenedor a tu gusto. El comando ofrece varias banderas (flags) que te permiten personalizar el comportamiento del contenedor sobre la marcha.

Aquí tienes algunas formas de lograrlo.

### Sobrescribir los puertos de red

A veces, es posible que desees utilizar instancias de base de datos independientes para fines de desarrollo y pruebas. Ejecutar estas instancias de base de datos en el mismo puerto podría causar conflictos. Puedes usar la opción `-p` en `docker run` para asignar puertos del contenedor a puertos del host, lo que te permite ejecutar múltiples instancias del contenedor sin ningún conflicto.

```console
$ docker run -d -p HOST_PORT:CONTAINER_PORT postgres
```

### Configurar variables de entorno

Esta opción establece una variable de entorno `foo` dentro del contenedor con el valor `bar`.

```console
$ docker run -e foo=bar postgres env
```

Verás una salida como la siguiente:

```console
HOSTNAME=2042f2e6ebe4
foo=bar
```

> [!TIP]
>
> El archivo `.env` actúa como una forma conveniente de configurar variables de entorno para tus contenedores de Docker sin saturar tu línea de comandos con numerosas banderas `-e`. Para usar un archivo `.env`, puedes pasar la opción `--env-file` con el comando `docker run`.
>
> ```console
> $ docker run --env-file .env postgres env
> ```

### Restringir los recursos que el contenedor puede consumir

Puedes usar las banderas `--memory` y `--cpus` con el comando `docker run` para restringir la cantidad de CPU y memoria que puede utilizar un contenedor. Por ejemplo, puedes establecer un límite de memoria para el contenedor de la API de Python, evitando que consuma recursos excesivos en tu host. Aquí está el comando:

```console
$ docker run -e POSTGRES_PASSWORD=secret --memory="512m" --cpus="0.5" postgres
```

Este comando limita el uso de memoria del contenedor a 512 MB y define una cuota de CPU de 0.5 para la mitad de un núcleo.

> **Monitorear el uso de recursos en tiempo real**
>
> Puedes usar el comando `docker stats` para monitorear el uso de recursos en tiempo real de los contenedores en ejecución. Esto te ayuda a comprender si los recursos asignados son suficientes o si necesitan ajustes.

Al utilizar eficazmente estas banderas de `docker run`, puedes adaptar el comportamiento de tu aplicación contenedorizada para que se ajuste a tus requisitos específicos.

## Pruébalo

En esta guía práctica, verás cómo utilizar el comando `docker run` para sobrescribir los valores predeterminados del contenedor.

1. [Descarga e instala](/get-started/get-docker/) Docker Desktop.

### Ejecutar múltiples instancias de la base de datos Postgres

1.  Inicia un contenedor utilizando la imagen de [Postgres](https://hub.docker.com/_/postgres) con el siguiente comando:

    ```console
    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres
    ```

    Esto iniciará la base de datos Postgres en segundo plano, escuchando en el puerto estándar del contenedor `5432` y asignado al puerto `5432` en la máquina host.

2.  Inicia un segundo contenedor de Postgres asignado a un puerto diferente.

    ```console
    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5433:5432 postgres
    ```

    Esto iniciará otro contenedor de Postgres en segundo plano, escuchando en el puerto estándar de Postgres `5432` en el contenedor, pero asignado al puerto `5433` en la máquina host. Sobrescribes el puerto del host solo para asegurarte de que este nuevo contenedor no entre en conflicto con el contenedor en ejecución existente.

3.  Verifica que ambos contenedores estén funcionando yendo a la vista de **Containers** en el Panel de Docker Desktop.

    ![Una captura de pantalla del Panel de Docker Desktop que muestra las instancias en ejecución de los contenedores de Postgres](/get-started/docker-concepts/running-containers/overriding-container-defaults/images/running-postgres-containers.webp?border=true)

### Ejecutar el contenedor de Postgres en una red controlada

De forma predeterminada, los contenedores se conectan automáticamente a una red especial llamada red tipo bridge (puente) cuando los ejecutas. Esta red bridge actúa como un puente virtual, permitiendo que los contenedores en el mismo host se comuniquen entre sí mientras los mantiene aislados del mundo exterior y de otros hosts. Es un punto de partida conveniente para la mayoría de las interacciones de contenedores. Sin embargo, para escenarios específicos, es posible que desees un mayor control sobre la configuración de la red.

Aquí es donde entra en juego la red personalizada. Creas una red personalizada pasando la bandera `--network` con el comando `docker run`. Todos los contenedores sin una bandera `--network` se conectan a la red bridge predeterminada.

Sigue los pasos para ver cómo conectar un contenedor de Postgres a una red personalizada.

1. Crea una nueva red personalizada utilizando el siguiente comando:

   ```console
   $ docker network create mynetwork
   ```

2. Verifica la red ejecutando el siguiente comando:

   ```console
   $ docker network ls
   ```

   Este comando enumera todas las redes, incluida la recién creada "mynetwork".

3. Conecta Postgres a la red personalizada utilizando el siguiente comando:

   ```console
   $ docker run -d -e POSTGRES_PASSWORD=secret -p 5434:5432 --network mynetwork postgres
   ```

   Esto iniciará el contenedor de Postgres en segundo plano, asignado al puerto del host 5434 y conectado a la red `mynetwork`. Pasaste el parámetro `--network` para sobrescribir el valor predeterminado del contenedor conectándolo a una red personalizada de Docker para un mejor aislamiento y comunicación con otros contenedores. Puedes usar el comando `docker network inspect` para ver si el contenedor está vinculado a esta nueva red bridge.

   > **Diferencias clave entre la red bridge predeterminada y las redes personalizadas**
   >
   > 1. Resolución DNS: De forma predeterminada, los contenedores conectados a la red bridge predeterminada pueden comunicarse entre sí, pero solo por dirección IP (a menos que utilices la opción `--link`, que se considera heredada). No se recomienda para uso en producción debido a varias [deficiencias técnicas](/engine/network/drivers/bridge/#differences-between-user-defined-bridges-and-the-default-bridge). En una red personalizada, los contenedores pueden resolverse entre sí por nombre o alias.
   > 2. Aislamiento: Todos los contenedores sin una red `--network` especificada se conectan a la red bridge predeterminada, lo que puede ser un riesgo, ya que los contenedores no relacionados pueden comunicarse entre sí. El uso de una red personalizada proporciona una red de ámbito cerrado en la que solo los contenedores conectados a esa red pueden comunicarse, proporcionando así un mejor aislamiento.

### Gestionar los recursos

De forma predeterminada, los contenedores no están limitados en su uso de recursos. Sin embargo, en sistemas compartidos, es crucial gestionar los recursos de manera efectiva. Es importante no permitir que un contenedor en ejecución consuma demasiada memoria de la máquina host.

Aquí es donde el comando `docker run` brilla de nuevo. Ofrece banderas como `--memory` y `--cpus` para restringir la cantidad de CPU y memoria que puede utilizar un contenedor.

```console
$ docker run -d -e POSTGRES_PASSWORD=secret --memory="512m" --cpus=".5" postgres
```

La bandera `--cpus` especifica la cuota de CPU para el contenedor. Aquí se establece en la mitad de un núcleo de CPU (0.5), mientras que la bandera `--memory` especifica el límite de memoria para el contenedor. En este caso se establece en 512 MB.

### Sobrescribir los valores predeterminados de CMD y ENTRYPOINT en Docker Compose

A veces, es posible que necesites sobrescribir los comandos predeterminados (`CMD`) o puntos de entrada (`ENTRYPOINT`) definidos en una imagen de Docker, especialmente al utilizar Docker Compose.

1. Crea un archivo `compose.yml` con el siguiente contenido:

   ```yaml
   services:
     postgres:
       image: postgres:18
       entrypoint: ["docker-entrypoint.sh", "postgres"]
       command: ["-h", "localhost", "-p", "5432"]
       environment:
         POSTGRES_PASSWORD: secret
   ```

   El archivo Compose define un servicio llamado `postgres` que utiliza la imagen oficial de Postgres, establece un script de punto de entrada e inicia el contenedor con autenticación por contraseña.

2. Inicia el servicio ejecutando el siguiente comando:

   ```console
   $ docker compose up -d
   ```

   Este comando inicia el servicio Postgres definido en el archivo Docker Compose.

3. Verifica la autenticación con el Panel de Docker Desktop.

   Abre el Panel de Docker Desktop, selecciona el contenedor **Postgres** y selecciona **Exec** para ingresar a la terminal del contenedor. Puedes escribir el siguiente comando para conectarte a la base de datos Postgres:

   ```console
   # psql -U postgres
   ```

   ![Una captura de pantalla del Panel de Docker Desktop seleccionando el contenedor Postgres e ingresando a su terminal utilizando el botón EXEC](/get-started/docker-concepts/running-containers/overriding-container-defaults/images/exec-into-postgres-container.webp?border=true)

   > [!NOTE]
   >
   > La imagen de PostgreSQL configura la autenticación de confianza localmente, por lo que notarás que no se requiere contraseña al conectarse desde localhost (dentro del mismo contenedor). Sin embargo, se requerirá una contraseña si se conecta desde un host o contenedor diferente.

### Sobrescribir los valores predeterminados de CMD y ENTRYPOINT con `docker run`

También puedes sobrescribir los valores predeterminados directamente utilizando el comando `docker run` con el siguiente comando:

```console
$ docker run -e POSTGRES_PASSWORD=secret postgres docker-entrypoint.sh -h localhost -p 5432
```

Este comando ejecuta un contenedor Postgres, establece una variable de entorno para la autenticación por contraseña, sobrescribe los comandos de inicio predeterminados y configura el nombre de host y la asignación de puertos.

## Recursos adicionales

- [Formas de establecer variables de entorno con Compose](/compose/how-tos/environment-variables/set-environment-variables/)
- [Qué es un contenedor](/get-started/docker-concepts/the-basics/what-is-a-container/)

## Siguientes pasos

Ahora que has aprendido sobre cómo sobrescribir los valores predeterminados del contenedor, es hora de aprender cómo persistir los datos del contenedor.

[Persistir datos del contenedor](/get-started/docker-concepts/running-containers/overriding-container-defaults/persisting-container-data)


