# Usar contenedores para el desarrollo de R


## Requisitos previos

Completa [Contenedorizar una aplicación R](/guides/r/develop/containerize/).

## Descripción general

En esta sección, aprenderás a configurar un entorno de desarrollo para tu aplicación contenedorizada. Esto incluye:

- Agregar una base de datos local y persistir datos
- Configurar Compose para actualizar automáticamente tus servicios de Compose en ejecución a medida que editas y guardas tu código

## Obtener la aplicación de ejemplo

Necesitarás clonar un nuevo repositorio para obtener una aplicación de ejemplo que incluya la lógica para conectarse a la base de datos.

Cambia al directorio donde deseas clonar el repositorio y ejecuta el siguiente comando.

```console
$ git clone https://github.com/mfranzon/r-docker-dev.git
```

## Configurar la aplicación para usar la base de datos

Para probar la conexión entre la aplicación Shiny y la base de datos local, debes modificar el `Dockerfile` cambiando la instrucción `COPY`:

```diff
-COPY src/ .
+COPY src_db/ .
```

## Agregar una base de datos local y persistir datos

Puedes usar contenedores para configurar servicios locales, como una base de datos. En esta sección, actualizarás el archivo `compose.yaml` para definir un servicio de base de datos y un volumen para persistir los datos.

En el directorio del repositorio clonado, abre el archivo `compose.yaml` en un IDE o editor de texto.

En el archivo `compose.yaml`, debes descomentar las propiedades para configurar la base de datos. También debes montar el archivo de contraseña de la base de datos y establecer una variable de entorno en el servicio `shiny-app` que apunte a la ubicación del archivo en el contenedor.

El siguiente es el archivo `compose.yaml` actualizado.

```yaml
services:
  shiny-app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3838:3838
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db-password
  db:
    image: postgres:18
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
```

> [!NOTE]
>
> Para obtener más información sobre las instrucciones en el archivo Compose, consulta la [referencia del archivo Compose](/reference/compose-file/).

Antes de ejecutar la aplicación usando Compose, observa que este archivo Compose especifica un archivo `password.txt` para contener la contraseña de la base de datos. Debes crear este archivo, ya que no está incluido en el repositorio fuente.

En el directorio del repositorio clonado, crea un nuevo directorio llamado `db` y dentro de ese directorio crea un archivo llamado `password.txt` que contenga la contraseña para la base de datos. Usando tu IDE o editor de texto favorito, agrega el siguiente contenido al archivo `password.txt`.

```text
mysecretpassword
```

Guarda y cierra el archivo `password.txt`.

Ahora deberías tener el siguiente contenido en tu directorio `r-docker-dev`.

```text
├── r-docker-dev/
│   ├── db/
│   │   └── password.txt
│   ├── src/
│   │   └── app.R
│   ├── src_db/
│   │   └── app_db.R
│   ├── requirements.txt
│   ├── .dockerignore
│   ├── compose.yaml
│   ├── Dockerfile
│   ├── README.Docker.md
│   └── README.md
```

Ahora, ejecuta el siguiente comando `docker compose up` para iniciar tu aplicación.

```console
$ docker compose up --build
```

Ahora prueba la conexión a tu base de datos abriendo un navegador en:

```console
http://localhost:3838
```

Deberías ver un mensaje emergente:

```text
DB CONNECTED
```

Presiona `ctrl+c` en la terminal para detener tu aplicación.

## Actualizar servicios automáticamente

Utiliza Compose Watch para actualizar automáticamente tus servicios de Compose en ejecución a medida que editas y guardas tu código. Para obtener más detalles sobre Compose Watch, consulta [Usar Compose Watch](/compose/how-tos/file-watch/).

Las líneas 15 a 18 en el archivo `compose.yaml` contienen propiedades que hacen que Docker vuelva a compilar la imagen cuando cambia un archivo en el directorio de trabajo actual:

```yaml {hl_lines="15-18",linenos=true}
services:
  shiny-app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3838:3838
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db-password
    develop:
      watch:
        - action: rebuild
          path: .
  db:
    image: postgres:18
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
```

Ejecuta el siguiente comando para ejecutar tu aplicación con Compose Watch.

```console
$ docker compose watch
```

Ahora, si modificas tu `app.R`, ¡verás los cambios en tiempo real sin volver a compilar la imagen!

Presiona `ctrl+c` in la terminal para detener tu aplicación.

## Resumen

En esta sección, viste cómo configurar tu archivo Compose para agregar una base de datos local y persistir datos. También aprendiste a usar Compose Watch para compilar y ejecutar automáticamente tu contenedor cuando actualizas tu código.

Información relacionada:

- [Referencia del archivo Compose](/reference/compose-file/)
- [Compose file watch](/compose/how-tos/file-watch/)
- [Compilaciones de múltiples etapas (multi-stage builds)](/build/building/multi-stage/)

## Pasos siguientes

En la siguiente sección, verás cómo configurar un flujo de trabajo de CI/CD utilizando GitHub Actions.

