Setting Up Lumen and MySQL With Docker - Part II

Setting Up Lumen and MySQL With Docker - Part II

Published: 5/15/20214 min read
PHP
Lumen
lumen.svg logo
MySQL
Docker

In Setting Up Lumen and MySQL With Docker - Part I we dockerized a Lumen app with a Dockerfile and a docker-compose.yml file. Then, we started our app by running:

docker-compose up
In this part we will:
  • Add MySQL 8.0 as a service to our docker-compose (with a volume).
  • Install necessary php extensions in our Dockerfile.
  • Learn how to use a .env file to pass variables to our docker-compose.yml file.
  • Learn how to enable Facade classes in a Lumen app.
  • Test our database connection.

Here is a link to the GitHub repository for this tutorial:
👉 https://github.com/yossi-abramov/lumen-mysql-docker

Add MySQL 8.0 to docker-compose.yml

In the previous post, this was our docker-compose.yml file:

version: '3.5'

services:
  lumen:
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
      - /var/www/html/vendor/
    build: .
    command: php -S lumen:8000 -t public
    restart: always

Now, let’s add MySQL 8 with a volume to persist data:

version: "3.5"

services:
  lumen:
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
      - /var/www/html/vendor/
    build: .
    command: php -S lumen:8000 -t public
    restart: always
    depends_on:
      - db
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: your_db_name
      MYSQL_USER: your_db_user
      MYSQL_PASSWORD: your_db_password
      MYSQL_ROOT_PASSWORD: root
    command: mysqld --default-authentication-plugin=mysql_native_password
    volumes:
      - ./database/mysql-data:/var/lib/mysql:rw
volumes:
  mysql-data:

Notice that this docker-compose.yml has MySQL hardcoded environment variables. We will soon change this. For more information about official MySQL images for Docker see:
👉 https://hub.docker.com/_/mysql

Install the pdo_mysql extension

Our database is ready, but Lumen will not be able to connect with it without the pdo_mysql extension. To enable any PHP extensions, we can simply add them to our Dockerfile.

Here is our updated Dockerfile:

FROM php:7.3-fpm-alpine

RUN docker-php-ext-install pdo_mysql

WORKDIR /var/www/html/

RUN php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer

COPY . .

RUN composer install

For more information about official PHP images for Docker see:
👉 https://hub.docker.com/_/php

Using Lumen’s .env file

As you can see, our docker-compose.yml has all MySQL environment variables hardcoded. Here is how we can pass Lumen’s .env variables to our docker-compose.yml:

version: "3.5"

services:
  lumen:
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
      - /var/www/html/vendor/
    build: .
    command: php -S lumen:8000 -t public
    restart: always
    depends_on:
      - db
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: root
    command: mysqld --default-authentication-plugin=mysql_native_password
    volumes:
      - ./database/mysql-data:/var/lib/mysql:rw
volumes:
  mysql-data:

One more important step before starting our container:
In .env you should set DB_HOST to the MySQL service name in your docker-compose.yml (db in this case):

...
DB_HOST=db #MySQL container name
...

Now we can fire up our Docker container with:

docker-compose --env-file .env up --build

Learn more about using environment variables with Docker:
👉 https://docs.docker.com/compose/environment-variables/

Enable Facade classes

For testing our database connection, we will use the DB Facade and the PDO object that holds our connection details. In Laravel, Façade classes are globally available out of the box, but with Lumen you have to uncomment the $app->withFacades(); option in bootstrap/app.php.

Test Database Connection

After enabling Facades, we can use DB in routes/web.php and dd() our connection’s PDO object:

<?php

/** @var \Laravel\Lumen\Routing\Router $router */

use Illuminate\Support\Facades\DB;

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/

$router->get('/', function () use ($router) {
    dd(DB::getPDO());
});

You can head over to http://localhost:8000 and should get an object specifying your connection. And now we have MySQL up and running with Lumen.
In the next part we will interact with our Lumen container and create a Migration, Model, Model Factory, and database Seeder.