Hace mucho tiempo… quise aprender Docker para poder correr proyectos en mi PC sin tener que andar moviendo la versión de PHP y MySQL y todo ese infierno que conoce la gente que trabaja en varios proyectos de diferentes versiones y todo eso 😥. Y que crees, aprendí la sintaxis de Docker, pero nunca pude construir nada o copiar algún entorno para poder hacerlo, así que use Laragon, XAMP o Hombrew para mis entornos.
Hoy que tengo un proyecto con Laravel y MySQL, me di una n oportunidad para crear el entorno, y con ayuda de internet y mi previo conocimiento sobre Docker pude generar uno 😜, y digo generar porque ninguno de los que encontré en internet me funciono, pero si tuve que basarme en ellos para hacer uno que me funcione a mí, principalmente en este Link.
¡Si deseas correr tu app PHP ya! Puedes acceder a mi repo y seguir los pasos descritos en el readme.md del repositorio.
Necesitas antes
Antes que nada necesitas instalar Docker, y ese es un viaje algo largo si es tu primera vez. No te preocupes, solo debes de leer bien las instrucciones oficiales, y por ahí debe haber tutoriales de como hacerlo. Yo creo en ti. Busca por todos lados hasta que lo consigas.
¿Ya tenemos Docker? ¡A pensar!
Describiendo la arquitectura
Así tengo la estructura de mis documentos, y espero que me la copies, porque por supuesto, yo la copie de alguien más 👀: Link.
// Estructura
> mysql // carpeta de configuracion de mysql
> nginx/default.conf// archivo de configuracion nginx
> src // proyecto php
.gitignore// si es que necesitas uno
docker-compose.yml// declaracion de los servicios
Dockerfile // declaracion del servicio principal
Descripción gráfica:

Describiendo docker-compose.yml
Espero no te molesten los comments inline, porque suelo hacerlos un montón.
Te presento el docker-compose.yml
.
version:"3.7"# version del docker-compose(?)
services:
nginx:# 1er servicio: nginx
image: nginx:stable-alpine # imagen de docker hub que vamos a usar
container_name: nginx # nombre para referirse al servicio
ports:
-8000:80# puerto de mi pc:puerto del servicio
volumes:
- ./src:/var/www/html # carpeta local/ vincula a carpeta de nginx
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf # archivo local / reflejado en archivo de la imagen
depends_on:# para correr este servicio debe estar corriendo php y mysql antes
- php
- mysql
networks:# la red que los conecta se llama laravel
- laravel
mysql:# 2do servici
image: mysql:5.7# imagen de docker hub
container_name: mysql # nombre de referencia del servicio
restart: unless-stopped # si tiene algun problema, reinicialo
tty:true# aqui si le fallo joven xD, 👀 leo los comentarios
ports:
-33069:3306# puerto local:puerto del servicio
volumes:
- ./mysql:/var/lib/mysql # carpeta local:carpeta de config de mysql
environment:# datos de configuracion del entorno
MYSQL_DATABASE:'homestead'# importante que tengan comillas
MYSQL_USER:'homestead'
MYSQL_PASSWORD:'secret'
MYSQL_ROOT_PASSWORD:'secret.root'
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- laravel # red
php:# 3er servicio
build:# este se construira aqui mismo
context: . # ruta de referencia ./
dockerfile: Dockerfile # nombre del archivo de configuracion de la imagen
container_name: php #
volumes:# carpeta de proyecto local : carpeta del container que da vida a los archivos PHP
- ./src:/var/www/html
ports:
-9000:80# ya te la sabes 😉
networks:
- laravel # red
networks:# declaracion de la red
laravel:
Resumen: Instalamos y configuramos las imágenes que ya existen en DockerHub de MySQL y Nginx, y declaramos que al 3er servicio será cargado a partir de otro archivo de configuración llamado Dockerfile, pero tambien agregamos algunas configuraciones.
PD: El repositorio contiene todos los archivos sin comentarios.
Describiendo Dockerfile
Dockerfile
es un archivo muy parecido al anterior, pero se usa en contenedores individuales(?). Este archivo fue construido mediante documentación y stackoverflow 🦚, cada fallo.
# imagen de dockerhub que descargara
FROM php:7.3-fpm-alpine
# algunas configuraciones para que funcione el contenedor
RUN docker-php-ext-install pdo pdo_mysql
# instala composer en el contenedor
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# da permisos para editar los archivos en esta ruta del container
RUN chown -R www-data:www-data /var/www
RUN chmod 755 /var/www
Archivos de configuración
Por suerte solo hay 1: nginx. Todo lo demás ya fue configurado en Docker. Tengo que confesar que es la primera vez que trabajo con Nginx, toda la configuración fue un copypaste del primer tutorial que vi, pero dejo los comentarios por mera interpretación.
PD: Solicito apoyo 6.6
# configuracion del servidor de nginx
server {
listen80; # puerto del container
index index.php index.html; # busca interpretar archivos de este tpo
server_name localhost; # usa el localhost
error_log /var/log/nginx/error.log; # registros de errores
access_log /var/log/nginx/access.log; # registros de acceso
root /var/www/html/public; # usara esta ruta como la root
# a partir de aqui todo es muy confuso 😹
location~ \.php$ {
try_files$uri =404; # por defecto regresa el 404
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000; # puerto al que se conectara para obtener sus archivos
fastcgi_index index.php; # el archivo raiz por default
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files$uri/ $uri /index.php?$query_string;
gzip_staticon;
}
}
Y tengo un archivo .gitignore por si quiero subir esto al Github
src/* # para que se lleve el contenido de src, dejandome la carpeta src
mysql/* # que se lleve todo el contenido de mysql excepto la misma carpeta
Corriendo el proyecto
Corre el entorno:
$ docker-compose build # trae y configura las imagenes
$ docker-compose up -d # enciende los containers y la red
Abre tu Docker y verás que tus servicios ya están corriendo 🤞.
A mí me dio un pequeño problema al correrlo la primera vez, pero funciono al dar el comando $ docker-compose down
y después $ docker-compose up
.

Agregando un proyecto con PHP
A partir de aquí es prácticamente es lo mismo que tengo en el repositorio.
-
Mueve a la carpeta
src
.$ cd src
-
Clona tu proyecto en
src
.# Es importante el espacio yel punto al final, porque así se instalara enla carpeta enla que está situado. # En este caso el proyecto que agregue es el default de Laravel. $ git clone https://github.com/laravel/laravel.git .
-
Instala las dependencias de composer mediante Docker.
# de esta manera puedes $ docker-compose exec php composer install --ignore-platform-reqs
-
Copia y renombra el archivo
.env.example
=>.env
. -
Agrega el app key.
$ docker-compose exec php php artisan key:generate
-
Abre el navegador en el puerto declarado en el
docker-compose.yml
para Nginx. En este caso es el puerto 8888. Si ves algo, lo que sea, hasta un error, ya estamos del otro lado.
Conectando la base de datos
En el archivo docker-compose.yml
vienen declaradas las configuraciones de la db, las puedes cambiar si gustas. Las que deje por default son:
ports:
- 33069:3306
container_name: mysql
environment:
MYSQL_DATABASE: 'homestead'
MYSQL_USER: 'homestead'
MYSQL_PASSWORD: 'secret'
MYSQL_ROOT_PASSWORD: 'secret.root'
Conecta el container con tu manejador de base de datos. En mi caso es Workbench. Como vez agrego los datos de user root, pero puedes agregar el usuario normal que tiene poder sobre la DB declarada en el docker-compose.yml
.

Después de esto deberás importar tu base de datos. Hay muchas formas de hacerlo dependiendo de tu gestor o si usas la terminal. Yo use Workbench, pero si tienes otro te doy una pista: “Como importar un archivo a mi base de datos con Workbench” en Google.
Ahora conecta tu proyecto con la base de datos. Esto lo logre abriendo el archivo .env e ingresando los datos del puerto local del servicio mysql.
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=secret.root
¿Listo para que todo arda? Haremos la migración.
Una migración exitosa confirmaría que la conexión con la base de datos es correcta, pero antes de hacerla limpiaremos el caché.
$ docker-compose exec php php artisan config:clear
$ docker-compose exec php php artisan cache:clear
$ docker-compose exec php php artisan view:clear
$ docker-compose exec php php artisan config:cache
Ojo: si te sale algún error es porque no tienes permisos root en las carpetas de tu proyecto o que no existen las carpetas de caché, para esto tengo 2 comandos para ti.
# para obtener permisos dentro del servicio php
$ docker-compose exec php chown -R www-data: /var/www/html
# para crear las carpetas del proyecto de php desde la carpeta src
$ pwd# debe decir que estas enla carpeta src
$ mkdir storage/framework/{views, testing, sessions, cache/data}
#puede que sea diferente para proyectos queno sean Laravel, ahi se los dejo a ustedes y su superpoder Google.
Ahora si: migración.
$ docker-compose exec php php artisan migrate
Si tuviste una migración exitosa, felicidades.
Con todo este desarrollo ya deberías poder acceder a la ruta principal o a algunas de tus rutas declaradas en tu carpeta routes.
¡Si no, felicidades también! ¡Ya tienes casi todo funcionando! Los servidores, la base de datos, solo es solucionar eso que no te permite conectar tu DB con el proyecto. Mi sugerencia: consulta a tus conocidos, escribe preguntas, lee doc, usa stackoverflow. Te entiendo completamente, la creación de entornos con PHP es mucho trabajo, pero siempre hay una manera (? I hope so).
Extra
Mi proyecto tenía la dependencia de passport, por lo que para poder trabajar debería de crear credenciales.
$ docker-compose exec php php artisan passport:install
Para esto las generé y las agregué en mi archivo app/Http/Controllers/Users/User.php
// ...
// line 53
$request->request->add([
'scope' => $scope,
'grant_type' => 'password',
'client_id' => '20',
'client_secret' => 'x5iM00tRbKcNFFXV7sz7psJjjIP3e1iHTawjR8iu',
'username' => Input::get($type),
'type_username' => $type
]);
return Route::dispatch(
Request::create('/api/oauth/token', 'post')
);
// ...
Y los comandos de PHP artisan y composer???
Para acceder a la terminal de cada servicio puedes hacerlo de dos formas:
-
Por medio de la interfaz de Docker abriendo la terminal del servicio:
-
Mediante comandos de docker-compose que mandan a ejecutar una linea en un servicio (como lo hice en todo el tuto).
# docker-compose ejecuta servicio-php $ docker-compose exec php php artisan migrate
Por fin
Recuerda que para
¡Felicidades! Acabas de consultar otra fuente, espero que sea la que te funcione. Si no, recuerda: Divide el problema y ¡No pares de buscar la solución!