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)
~/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/wwwes una instrucción que no crea ni llena la carpeta. Solo establece el directorio de trabajo por defecto dentro del contenedor. Cuando entres condocker execo 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).Sí se instala más tarde, cuando el contenedor ya está en ejecución y tú lanzas
composer create-projectdentro de él.
La sincronización paso a paso (con rutas explícitas)
1. Construcción de la imagen
Ejecutas
docker-compose build(oupque 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 basephp:8.2-fpm.El
WORKDIR /var/wwwsolo apunta a esa ruta.
2. Levantamiento del contenedor (docker-compose up)
Aquí entra en juego el bind mount definido en
docker-compose.yml:
volumes:
- ./:/var/www./(en el contexto deldocker-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
Dockerfileydocker-compose.yml. Es decir, su/var/wwwcontiene esos dos archivos.
3. Creación del proyecto Laravel con Composer
Entras al contenedor:
docker exec -it laravel-app-1 /bin/bashUna vez dentro, tu prompt está en
/var/www(gracias alWORKDIR).Ejecutas:
composer create-project laravel/laravel application --prefer-distComposer escribe todos los archivos de Laravel en
/var/www/applicationdentro del contenedor.Pero
/var/wwwdentro del contenedor es realmente~/laravel-docker/del host (por el montaje).Por tanto, los archivos se están escribiendo directamente en
~/laravel-docker/applicationen tu disco duro.
4. Resultado en el host
Abres tu explorador de archivos en
~/laravel-docker/y ves que ha aparecido la carpetaapplication/con toda la estructura de Laravel:
~/laravel-docker/
├── application/
│ ├── app/
│ ├── bootstrap/
│ ├── ... (todo Laravel)
├── Dockerfile
└── docker-compose.yml5. 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:
~/laravel-docker/
├── app/
├── bootstrap/
├── config/
├── ... (todos los archivos de Laravel)
├── Dockerfile
└── docker-compose.ymlEn el contenedor,
/var/wwwtambién tendrá esa misma estructura, porque es el mismo lugar.
Resumen de rutas y sincronización
| Lugar | Ruta | Contenido |
|---|---|---|
| Host | ~/laravel-docker/ | Tus archivos de configuración y, tras crear el proyecto, todo el código de Laravel. |
| Contenedor | /var/www | Espejo exacto de ~/laravel-docker/ gracias al volumen ./:/var/www. |
| Flujo | Cualquier 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/wwwsolo define dónde te sitúas cuando entras al contenedor.El volumen
./:/var/wwwes el que realmente conecta tu carpeta~/laravel-docker/con/var/wwwdentro 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:
composer create-project laravel/laravel application --prefer-distEjecuta esto:
composer create-project laravel/laravel . --prefer-distFí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í:
~/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:
Para usar
laravel new, necesitas instalar el instalador global de Laravel dentro del contenedor:composer global require laravel/installerLuego ejecutarías:
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 tieneDockerfileydocker-compose.yml, así que no está vacía). Tendrías que usar la bandera--forceo--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-projectes 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)
| Paso | Acción | Resultado |
|---|---|---|
| 1 | Entras al contenedor (docker exec -it laravel-app-1 /bin/bash) | Estás en /var/www |
| 2 | Ejecutas composer create-project laravel/laravel . --prefer-dist | Composer escribe todos los archivos directamente en /var/www |
| 3 | Sales del contenedor y miras tu host | En ~/laravel-docker/ están todos los archivos de Laravel mezclados con el Dockerfile y compose |
| 4 | Ejecutas 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:
composer create-project laravel/laravel application --prefer-distEjecuta esto:
composer create-project laravel/laravel . --prefer-distFí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í:
~/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:
Para usar
laravel new, necesitas instalar el instalador global de Laravel dentro del contenedor:composer global require laravel/installerLuego ejecutarías:
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 tieneDockerfileydocker-compose.yml, así que no está vacía). Tendrías que usar la bandera--forceo--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-projectes 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)
| Paso | Acción | Resultado |
|---|---|---|
| 1 | Entras al contenedor (docker exec -it laravel-app-1 /bin/bash) | Estás en /var/www |
| 2 | Ejecutas composer create-project laravel/laravel . --prefer-dist | Composer escribe todos los archivos directamente en /var/www |
| 3 | Sales del contenedor y miras tu host | En ~/laravel-docker/ están todos los archivos de Laravel mezclados con el Dockerfile y compose |
| 4 | Ejecutas 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
Publicar un comentario