Setting Up Lumen and MySQL With Docker - Part II
Tags: php, mysql, docker, laravel
Published: 2021-05-15 18:33:41

In  [Setting Up Lumen and MySQL With Docker - Part I](https://yossiabramov.com/blog/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:

```plaintext
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 an  `.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](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:

```plaintext
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:

```plaintext
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**](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`:

```plaintext
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**](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`:

```plaintext
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):

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

Now we can fire up our Docker container with:

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

Learn more about using environment variables with Docker:

👉 [**https://docs.docker.com/compose/environment-variables/**](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
<?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.

✍ For more posts:
[https://yossiabramov.com/](https://yossiabramov.com/)