# Preguntas frecuentes sobre Docker Compose


### ¿Cuál es la diferencia entre `docker compose` y `docker-compose`?

La versión uno del binario de línea de comandos de Docker Compose se lanzó por primera vez en 2014. Estaba escrita en Python y se invoca con `docker-compose`. Por lo general, los proyectos de Compose v1 incluyen un elemento `version` de nivel superior en el archivo `compose.yaml`, con valores que van desde el 2.0 hasta el 3.8, los cuales hacen referencia a los formatos de archivo específicos.

La versión dos del binario de línea de comandos de Docker Compose se anunció en 2020, está escrita en Go y se invoca con `docker compose`. Compose v2 ignora el elemento de nivel superior `version` en el archivo `compose.yaml`.

Para obtener más información, consulta [Historia y desarrollo de Compose](/compose/intro/history/).

### ¿Cuál es la diferencia entre `up`, `run` y `start`?

Normalmente, lo que necesitas es `docker compose up`. Utiliza `up` para iniciar o reiniciar todos los servicios definidos en un archivo `compose.yaml`. En el modo "attached" (conectado) predeterminado, verás todos los logs de todos los contenedores. En el modo "detached" (desconectado, `-d`), Compose finaliza después de iniciar los contenedores, pero estos continúan ejecutándose en segundo plano.

El comando `docker compose run` sirve para ejecutar tareas puntuales ("one-off" o "adhoc"). Requiere el nombre del servicio que deseas ejecutar y únicamente inicia contenedores para los servicios de los que depende el servicio en ejecución. Utiliza `run` para ejecutar pruebas o realizar tareas administrativas, como eliminar o añadir datos a un contenedor con volumen de datos. El comando `run` actúa como `docker run -ti` en el sentido de que abre un terminal interactivo en el contenedor y devuelve un estado de salida idéntico al estado de salida del proceso dentro del contenedor.

El comando `docker compose start` es útil únicamente para reiniciar contenedores que fueron creados previamente pero que se detuvieron. Nunca crea contenedores nuevos.

### ¿Por qué mis servicios tardan 10 segundos en recrearse o detenerse?

El comando `docker compose stop` intenta detener un contenedor enviando un `SIGTERM`. Luego espera un [tiempo de espera predeterminado de 10 segundos](/reference/cli/docker/compose/stop/). Transcurrido ese tiempo de espera, se envía un `SIGKILL` al contenedor para forzar su detención. Si experimentas este tiempo de espera, significa que tus contenedores no se están apagando al recibir la señal `SIGTERM`.

Ya se ha escrito mucho sobre este problema de [procesamiento de señales por parte de los procesos](https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86) en los contenedores.

Para solucionar este problema, prueba lo siguiente:

- Asegúrate de estar utilizando la forma ejecutable (exec form) de `CMD` y `ENTRYPOINT` en tu Dockerfile.

  Por ejemplo, utiliza `["program", "arg1", "arg2"]` en lugar de `"program arg1 arg2"`.
  El uso de la forma de cadena de texto hace que Docker ejecute el proceso utilizando `bash`, el cual no maneja las señales correctamente. Compose siempre utiliza la forma JSON, así que no te preocupes si sobrescribes el comando o el punto de entrada (entrypoint) en tu archivo de Compose.

- Si te es posible, modifica la aplicación que estás ejecutando para añadir un manejador de señales explícito para `SIGTERM`.

- Establece el atributo `stop_signal` con una señal que la aplicación sepa cómo manejar:

  ```yaml
  services:
    web:
      build: .
      stop_signal: SIGINT
  ```

- Si no puedes modificar la aplicación, envuélvela en un sistema de inicio (init) ligero (como [s6](https://skarnet.org/software/s6/)) o en un proxy de señales (como [dumb-init](https://github.com/Yelp/dumb-init) o [tini](https://github.com/krallin/tini)). Cualquiera de estas envolturas se encargará de manejar `SIGTERM` correctamente.

### ¿Cómo ejecuto múltiples copias de un archivo de Compose en el mismo host?

Compose utiliza el nombre del proyecto para crear identificadores únicos para todos los contenedores y otros recursos de un proyecto. Para ejecutar múltiples copias de un proyecto, establece un nombre de proyecto personalizado utilizando la opción de línea de comandos `-p` o la [variable de entorno `COMPOSE_PROJECT_NAME`](/compose/how-tos/environment-variables/envvars/#compose_project_name).

### ¿Puedo usar JSON en lugar de YAML para mi archivo de Compose?

Sí. [YAML es un superconjunto de JSON](https://stackoverflow.com/a/1729545/444646), por lo que cualquier archivo JSON debería ser un YAML válido. Para utilizar un archivo JSON con Compose, especifica el nombre del archivo a usar, por ejemplo:

```console
$ docker compose -f compose.json up
```

### ¿Debería incluir mi código con `COPY`/`ADD` o con un volumen?

Puedes añadir tu código a la imagen utilizando la directiva `COPY` o `ADD` en un `Dockerfile`. Esto es útil si necesitas trasladar tu código junto con la imagen de Docker, por ejemplo, cuando envías el código a otro entorno (producción, CI, etc.).

Utiliza un volumen (`volume`) si quieres realizar cambios en tu código y verlos reflejados inmediatamente, por ejemplo, cuando estás desarrollando código y tu servidor admite la recarga de código en caliente (hot reloading) o la actualización en vivo (live-reload).

Puede haber casos en los que desees utilizar ambos métodos. Puedes hacer que la imagen incluya el código mediante un `COPY` y utilizar un volumen en tu archivo de Compose para incluir el código desde el host durante el desarrollo. El volumen sobrescribe el contenido del directorio de la imagen.

