WORKDIR

 Perfecto, ahora voy a integrar tu árbol inicial del host con la explicación del WORKDIR y el volumen, para que veas exactamente qué ruta se sincroniza y cómo ocurre el "milagro".


Árbol inicial del host (antes de levantar contenedores)

text
~/laravel-docker/
├── Dockerfile          (lo creamos)
└── docker-compose.yml  (lo creamos)

Esta carpeta (~/laravel-docker/) es tu proyecto en el host. En este momento solo tienes esos dos archivos de configuración.


¿Qué hace el WORKDIR /var/www dentro del Dockerfile?

  • WORKDIR /var/www es una instrucción que no crea ni llena la carpeta. Solo establece el directorio de trabajo por defecto dentro del contenedor. Cuando entres con docker exec o ejecutes comandos, estarás automáticamente en /var/www.


¿Dónde y cuándo se instala realmente Laravel?

  • No se instala al construir la imagen (docker build).

  • se instala más tarde, cuando el contenedor ya está en ejecución y tú lanzas composer create-project dentro de él.


La sincronización paso a paso (con rutas explícitas)

1. Construcción de la imagen

  • Ejecutas docker-compose build (o up que también construye).

  • Docker crea la imagen basada en el Dockerfile. En ese momento, dentro de la imagen existe la carpeta /var/www (vacía) porque así está definida la imagen base php:8.2-fpm.

  • El WORKDIR /var/www solo apunta a esa ruta.

2. Levantamiento del contenedor (docker-compose up)

  • Aquí entra en juego el bind mount definido en docker-compose.yml:

yaml
volumes:
  - ./:/var/www
  • ./ (en el contexto del docker-compose.yml) es la carpeta donde está ese archivo, es decir, ~/laravel-docker/.

  • Docker monta (pega) todo el contenido de ~/laravel-docker/ dentro del contenedor en /var/www.

  • En este momento, el contenedor ve exactamente lo que hay en tu host: solo Dockerfile y docker-compose.yml. Es decir, su /var/www contiene esos dos archivos.

3. Creación del proyecto Laravel con Composer

  • Entras al contenedor:

    bash
    docker exec -it laravel-app-1 /bin/bash
  • Una vez dentro, tu prompt está en /var/www (gracias al WORKDIR).

  • Ejecutas:

    bash
    composer create-project laravel/laravel application --prefer-dist
  • Composer escribe todos los archivos de Laravel en /var/www/application dentro del contenedor.

  • Pero /var/www dentro del contenedor es realmente ~/laravel-docker/ del host (por el montaje).

  • Por tanto, los archivos se están escribiendo directamente en ~/laravel-docker/application en tu disco duro.

4. Resultado en el host

  • Abres tu explorador de archivos en ~/laravel-docker/ y ves que ha aparecido la carpeta application/ con toda la estructura de Laravel:

text
~/laravel-docker/
├── application/
│   ├── app/
│   ├── bootstrap/
│   ├── ... (todo Laravel)
├── Dockerfile
└── docker-compose.yml

5. Mover los archivos a la raíz (opcional)

  • Si mueves todo el contenido de application/ a la raíz (como indica el tutorial), entonces tendrás:

text
~/laravel-docker/
├── app/
├── bootstrap/
├── config/
├── ... (todos los archivos de Laravel)
├── Dockerfile
└── docker-compose.yml
  • En el contenedor, /var/www también tendrá esa misma estructura, porque es el mismo lugar.


Resumen de rutas y sincronización

LugarRutaContenido
Host~/laravel-docker/Tus archivos de configuración y, tras crear el proyecto, todo el código de Laravel.
Contenedor/var/wwwEspejo exacto de ~/laravel-docker/ gracias al volumen ./:/var/www.
FlujoCualquier cambio en el host (editar código, crear archivos) se refleja al instante en /var/www del contenedor, y viceversa (por ejemplo, logs o caches generados por Laravel aparecen en el host).

Conclusión clave

  • El WORKDIR /var/www solo define dónde te sitúas cuando entras al contenedor.

  • El volumen ./:/var/www es el que realmente conecta tu carpeta ~/laravel-docker/ con /var/www dentro del contenedor.

  • Laravel se instala dentro del contenedor con Composer, pero como esa carpeta está montada, los archivos nacen directamente en tu host.

  • Todo el código vive en tu máquina host, y el contenedor lo ejecuta en tiempo real. Por eso editas con tu IDE y ves los cambios sin reconstruir nada. ¡Esa es la magia de los bind mounts!

Si tienes más dudas, pregúntame sin problema

-------------------------------------------------}

Puedes saltarte ese paso de mover archivos por completo usando un comando mucho más directo.

En lugar de crear una subcarpeta (application), puedes indicarle a Composer que instale directamente en el directorio actual (que es /var/www dentro del contenedor).

Aquí tienes la solución y cómo quedaría el flujo:

La alternativa recomendada (la más limpia)

Dentro del contenedor, en lugar de ejecutar:

bash
composer create-project laravel/laravel application --prefer-dist

Ejecuta esto:

bash
composer create-project laravel/laravel . --prefer-dist

Fíjate en el punto (.). Ese punto le dice a Composer: "Instala Laravel aquí mismo, en la carpeta donde estoy parado".

Como dentro del contenedor estás en /var/www (gracias al WORKDIR), y /var/www está sincronizado con ~/laravel-docker/ de tu host, todos los archivos aparecerán directamente en la raíz de tu proyecto host.

Resultado en el host (sin mover nada)

Después de ejecutar ese comando, tu árbol en el host quedará directamente así:

text
~/laravel-docker/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
├── .env
├── composer.json
├── artisan
├── ... (resto de archivos)
├── Dockerfile          ← Sigue aquí
└── docker-compose.yml  ← Sigue aquí

¡Sin carpetas anidadas, sin mover nada, sin riesgos de permisos! Es mucho más rápido y limpio.


¿Y qué pasa con el comando laravel new?

También podrías usarlo, pero tiene un pequeño inconveniente en este entorno:

  1. Para usar laravel new, necesitas instalar el instalador global de Laravel dentro del contenedor:

    bash
    composer global require laravel/installer
  2. Luego ejecutarías:

    bash
    laravel new .

    (el punto también indica el directorio actual)

¿Por qué no lo recomiendo tanto?

  • El instalador de Laravel (laravel new) suele pedir confirmación si la carpeta no está vacía (y tu carpeta tiene Dockerfile y docker-compose.yml, así que no está vacía). Tendrías que usar la bandera --force o --no-interaction.

  • Además, instala dependencias usando Yarn o NPM si detecta package.json, lo que añade más pasos.

  • El comando composer create-project es el método "estándar" y universal de Composer, funciona perfectamente sin configuraciones extra y es el que usa el tutorial oficial de Laravel.


Resumen del flujo mejorado (sin mover nada)

PasoAcciónResultado
1Entras al contenedor (docker exec -it laravel-app-1 /bin/bash)Estás en /var/www
2Ejecutas composer create-project laravel/laravel . --prefer-distComposer escribe todos los archivos directamente en /var/www
3Sales del contenedor y miras tu hostEn ~/laravel-docker/ están todos los archivos de Laravel mezclados con el Dockerfile y compose
4Ejecutas php artisan key:generate (dentro del contenedor)El .env se actualiza directamente en el host también

Con este cambio, el paso 5.3 del tutorial (el molesto cp -RT y rm -rf) desaparece por completo. ¡Así es mucho más fácil!


**********************

Puedes saltarte ese paso de mover archivos por completo usando un comando mucho más directo.

En lugar de crear una subcarpeta (application), puedes indicarle a Composer que instale directamente en el directorio actual (que es /var/www dentro del contenedor).

Aquí tienes la solución y cómo quedaría el flujo:

La alternativa recomendada (la más limpia)

Dentro del contenedor, en lugar de ejecutar:

bash
composer create-project laravel/laravel application --prefer-dist

Ejecuta esto:

bash
composer create-project laravel/laravel . --prefer-dist

Fíjate en el punto (.). Ese punto le dice a Composer: "Instala Laravel aquí mismo, en la carpeta donde estoy parado".

Como dentro del contenedor estás en /var/www (gracias al WORKDIR), y /var/www está sincronizado con ~/laravel-docker/ de tu host, todos los archivos aparecerán directamente en la raíz de tu proyecto host.

Resultado en el host (sin mover nada)

Después de ejecutar ese comando, tu árbol en el host quedará directamente así:

text
~/laravel-docker/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
├── .env
├── composer.json
├── artisan
├── ... (resto de archivos)
├── Dockerfile          ← Sigue aquí
└── docker-compose.yml  ← Sigue aquí

¡Sin carpetas anidadas, sin mover nada, sin riesgos de permisos! Es mucho más rápido y limpio.


¿Y qué pasa con el comando laravel new?

También podrías usarlo, pero tiene un pequeño inconveniente en este entorno:

  1. Para usar laravel new, necesitas instalar el instalador global de Laravel dentro del contenedor:

    bash
    composer global require laravel/installer
  2. Luego ejecutarías:

    bash
    laravel new .

    (el punto también indica el directorio actual)

¿Por qué no lo recomiendo tanto?

  • El instalador de Laravel (laravel new) suele pedir confirmación si la carpeta no está vacía (y tu carpeta tiene Dockerfile y docker-compose.yml, así que no está vacía). Tendrías que usar la bandera --force o --no-interaction.

  • Además, instala dependencias usando Yarn o NPM si detecta package.json, lo que añade más pasos.

  • El comando composer create-project es el método "estándar" y universal de Composer, funciona perfectamente sin configuraciones extra y es el que usa el tutorial oficial de Laravel.


Resumen del flujo mejorado (sin mover nada)

PasoAcciónResultado
1Entras al contenedor (docker exec -it laravel-app-1 /bin/bash)Estás en /var/www
2Ejecutas composer create-project laravel/laravel . --prefer-distComposer escribe todos los archivos directamente en /var/www
3Sales del contenedor y miras tu hostEn ~/laravel-docker/ están todos los archivos de Laravel mezclados con el Dockerfile y compose
4Ejecutas php artisan key:generate (dentro del contenedor)El .env se actualiza directamente en el host también

Con este cambio, el paso 5.3 del tutorial (el molesto cp -RT y rm -rf) desaparece por completo. ¡Así es mucho más fácil!

Comentarios

Entradas más populares de este blog

12. Hola Mundo en Docker.

11¿Qué es Docker? y ¿Por qué debo saberlo?

14. Publish and Detached modes