Saltar al contenido
Curso Docker y Laravel Sail desde cero
03/10 Dockerizar una aplicación PHP a mano Dockerfile para PHP-FPM: crear tu propia imagen de PHP con Composer
Tu lectura Quedan 9 min
Lección 3 de 10 · Dockerizar una aplicación PHP a mano

Dockerfile para PHP-FPM: crear tu propia imagen de PHP con Composer

9 min de lectura Docker Engine 29.8

Hola, bienvenido. Un Dockerfile es la receta con la que Docker construye una imagen propia: para PHP-FPM, parte de la imagen oficial php:8.5-fpm-alpine, le añade las extensiones que necesita tu aplicación y Composer, y copia tu código dentro. El resultado es una imagen con todo lo necesario para ejecutar la aplicación, igual en tu máquina que en la de cualquier compañero.

Hasta ahora hemos usado imágenes de otros, y en esta lección por fin vamos a hacer la nuestra. Primero vamos a crear tasks, la aplicación PHP de partida del curso, y después su Dockerfile, para terminar construyendo la imagen y comprobando que lleva lo que esperamos.

La aplicación de partida

tasks es un gestor de tareas mínimo y sin framework: se conecta a MySQL con PDO y lista las tareas de una tabla, nada más. Es pequeño a propósito, porque lo que nos interesa en el curso es el stack que lo rodea y no la aplicación. Si te interesa construir una aplicación PHP de verdad sobre este mismo stack, en la lección siguiente te dejo el curso que lo hace.

Estos archivos los vamos a crear, pero no los vamos a ejecutar en tu máquina. No tienes PHP instalado ni te hace falta: PHP, Composer y las extensiones van a vivir en la imagen que construyamos.

Crea una carpeta para el curso y, dentro, la carpeta tasks. Todo lo que hagamos en esta primera sección va dentro de tasks. Empezamos por el composer.json, que solo lleva el autoload PSR-4 para que las clases de src/ se carguen solas con el espacio de nombres App:

tasks/composer.json Nuevo +7
1{
2 "autoload": {
3 "psr-4": {
4 "App\\": "src/"
5 }
6 }
7}

La conexión a la base de datos va en una clase Database. Lee la configuración de las variables de entorno, con los mismos nombres que usa Laravel (DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME y DB_PASSWORD), porque así, cuando lleguemos a Sail, los reconocerás en su .env:

tasks/src/Database.php Nuevo +31
1<?php
2
3declare(strict_types=1);
4
5namespace App;
6
7use PDO;
8use PDOException;
9
10final class Database
11{
12 public static function connect(): PDO
13 {
14 $dsn = sprintf(
15 'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4',
16 getenv('DB_HOST') ?: '127.0.0.1',
17 getenv('DB_PORT') ?: '3306',
18 getenv('DB_DATABASE') ?: 'tasks',
19 );
20
21 try {
22 return new PDO($dsn, getenv('DB_USERNAME') ?: 'root', getenv('DB_PASSWORD') ?: '', [
23 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
24 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
25 ]);
26 } catch (PDOException $e) {
27 http_response_code(500);
28 exit('No se puede conectar con la base de datos: ' . $e->getMessage() . PHP_EOL);
29 }
30 }
31}

Si una variable no está definida, se usa un valor por defecto, y el de DB_HOST es 127.0.0.1, algo que va a salir en las próximas lecciones. Y si la conexión falla, la aplicación no se queda en blanco: devuelve un 500 con el mensaje de error de PDO, que es justo lo que vas a necesitar leer cuando algo no conecte.

Por último, public/index.php, que carga el autoload de Composer, pide las tareas y las escribe en texto plano:

tasks/public/index.php Nuevo +19
1<?php
2
3declare(strict_types=1);
4
5use App\Database;
6
7require __DIR__ . '/../vendor/autoload.php';
8
9header('Content-Type: text/plain; charset=utf-8');
10
11$tasks = Database::connect()
12 ->query('SELECT title, done FROM tasks ORDER BY id')
13 ->fetchAll();
14
15echo 'Tareas' . PHP_EOL;
16
17foreach ($tasks as $task) {
18 echo ($task['done'] ? '[x] ' : '[ ] ') . $task['title'] . PHP_EOL;
19}
Lo que queda de esta lección
  1. 02Qué es PHP-FPM
  2. 03El Dockerfile
  3. 04Construir la imagen
  4. 05Comprobar la imagen
Sigue leyendo gratis Este curso es gratuito. Déjanos tu email y te enviamos un enlace para leerlo entero, junto con el resto de cursos gratuitos.

¿Ya lo habías pedido o entras desde otro dispositivo? Escribe el mismo email: recuperas tu acceso y tu avance.