2-bind mount-volumes: - ./ruta/local:/ruta/en/contenedor

  • La sintaxis en docker-compose.yml es:
    volumes: - ./ruta/local:/ruta/en/contenedor

El . significa "busca el Dockerfile en la carpeta actual".

¿Qué hace - ./:/var/www/html?

  • ./ es la carpeta actual de tu host (donde está el docker-compose.yml).

  • /var/www/html es la ruta dentro del contenedor.

  • Efecto: Todo lo que esté en ./ se ve dentro del contenedor en /var/www/html, y todo lo que se cree dentro del contenedor en /var/www/html aparecerá automáticamente en tu ./. Es una sincronización bidireccional y en tiempo real.


 El "bind mount" (volumes: - ./:/var/www/html) es el corazón de la sincronización entre tu PC y el contenedor. No necesitas ningún script adicional para "sacar" los archivos, porque ese montaje ya lo hace en tiempo real y de forma bidireccional.

Entonces, el tutorial que ya te di ya incluye ese bind mount. Solo debo enfatizar más ese punto y eliminar lo de bin/ para no confundir. Aquí tienes la versión depurada y centrada únicamente en el bind mount:


Tutorial Definitivo: Docker con Laravel (Enfoque "Contenedor Primero" + Bind Mount)

Objetivo: No necesitas PHP, Composer, Nginx ni MySQL en tu host. Solo Docker. El bind mount sincroniza automáticamente los archivos entre el contenedor y tu PC.


Paso 0: (Opcional) Evitar sudo en cada comando Docker

Agrega tu usuario al grupo docker:

bash
sudo usermod -aG docker $USER

Cierra y abre la terminal para que surta efecto. Luego verifica:

bash
docker ps

Si no ves error de permisos, ya no necesitas sudo.


Paso 1: Estructura de archivos (en tu host)

Crea una carpeta vacía para tu proyecto y dentro coloca estos archivos:

text
mi-proyecto-laravel/
├── docker/
│   ├── nginx/
│   │   └── default.conf
│   └── php/
│       └── Dockerfile
└── docker-compose.yml

(La carpeta del proyecto está VACÍA inicialmente, solo tiene estos archivos de configuración).


Paso 2: Dockerfile para PHP

Ruta: docker/php/Dockerfile

dockerfile
FROM php:8.2-fpm

RUN apt-get update && apt-get install -y \
    git curl libpng-dev libonig-dev libxml2-dev zip unzip

RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html
EXPOSE 9000
CMD ["php-fpm"]

Paso 3: Configuración de Nginx

Ruta: docker/nginx/default.conf

nginx
server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;

    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Paso 4: Docker Compose (con el BIND MOUNT)

Ruta: docker-compose.yml

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    container_name: laravel_app
    restart: unless-stopped
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html   # <--- ¡AQUÍ ESTÁ EL BIND MOUNT!
    networks:
      - laravel
    depends_on:
      - db
      - redis

  webserver:
    image: nginx:alpine
    container_name: laravel_webserver
    restart: unless-stopped
    ports:
      - "8000:80"
    volumes:
      - ./:/var/www/html   # <--- MISMO BIND MOUNT para Nginx
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    networks:
      - laravel

  db:
    image: mysql:8.0
    container_name: laravel_db
    restart: unless-stopped
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_USER: laraveluser
      MYSQL_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

  redis:
    image: redis:alpine
    container_name: laravel_redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    networks:
      - laravel

networks:
  laravel:
    driver: bridge

volumes:
  db_data:

¿Qué hace - ./:/var/www/html?

  • ./ es la carpeta actual de tu host (donde está el docker-compose.yml).

  • /var/www/html es la ruta dentro del contenedor.

  • Efecto: Todo lo que esté en ./ se ve dentro del contenedor en /var/www/html, y todo lo que se cree dentro del contenedor en /var/www/html aparecerá automáticamente en tu ./. Es una sincronización bidireccional y en tiempo real.


Paso 5: Levantar los contenedores (aún sin código)

bash
docker-compose up -d --build

Verifica que estén corriendo:

bash
docker-compose ps

Paso 6: Crear el proyecto Laravel DENTRO del contenedor

Entra al contenedor app:

bash
docker-compose exec app bash

Dentro, ejecuta:

bash
composer create-project laravel/laravel .

¡Aquí ocurre la magia del bind mount!
Mientras Composer va creando archivos dentro del contenedor en /var/www/html, esos archivos aparecen instantáneamente en tu carpeta local ./. Abre tu explorador de archivos y verás cómo se llena de carpetas (app/, config/, vendor/, etc.) en tiempo real.


Paso 7: Configurar el .env (dentro del contenedor)

Sigue dentro del bash:

bash
cp .env.example .env
nano .env

Ajusta las credenciales de la BD:

env
DB_CONNECTION=mysql
DB_HOST=db              # <--- nombre del servicio en docker-compose
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laraveluser
DB_PASSWORD=secret

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

Guarda y sal del contenedor (exit).


Paso 8: Arreglar PERMISOS en el host (solo Linux)

Como los archivos los creó el usuario www-data dentro del contenedor, en tu Linux te pertenecerán a root y no podrás editarlos con tu editor normal. Desde el host ejecuta:

bash
docker-compose exec app chown -R $(id -u):$(id -g) .

Esto cambia la propiedad de todos los archivos a tu usuario del host. En Windows/Mac no suele ser necesario, pero no hace daño.


Paso 9: Migrar la base de datos

bash
docker-compose exec app php artisan migrate

Responde yes cuando pregunte.


Paso 10: ¡Abre el navegador!

text
http://localhost:8000

Deberías ver la página de bienvenida de Laravel.


¿Cómo funciona la sincronización en el día a día?

  • Editas código en tu PC (con VSCode, PHPStorm, etc.) → Los cambios se reflejan al instante dentro del contenedor (gracias al bind mount).

  • Ejecutas composer require o artisan make:... dentro del contenedor → Los nuevos archivos aparecen automáticamente en tu PC (gracias al bind mount).

  • No necesitas copiar nada manualmente. El bind mount lo hace todo.


Comandos útiles (sin scripts extras)

bash
# Ejecutar Artisan
docker-compose exec app php artisan cache:clear

# Ejecutar Composer
docker-compose exec app composer require spatie/laravel-permission

# Entrar al bash del contenedor
docker-compose exec app bash

# Detener contenedores
docker-compose down

# Reconstruir y levantar
docker-compose up -d --build

Resumen

  • Bind mount: - ./:/var/www/html es el único mecanismo que necesitas para sincronizar archivos.

  • No hay scripts mágicos, solo el montaje directo.

  • Todo el proyecto se genera dentro del contenedor, pero tú lo ves y editas desde tu PC.

  • Solo necesitas Docker en tu máquina

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